From 95167ece6756babd3f88f1068e86c4853267aa47 Mon Sep 17 00:00:00 2001 From: Da Shen Date: Thu, 28 May 2026 13:32:51 +0800 Subject: [PATCH 1/2] =?UTF-8?q?[0177]=20=E4=BF=AE=E5=A4=8D=20extract=5Fatt?= =?UTF-8?q?achments=5Ffrom=5Fpdf=20=E4=B8=AD=20streamReader=20=E7=9A=84?= =?UTF-8?q?=E5=86=85=E5=AD=98=E6=B3=84=E6=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- devel/0177.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 devel/0177.md diff --git a/devel/0177.md b/devel/0177.md new file mode 100644 index 0000000000..4d17a176b8 --- /dev/null +++ b/devel/0177.md @@ -0,0 +1,26 @@ +# [0177] 修复 extract_attachments_from_pdf 中 streamReader 的内存泄漏 + +## 相关文档 +- [0171.md](0171.md) - 上一轮内存泄漏修复 + +## 任务相关的代码文件 +- `src/Plugins/Pdf/pdf_hummus_extract_attachment.cpp` + +## 如何测试 + +### 确定性测试 +```bash +xmake b stem +``` + +## What + +1. 修复 `extract_attachments_from_pdf` 函数中 `IByteReader* streamReader` 的内存泄漏。`streamReader` 仅在 for 循环的成功迭代结束时被 `delete`,当循环中任何错误路径触发 `break` 时,`streamReader` 不会被释放。 + +## Why + +`streamReader` 在循环内部通过 `parser.CreateInputStreamReader()` 分配。循环中有多个 `break` 点(文件打开失败、流拷贝失败、关闭失败等),这些路径跳过了 `delete streamReader`。 + +## How + +将 `streamReader` 声明提升到 for 循环之前并初始化为 `nullptr`。成功路径在 `delete` 后置 `nullptr`。在 for 循环结束后添加 `delete streamReader`(`delete nullptr` 安全),确保 `break` 路径也能释放。 From ac5f5e46444f20c0a9f378e19ea9d50d135fb15e Mon Sep 17 00:00:00 2001 From: Da Shen Date: Thu, 28 May 2026 13:33:08 +0800 Subject: [PATCH 2/2] =?UTF-8?q?[0177]=20=E4=BF=AE=E5=A4=8D=20extract=5Fatt?= =?UTF-8?q?achments=5Ffrom=5Fpdf=20=E4=B8=AD=20streamReader=20=E7=9A=84?= =?UTF-8?q?=E5=86=85=E5=AD=98=E6=B3=84=E6=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- src/Plugins/Pdf/pdf_hummus_extract_attachment.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Plugins/Pdf/pdf_hummus_extract_attachment.cpp b/src/Plugins/Pdf/pdf_hummus_extract_attachment.cpp index 45b8214370..aa06a4ad91 100644 --- a/src/Plugins/Pdf/pdf_hummus_extract_attachment.cpp +++ b/src/Plugins/Pdf/pdf_hummus_extract_attachment.cpp @@ -98,6 +98,7 @@ extract_attachments_from_pdf (url pdf_path, list& names) { status= PDFHummus::eFailure; break; } + IByteReader* streamReader= nullptr; for (unsigned long i= 0; i < n; i+= 2) { PDFObjectCastPtr name (arr->QueryObject (i)); if (!name) { @@ -129,8 +130,7 @@ extract_attachments_from_pdf (url pdf_path, list& names) { } PDFDictionary* dir= stream->QueryStreamDictionary (); - IByteReader* streamReader= - parser.CreateInputStreamReader (stream.GetPtr ()); + streamReader= parser.CreateInputStreamReader (stream.GetPtr ()); if (!streamReader) { if (DEBUG_CONVERT) debug_convert << "Can't find streamReader" << LF; status= PDFHummus::eFailure; @@ -165,7 +165,9 @@ extract_attachments_from_pdf (url pdf_path, list& names) { names= names * attachment_path; delete streamReader; + streamReader= nullptr; } + delete streamReader; } while (false); if (status == PDFHummus::eFailure) return false; else return true;