mirror of
https://github.com/jmcnamara/libxlsxwriter.git
synced 2026-05-15 06:06:09 -06:00
[GH-ISSUE #513] worksheet_add_table allocates O(n²) memory for default column headers, allocating excess memory, especially for wide tables #399
Labels
No labels
awaiting user feedback
bug
cmake
cmake
docs
feature request
in progress
long term
medium term
medium term
pull-request
question
question
ready to close
short term
under investigation
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/libxlsxwriter#399
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @billdenney on GitHub (Apr 6, 2026).
Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/513
Summary
When
worksheet_add_table()is called without user-supplied column options, the internal function that generates default "Column1", "Column2", … headers allocatesnum_colscopies oflxw_table_columnper loop iteration instead of one. Total allocation grows asnum_cols², causingcallocto fail and the function to returnLXW_ERROR_MEMORY_MALLOC_FAILEDfor any table wide enough thatnum_cols² × sizeof(lxw_table_column)exceeds available memory.Reproduction
Expected behaviour
worksheet_add_table()succeeds (returnsLXW_NO_ERROR) for any column count within Excel's limits.Actual behaviour
On Linux with the default overcommit policy,
callocreturns non-NULLfor eachallocation (virtual pages are not backed by physical memory until accessed, and
only the first element of each allocation is written). The function therefore
appears to succeed, but silently maps up to ~15 GB of virtual address space.
On systems where overcommit is disabled, or when virtual memory is capped (e.g.
ulimit -v 2097152), the call fails and returnsLXW_ERROR_MEMORY_MALLOC_FAILED.The failure also occurs on embedded targets and any allocator that enforces
commit limits.
Root cause
In
_set_default_table_columns()(called byworksheet_add_table()when nolxw_table_optionsare provided), the inner loop contains:The second argument to
callocisnum_colsinstead of1, allocatingnum_colsstructs on every iteration when only one is needed. Onlycolumns[i](the first element of each over-allocated block) is ever used. The remainingnum_cols - 1structs per iteration are unreachable. The existing cleanup path (_free_worksheet_table_column→free(columns[i])) correctly frees each block, so there is no memory leak — only the excessive upfront allocation.