This release adds 2 notable features for engineering teams evaluating rollout.
✓ No known CVEs patched in this version
Topics
+5 more
ReleasePort's take
Moderate signalThe v0.3.0‑alpha release fixes a crash bug in table handling for out‑of‑range end_col values and adds several usability improvements.
Why it matters: Severity 90 crash bug fixed; operators should upgrade to avoid application crashes when processing tables with invalid column indices.
Summary
AI summaryUpdates 0.3.0-alpha, 2026-07-10, and always across a mixed release.
Changes in this release
| Type | Severity | Summary | CVE |
|---|---|---|---|
| Security | Critical |
Crash bug in table handling with out-of-range end_col fixed. Crash bug in table handling with out-of-range end_col fixed. Source: llm_adapter@2026-07-16 Confidence: high |
— |
| Feature | Low |
Direct DataFrame input via Arrow PyCapsule interface added. Direct DataFrame input via Arrow PyCapsule interface added. Source: llm_adapter@2026-07-16 Confidence: high |
— |
| Feature | Low |
`num_threads` knob added to single‑sheet writers. `num_threads` knob added to single‑sheet writers. Source: llm_adapter@2026-07-16 Confidence: high |
— |
| Feature | Low |
Categorical/dictionary column support added for pandas/Polars Arrow columns. Categorical/dictionary column support added for pandas/Polars Arrow columns. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Feature | Low |
All-None (Null-type) columns now write as blank cells instead of raising errors. All-None (Null-type) columns now write as blank cells instead of raising errors. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Feature | Low |
`legend_position` for charts is now parsed and applied. `legend_position` for charts is now parsed and applied. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | High |
Sheets exceeding Excel's row/column limits ( >1,048,576 rows or >16,384 columns ) now raise a catchable error on all paths. Sheets exceeding Excel's row/column limits ( >1,048,576 rows or >16,384 columns ) now raise a catchable error on all paths. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Medium |
Cell borders now render correctly. Cell borders now render correctly. Source: llm_adapter@2026-07-16 Confidence: high |
— |
| Bugfix | Medium |
`uint64` values above `i64::MAX` no longer overflow to negative. `uint64` values above `i64::MAX` no longer overflow to negative. Source: llm_adapter@2026-07-16 Confidence: low |
— |
| Bugfix | Medium |
Excel-1900 date serials corrected for dates on/before 1900‑02‑28. Excel-1900 date serials corrected for dates on/before 1900‑02‑28. Source: llm_adapter@2026-07-16 Confidence: low |
— |
| Bugfix | Medium |
Out-of-range `text_rotation` values are clamped to valid encoding, preventing workbook corruption. Out-of-range `text_rotation` values are clamped to valid encoding, preventing workbook corruption. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Medium |
Formulas with a leading `=` no longer have the extra `=` duplicated. Formulas with a leading `=` no longer have the extra `=` duplicated. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Medium |
NaN/±Inf values in dictionary path now produce empty cells, matching Arrow handling. NaN/±Inf values in dictionary path now produce empty cells, matching Arrow handling. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Medium |
Table names with spaces or invalid characters are sanitized, preventing unopenable files. Table names with spaces or invalid characters are sanitized, preventing unopenable files. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Medium |
Scatter‑chart value‑axis element order conforms to ECMA‑376 (majorGridlines precede title). Scatter‑chart value‑axis element order conforms to ECMA‑376 (majorGridlines precede title). Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Low |
Invalid color strings are normalized to ARGB or omitted, avoiding stylesheet breakage. Invalid color strings are normalized to ARGB or omitted, avoiding stylesheet breakage. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Low |
Pre-1900 dates are written as ISO‑8601 strings instead of invalid negative serials. Pre-1900 dates are written as ISO‑8601 strings instead of invalid negative serials. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Low |
Reversed cell ranges are normalized to valid A1 notation, preserving CF/merge/data‑validation rules. Reversed cell ranges are normalized to valid A1 notation, preserving CF/merge/data‑validation rules. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Low |
Hyperlinks on row 0 are clamped to ≥1, preventing sheet corruption. Hyperlinks on row 0 are clamped to ≥1, preventing sheet corruption. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Low |
Hyperlinks inside merged ranges are relocated to the merge anchor, avoiding workbook corruption. Hyperlinks inside merged ranges are relocated to the merge anchor, avoiding workbook corruption. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Low |
Duplicate table names receive a unique id suffix, avoiding workbook corruption. Duplicate table names receive a unique id suffix, avoiding workbook corruption. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
| Bugfix | Low |
Chart title/axis colors are normalized, and `title_font_size=0` is clamped to the valid range. Chart title/axis colors are normalized, and `title_font_size=0` is clamped to the valid range. Source: granite4.1:30b@2026-07-16-audit Confidence: low |
— |
Full changelog
0.3.0-alpha (2026-07-10)
Summary
Stability and correctness release. 27 silent data-loss/corruption bugs fixed, plus new features and hardening. All fixes validated by round-trip inspection, official ECMA-376 schema conformance, and property-based fuzzing (0 failures across 55,000+ writes/checks).
Features
- Direct DataFrame input — Arrow-consuming functions now accept any object implementing the Arrow PyCapsule interface (
__arrow_c_stream__), so bare Polars/pandas DataFrames work without.to_arrow(). Handles PolarsUtf8View/BinaryViewC-stream exports. Fully backward compatible; byte-identical values vs.to_arrow(). num_threadson single-sheet writers —write_sheet_arrow/write_sheet_arrow_to_bytesaccept"auto"(default; uses all cores, prints chosen count) or an explicit int (values <1 clamp to serial). Performance-only knob: every value produces byte-identical output. Invalid values raise cleanly.- Categorical/dictionary column support — pandas/Polars
Categorical/Enum(ArrowDictionary) columns are now decoded and written; previously rejected outright. Non-categorical workloads pay nothing (fast-path early return). - Null-type column support — all-
Nonecolumns (ArrowNull) now write as blank cells instead of raising. - Clear column-reference errors — unmatched
column_formats/column_widths/hidden_columnsnames hard-error and list available columns as a copyable Python literal. Case-sensitive exact match.
Performance enhancement
- Parallel single-sheet row generation — large single sheets (>50k rows, no table headers, multi-core) now generate row XML across rayon workers. Byte-identical to the serial path by construction. No regression on the serial path (
#[inline(always)]per-row writer).
Bug Fixes
Styles & formatting
- Cell borders never rendered (
borderIdhardcoded to 0). - Out-of-range
text_rotationcorrupted the workbook; now mapped/clamped to valid encoding. - Invalid color strings (
"red","#FF0000","F00") broke the entire stylesheet; now normalized to ARGB or omitted (fonts, fills, color scales, data bars).
Values & types uint64abovei64::MAXoverflowed to negative; now routed through the exact f64 path.- Formulas with a leading
=doubled to==; now stripped. - Excel-1900 date serials off by one on/before 1900-02-28 (phantom 1900-02-29); now matches Excel's canonical serials.
- Pre-1900 dates produced invalid negative serials; now written as ISO-8601 strings (1900+ stay date-typed).
- NaN/±Inf in the dict path emitted invalid
<v>NaN</v>/<v>inf</v>; now empty cells (matching the Arrow path).
Ranges & geometry - Reversed ranges (end before start) silently discarded CF/merge/data-validation rules; now normalized to valid A1.
- No enforcement of Excel's grid limits; sheets past 1,048,576 rows / 16,384 cols now rejected with a catchable error on all paths.
- Hyperlink on row 0 corrupted the sheet; row clamped to ≥1.
- Hyperlink inside a merged range corrupted the workbook; ref relocated to the merge anchor.
Tables & charts - CRITICAL — table with out-of-range
end_colpanicked and (underpanic="abort") crashed the whole Python process; now clamped/guarded on all four paths. - Tables with spaced/invalid names produced unopenable files; names sanitized.
- Duplicate table names corrupted the workbook; unique id appended to
name/displayName. legend_positiondocumented but ignored; now parsed.- Scatter-chart value-axis element order violated ECMA-376 (
majorGridlinesnow precedestitle). - Chart title/axis colors written raw; now normalized.
title_font_size=0(invalid) clamped to the valid 100–400000 range.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About Jetxl
All releases →Beta — feedback welcome: [email protected]