From 77e7a6ee7a69fb0631d4fea008e3efc9d11d8e52 Mon Sep 17 00:00:00 2001 From: Liu Jinchang Date: Mon, 22 Jun 2026 14:22:02 +0800 Subject: [PATCH] fix(docparser): prevent exception escape in doConvertFile from aborting host process MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move createParser() call and nullptr check inside the try block in doConvertFile() so parser constructor exceptions are also caught - Replace throwing std::logic_error with a log + return {} for unsupported extensions, aligning with tryConvertWithTruncation() - Prevents std::logic_error from escaping DocParser::convertFile, which previously triggered std::terminate -> abort in callers without try-catch (e.g. dde-file-manager TextExtractor::extract) - Add binary test file test_crash_unsupported_ext.dat to reproduce/regress the unsupported-extension crash path 修复(docparser): 防止 doConvertFile 中异常逃逸导致宿主进程崩溃 - 将 createParser() 调用和 nullptr 检查移入 doConvertFile() 的 try 块内,确保解析器构造期异常也被捕获 - 不支持的扩展名由抛出 std::logic_error 改为打印日志并返回空串,与 tryConvertWithTruncation() 写法保持一致 - 防止 std::logic_error 从 DocParser::convertFile 逃逸,原先会在无 try-catch 的调用方(如 dde-file-manager 的 TextExtractor::extract)触发 std::terminate -> abort - 新增二进制测试文件 test_crash_unsupported_ext.dat,用于复现/回归不支持扩展名的崩溃路径 Log: 修复 doConvertFile 中异常逃逸导致宿主进程 std::terminate -> abort 的问题,将不支持扩展名的处理由抛异常改为返回空串,并把 createParser 调用纳入 try 保护 Task: https://pms.uniontech.com/task-view-391293.html --- src/docparser.cpp | 16 +++++++++++----- tests/file/test_crash_unsupported_ext.dat | Bin 0 -> 19 bytes 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 tests/file/test_crash_unsupported_ext.dat diff --git a/src/docparser.cpp b/src/docparser.cpp index 7233075..203f6a1 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -283,12 +283,18 @@ static std::string doConvertFile(const std::string &filename, std::string suffix std::transform(suffix.begin(), suffix.end(), suffix.begin(), [](unsigned char c) { return std::tolower(c); }); - std::unique_ptr document = createParser(filename, suffix); - if (!document) { - throw std::logic_error("Unsupported file extension: " + filename); - } - + // createParser() 的调用和 nullptr 检查都必须在 try 块内: + // 1) 构造期可能抛异常(如某些解析器在打开损坏文件时); + // 2) 不支持的扩展名不应抛异常——上层调用方(如 dde-file-manager 的 + // TextExtractor::extract)可能没有 try-catch,异常一旦逃逸会触发 + // std::terminate -> abort。此处返回空串,与 tryConvertWithTruncation 一致。 try { + std::unique_ptr document = createParser(filename, suffix); + if (!document) { + std::cout << "Unsupported file extension: " << filename << std::endl; + return {}; + } + document->convert(); // Use move semantics to avoid copying return std::move(document->m_text); diff --git a/tests/file/test_crash_unsupported_ext.dat b/tests/file/test_crash_unsupported_ext.dat new file mode 100644 index 0000000000000000000000000000000000000000..bfd33dbdb3d8b9b64ec562a763866b1350e0b0ad GIT binary patch literal 19 bcmZQzWMcmRuVKQ14F@hf_^@jCnY-@*T$T&K literal 0 HcmV?d00001