[GH-ISSUE #490] Infinite Loop in workbook_close() with Invalid Chart Scale Parameters #382

Closed
opened 2026-05-05 12:14:05 -06:00 by gitea-mirror · 4 comments
Owner

Originally created by @LkkkLxy on GitHub (Oct 11, 2025).
Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/490

Originally assigned to: @jmcnamara on GitHub.

Description

An infinite loop vulnerability exists in libxlsxwriter that causes the program to hang indefinitely when workbook_close() is called after inserting a chart with infinite or extremely large scale values in lxw_chart_options.

Steps to Reproduce

Environment

  • OS: Linux (tested on Ubuntu with Docker)
  • libxlsxwriter version: Current git master
  • Compiler: clang with AddressSanitizer

Compilation Command

clang test_infinite_loop.c -o test_infinite_loop \
    -fsanitize=address \
    -I/path/to/libxlsxwriter/include \
    /path/to/libxlsxwriter.a \
    -lz -lm

Minimal Test Case

#include <xlsxwriter.h>
#include <math.h>
#include <stdio.h>

int main() {
    // Create workbook
    lxw_workbook *workbook = workbook_new("/tmp/test.xlsx");
    if (!workbook) return 1;

    // Add worksheet
    lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
    if (!worksheet) {
        workbook_close(workbook);
        return 1;
    }

    // Add chart
    lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE);
    if (!chart) {
        workbook_close(workbook);
        return 1;
    }

    // Add data series
    chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5");

    // Insert chart with infinite x_scale - triggers infinite loop
    lxw_chart_options chart_opts = {0};
    chart_opts.x_scale = INFINITY;  // This causes the bug
    chart_opts.y_scale = 1.0;

    worksheet_insert_chart_opt(worksheet, 0, 0, chart, &chart_opts);

    // This call hangs indefinitely
    printf("Calling workbook_close...\n");
    workbook_close(workbook);  // Program hangs here
    printf("Should never reach here\n");

    return 0;
}

Expected Behavior

The library should either:

  1. Validate the x_scale and y_scale parameters and return an error for invalid values (INFINITY, NAN, negative values)
  2. Handle extreme values gracefully without hanging

Actual Behavior

The program hangs indefinitely in workbook_close() and must be forcefully terminated.

Verification

$ timeout 5 ./test_infinite_loop
Calling workbook_close...
# Process hangs and is killed after 5 seconds

Root Cause

The infinite loop occurs in src/worksheet.c:3010 in the _worksheet_position_object_pixels() function:

/* Subtract the underlying cell widths to find the end cell. */
while (width >= _worksheet_size_col(self, col_end, anchor)) {
    width -= _worksheet_size_col(self, col_end, anchor);
    col_end++;
}

When chart_opts.x_scale is set to INFINITY:

  1. The computed width becomes INFINITY
  2. The loop condition width >= _worksheet_size_col(...) is always true
  3. Subtracting from infinity still leaves infinity: INFINITY - finite_value = INFINITY
  4. The loop never terminates

Call Stack

#4  _worksheet_size_col at worksheet.c:2815
#5  _worksheet_position_object_pixels at worksheet.c:3011
#6  _worksheet_position_object_emus at worksheet.c:3050
#7  lxw_worksheet_prepare_chart at worksheet.c:3674
#8  _prepare_drawings at workbook.c:1238
#9  workbook_close at workbook.c:2272

Additional Information

This bug is detected by fuzzing.

Originally created by @LkkkLxy on GitHub (Oct 11, 2025). Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/490 Originally assigned to: @jmcnamara on GitHub. ## Description An infinite loop vulnerability exists in libxlsxwriter that causes the program to hang indefinitely when `workbook_close()` is called after inserting a chart with infinite or extremely large scale values in `lxw_chart_options`. ## Steps to Reproduce ### Environment - **OS**: Linux (tested on Ubuntu with Docker) - **libxlsxwriter version**: Current git master - **Compiler**: clang with AddressSanitizer ### Compilation Command ```bash clang test_infinite_loop.c -o test_infinite_loop \ -fsanitize=address \ -I/path/to/libxlsxwriter/include \ /path/to/libxlsxwriter.a \ -lz -lm ``` ### Minimal Test Case ```c #include <xlsxwriter.h> #include <math.h> #include <stdio.h> int main() { // Create workbook lxw_workbook *workbook = workbook_new("/tmp/test.xlsx"); if (!workbook) return 1; // Add worksheet lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); if (!worksheet) { workbook_close(workbook); return 1; } // Add chart lxw_chart *chart = workbook_add_chart(workbook, LXW_CHART_LINE); if (!chart) { workbook_close(workbook); return 1; } // Add data series chart_add_series(chart, NULL, "=Sheet1!$A$1:$A$5"); // Insert chart with infinite x_scale - triggers infinite loop lxw_chart_options chart_opts = {0}; chart_opts.x_scale = INFINITY; // This causes the bug chart_opts.y_scale = 1.0; worksheet_insert_chart_opt(worksheet, 0, 0, chart, &chart_opts); // This call hangs indefinitely printf("Calling workbook_close...\n"); workbook_close(workbook); // Program hangs here printf("Should never reach here\n"); return 0; } ``` ### Expected Behavior The library should either: 1. Validate the `x_scale` and `y_scale` parameters and return an error for invalid values (INFINITY, NAN, negative values) 2. Handle extreme values gracefully without hanging ### Actual Behavior The program hangs indefinitely in `workbook_close()` and must be forcefully terminated. ### Verification ```bash $ timeout 5 ./test_infinite_loop Calling workbook_close... # Process hangs and is killed after 5 seconds ``` ## Root Cause The infinite loop occurs in `src/worksheet.c:3010` in the `_worksheet_position_object_pixels()` function: ```c /* Subtract the underlying cell widths to find the end cell. */ while (width >= _worksheet_size_col(self, col_end, anchor)) { width -= _worksheet_size_col(self, col_end, anchor); col_end++; } ``` When `chart_opts.x_scale` is set to `INFINITY`: 1. The computed `width` becomes `INFINITY` 2. The loop condition `width >= _worksheet_size_col(...)` is always true 3. Subtracting from infinity still leaves infinity: `INFINITY - finite_value = INFINITY` 4. The loop never terminates ### Call Stack ``` #4 _worksheet_size_col at worksheet.c:2815 #5 _worksheet_position_object_pixels at worksheet.c:3011 #6 _worksheet_position_object_emus at worksheet.c:3050 #7 lxw_worksheet_prepare_chart at worksheet.c:3674 #8 _prepare_drawings at workbook.c:1238 #9 workbook_close at workbook.c:2272 ``` ## Additional Information This bug is detected by fuzzing.
gitea-mirror 2026-05-05 12:14:05 -06:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@jmcnamara commented on GitHub (Oct 13, 2025):

I think this is a user error. If the user enters INFINITY then they are getting what they ask for.

I will look into a fix anyway.

<!-- gh-comment-id:3396403051 --> @jmcnamara commented on GitHub (Oct 13, 2025): I think this is a user error. If the user enters INFINITY then they are getting what they ask for. I will look into a fix anyway.
Author
Owner

@jmcnamara commented on GitHub (Oct 30, 2025):

Fixed on main. Thanks for the report.

<!-- gh-comment-id:3466704703 --> @jmcnamara commented on GitHub (Oct 30, 2025): Fixed on main. Thanks for the report.
Author
Owner

@kruftindustries commented on GitHub (Jan 16, 2026):

This is bad timing but I studied this issue and found excel calculates the percent based on a maximum width and height, not sure if it's different on other machines or if there are settings that can affect the value.

#define LXW_OBJECT_MAX_SIZE_PIXELS 225408.0 /* Excel max: 2348 inches * 96 DPI */
#define LXW_OBJECT_MIN_SCALE 0.01 /

<!-- gh-comment-id:3758516846 --> @kruftindustries commented on GitHub (Jan 16, 2026): This is bad timing but I studied this issue and found excel calculates the percent based on a maximum width and height, not sure if it's different on other machines or if there are settings that can affect the value. #define LXW_OBJECT_MAX_SIZE_PIXELS 225408.0 /* Excel max: 2348 inches * 96 DPI */ #define LXW_OBJECT_MIN_SCALE 0.01 /
Author
Owner

@jmcnamara commented on GitHub (Jan 16, 2026):

I studied this issue and found excel calculates the percent based on a maximum width and height

@kruftindustries That looks like a bug but it is different from this one. Could you open a new bug report for it. Thanks.

<!-- gh-comment-id:3759053756 --> @jmcnamara commented on GitHub (Jan 16, 2026): > I studied this issue and found excel calculates the percent based on a maximum width and height @kruftindustries That looks like a bug but it is different from this one. Could you open a new bug report for it. Thanks.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/libxlsxwriter#382
No description provided.