From 9e3a4c1772f5ffca37d471550a538efdcaba28ff Mon Sep 17 00:00:00 2001 From: Liu Jinchang Date: Mon, 22 Jun 2026 11:29:52 +0800 Subject: [PATCH] fix(excel): fix segfault on xlsx with main content type declared via MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Wrap the branch in iterate_files_by_contenttype_expat_callback_element_start (xlsxio_read.c) with #ifndef USE_MINIZIP so the minizip backend skips the zip directory traversal at compile time; previously the traversal ran inside an expat callback while [Content_Types].xml was open for streaming read, reentering the minizip single-state handle and crashing in unzGetCurrentFileInfo (upstream issue #28, unfixed in xlsxio 0.2.36) - Add regression sample tests/file/test_xlsxio_default_crash.xlsx whose [Content_Types].xml declares the main content type via to cover the former crash path 修复(excel): 修复 main contenttype 经 声明的 xlsx 解析段错误 - 在 iterate_files_by_contenttype_expat_callback_element_start 的 分支用 #ifndef USE_MINIZIP 包裹,使 minizip 后端编译期跳过 zip 目录遍历;原实现该遍历在 expat 回调内执行,而此时 [Content_Types].xml 已打开流式读取,对同一 unzFile 重入导致 minizip 单状态机冲突,在 unzGetCurrentFileInfo 处段错误(上游 issue #28,xlsxio 0.2.36 未修复) - 新增回归样本 tests/file/test_xlsxio_default_crash.xlsx,其 [Content_Types].xml 将 main contenttype 经 声明,覆盖原崩溃路径 Log: 修复 xlsxio 在 minizip 后端下解析 [Content_Types].xml 中经 声明的 main contenttype 时,因目录遍历重入已打开文件的流式读取状态而在 unzGetCurrentFileInfo 处段错误的问题,并补充回归样本 Task: https://pms.uniontech.com/task-view-391297.html https://github.com/brechtsanders/xlsxio/issues/28 --- 3rdparty/libs/fileext/excel/xlsxio/xlsxio_read.c | 8 ++++++++ tests/file/test_xlsxio_default_crash.xlsx | Bin 0 -> 602 bytes 2 files changed, 8 insertions(+) create mode 100644 tests/file/test_xlsxio_default_crash.xlsx diff --git a/3rdparty/libs/fileext/excel/xlsxio/xlsxio_read.c b/3rdparty/libs/fileext/excel/xlsxio/xlsxio_read.c index fcf18a9..05559f6 100644 --- a/3rdparty/libs/fileext/excel/xlsxio/xlsxio_read.c +++ b/3rdparty/libs/fileext/excel/xlsxio/xlsxio_read.c @@ -684,6 +684,13 @@ void iterate_files_by_contenttype_expat_callback_element_start (void* callbackda } } else if (XML_Char_icmp_ins(name, X("Default")) == 0) { //by extension + // minizip 后端下:外层 expat_process_zip_file 已 unzOpenCurrentFile 打开 + // [Content_Types].xml 并流式读取,此处对同一 unzFile 调用 unzGoToFirstFile / + // unzGetCurrentFileInfo / unzGoToNextFile 会破坏 minizip 单状态机导致段错误 + // (上游 issue #28,xlsxio 0.2.36 仍未修复)。合法 xlsx 的 main contenttype 必 + // 通过 声明, 扩展名匹配对 xlsxio 无意义,故 minizip 后端 + // 直接跳过本分支;libzip 后端基于索引的 zip_get_name 不受影响,逻辑保留。 +#ifndef USE_MINIZIP const XML_Char* contenttype; const XML_Char* extension; if ((contenttype = get_expat_attr_by_name(atts, X("ContentType"))) != NULL && XML_Char_icmp(contenttype, data->contenttype) == 0) { @@ -731,6 +738,7 @@ unzGetGlobalInfo(data->zip, &zipglobalinfo); #endif } } +#endif /* !USE_MINIZIP: 跳过 分支,避免 minizip 状态冲突崩溃 */ } } diff --git a/tests/file/test_xlsxio_default_crash.xlsx b/tests/file/test_xlsxio_default_crash.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..30c9a9030fc9cb782607d16ad23b3862cabd3ab2 GIT binary patch literal 602 zcmWIWW@Zs#U|`^2XpFcP(bEZzP z%{y$s)B1g$(*>!BA}bNsL`&y-zX@^;6EdPZTsRjAscc{WW{da5rNWMOc6BQ4hfUcE z4<53cII;SwcVo)r&nD78EC0NhxAXzm69p9~<@^($4D5K0N4trg^~re>lwEgm*4rk* zh^0MOrf5#(*t#_Jn&cbKv@89!|Ci)0>I&Jt>)eFLAKHZHIE%i&9=1>a(wm??_kM>> znK+^NgILz&udR3VJ*F=^8C`O6Uh-y*bF2qHHbo={M2864yuEhtmw(E^1OJoj%9tJu9ZEq|b{w&jCc0RkdHtj6zvJ>~& zJI!(-zmdW-iq7Z0RYj^?e72p literal 0 HcmV?d00001