v3.5
v3.5 is mostly a fix-and-polish release after the big v3.4. We burned down the open issues backlog, and out of that came a rebuilt PostgreSQL loader, a new native DuckDB loader, and three security fixes.
Security fixes
Nine people reported three security issues in VisiData (eight of them found the same zip slip):
- pandas:
.picklefiles are no longer loaded unless the newpandas_allow_pickleoption is set (default off). Unpickling runs arbitrary code from the file, so opening an untrusted.picklecould execute it. CVE pending, reported by @Santoshkumarpuppala. - unzip_http: refuse zip members whose path resolves outside the extraction directory (Zip Slip). CVE-2026-41958, reported by @MaxFreedomPollard, and independently by @robsherw of Cisco Talos and six others. Also fixed in unzip-http 0.8.
- eml:
gxrefuses attachment filenames that resolve outside the extraction directory (path traversal). CVE-2026-42532, reported by @robsherw of Cisco Talos.
You should upgrade if you open files from sources you don't trust.
Data changes
- Dict and list cells now save as JSON by default in text formats. (#2944)
- On the Describe sheet, all null forms count as one distinct value. (#3223)
Interface changes
- Join type
concatmatches columns by position and keeps the first sheet's column names (and type as before). Useappendto match by name. (#3208) - Macros record literal
{braces}safely (f-strings and regexes no longer turn into parameters), and{{ }}escapes braces in parameterized macros. (#2785) - Command line args are now added in order @midichef (#3225)
- Options: reading an undefined option warns and returns None, instead of raising.
New commands
set-envvarto record environment changes for replay (for e.g. $LC_ALL reproducibility). (#3195)addcol-incr-key, likeaddcol-incrbut increment restarts at each change in key columnsselect-col-duplicatesto select duplicate cells in one column @midichefresize-col-max-allandresize-cols-max-allto resize columns looking at all rows (#2780)syscopy-sql(#2393)undo-redo-input(zU) undoes the last change and reruns it with its input prefilled, for e.g. fixing a typo in a long expression. (#3031)llm-query-sheetandllm-query-selectedsend rows as one query to an Anthropic LLM; stream replies into the sheet (#2947)
Highlighted features
- PostgreSQL loader overhaul: open a table directly with
postgres://host/dbname/tablename, runexec-sql/edit-sql, and browse large tables that load lazily and stream rows. Connection details come from libpq (via$PGUSER,$PGHOST,~/.pgpass, etc). Tables are readonly for now; write support is deferred to a later release. (#282 #586 #727 #2989) - Native DuckDB loader for
.duckdbfiles, including saver. (#3035 #3237) - Decimal type:
type-decimalparses currency and(1,234.50)accounting negatives and keeps the source precision. Unbound by default; bind it to$to try it. (#2396) - Command-server client: include the
vdxscript to interact with a livevdcommand-server (LLMs can drive vd now too!) - .vds format: several improvements to VisiData's own save format
Spit and Polish
- Hidden columns keep their width across hide/unhide; sheet edge requires extra
go-rightbefore stepping into hidden columns. (#3214 #3215) - Better wide-character support: fix terminal display issues with emoji and wide characters, and also better wrapping for same. (#2416 #2685)
- Archives: members decompress by suffix, nested tars open, and
zEnteropens a member as a chosen filetype. (#3212) - macOS: respect
XDG_DATA_HOME/XDG_STATE_HOMEon macOS
Thanks to @midichef for many bugfixes and reviews, and to @VXNCXNX, @danielwe, @chutzimir, @mpr1255, @horizonbymuneeb, @chiliec, @dacodas, @maxfain, and @khughitt for their contributions.
Please see the CHANGELOG for the full list of changes.