Repository navigation
fix(outlook): strip NUL terminators from Unicode MSG string streams - #2738
Open
陈志谦 (simpleqt) wants to merge 1 commit into
Open
陈志谦 (simpleqt) wants to merge 1 commit into
陈志谦 (simpleqt) wants to merge 1 commit into
Conversation
Some writers terminate or pad a string stream with NULs, and the non-Unicode
path removes them before decoding. The Unicode path does not: there a
terminator is a UTF-16 code unit, which decodes to a NUL character that
str.strip() keeps. Converting such a message left a NUL at the end of every
header value, of the body and of the document title, and a property holding
nothing but its terminator was reported as a value ("\x00") instead of being
omitted.
Remove the terminators from the decoded text. That has to happen after
decoding: the last byte of a UTF-16 stream is the high byte of its final
character, so the bytes cannot be stripped the way the 8-bit streams are.
Add regression coverage mirroring the existing ANSI terminator and
empty-property cases.
Signed-off-by: simpleqt <2015900818@qq.com>
Author
AI assistanceStated here rather than left implicit: this change was produced with AI assistance - an autonomous coding agent prepared the analysis, the fix, the regression test, and this description. A human reviewed the result before submission. Disclosing this is now something I do on every submission. I did not do it consistently in earlier contributions, here or elsewhere, and I am going back over them. This repository has no contributing guide and no AI clause, so nothing here is being corrected; I am stating it because omitting it is what got me into trouble in repositories that do ask. |
wd5708698-png
approved these changes
Oct 23, 2026
San-Hsien (SanHsien)
pushed a commit
to SanHsien/markitdown
that referenced
this pull request
Oct 25, 2026
本 repo 已停用 issues,接續開發報告依規定寫在本 commit 訊息。 # 接續開發報告 2026-10-25 ## 一、線索與處理 - open/draft PR:無。PR #1 已關閉未合併,內容已 squash 進 main(bebd625), head 分支 ci/job-names-20261024 已不在遠端。 - 非預設分支:只有 claude/gifted-dirac-r9vpm0(本 session 工作分支,內容已 fast-forward 進 main)。 - open issue:無(issues 已停用)。 - main 紅燈 Dependency freshness:ruff 0.17.2。對 E9+F gate 全綠,記入 .github/dependency-deferrals.json(deferredLatest),未調高下限 → 已轉綠。 - main 紅燈 Upstream check:20 commit/153 PR/40 issue 未審 → 第三輪審查完成,已轉綠。 - HANDOFF.md/TODO.md:不存在。程式碼 TODO/FIXME 7 處皆為上游產品碼,不動。 - REVIEW.md:R-01~R-10 已修,無未修項。 - 2026-09-30 待辦 microsoft#2506:觸發條件成立(上游整併測試依賴它),已採用(4a377f9)。 ## 二、做了什麼(bebd625..本 commit) - 上游 commit:cherry-pick -x 本輪 20 筆中 19 筆(9a15f66..e211f83),microsoft#2731 部分採用(3e440d7), 補採 microsoft#2506(4a377f9)。 - 例外移植上游 OPEN PR,皆先重現缺陷、附 PR 測試: - microsoft#2674(1029094):短 UTF-8 文字被誤判 UTF-16 亂碼。 - microsoft#2742(9947ed1):UTF-8 BOM 殘留。 - microsoft#2738(38a2ae6):Outlook MSG 尾端 NUL。 - microsoft#2620(0d1140c):大寫副檔名音訊不轉譯。 - 依賴(c561006): - requirements 跟隨上游 magika/mammoth/certifi,補列 ocr 漏的 PyMuPDF、Pillow。 - dependabot 補 ocr 與 sample-plugin 目錄。 - ruff 延後。 - 文件(8f1db57、3382745、b618bc9、本 commit): - microsoft#1913 英文段落併入 README.en.md。 - 繁中 README text_content → markdown。 - DECISIONS/UPSTREAM/baseline 推進水位。 - CI(d4c2b7a):移除 microsoft#2586 帶進 tests.yml 的 Linux 專用 apt-get 步驟(R-09)。 - 驗證: - 每批推送前由全新審查員審 diff 並等 Windows CI 完成(一次 NO-SHIP,修正後重審 ship)。 - 維護 gate 與 Windows CI py3.10–3.14 全綠。 - 產品測試(Linux 雲端)1312 passed/12 skipped/2 failed,2 個失敗皆因沙箱無對外網路。 ## 三、上游結論 - 水位:commit 7482c09、PR microsoft#2765、issue microsoft#2762。 - commit:採用 18、部分採用 1(microsoft#2731 ARM/pre-commit CI 不適用),microsoft#2733 版本 bump 不適用。 - PR: - MERGED 12,例外移植 4。 - 其餘 OPEN 不 fork-ahead,等上游合併。 - 無 merge ref 12 筆多為重複,不採。 - issue:已修 2(microsoft#2646、microsoft#2719),16 筆對應 OPEN PR,其餘為不適用、觸發條件或垃圾。 - 逐筆見 docs/DECISIONS.md 2026-10-25。 ## 四、刻意不做(理由/觸發條件) - microsoft#2756 ZIP 檔名:會把 Big5「臺灣報告.pdf」解成亂碼(誤判為 shift_jis_2004)。 觸發:上游合併時先補 cp950 測試,或改為優先 metadata_encoding/locale。 - microsoft#2621/microsoft#2622 SSRF 政策:牽動 MCP/URI 擷取。 觸發:上游合併,或本 fork 對外提供 MCP HTTP 服務。 - microsoft#2679/microsoft#2723 cp1252 偵測:可能影響 CJK 舊碼頁。觸發:上游合併後跑 CJK charset 測試。 - microsoft#2407 youtube-transcript-api ~=1.2.3:維持本 fork >=1.0.0+freshness-hold。 - microsoft#2740 Python 3.15:上游 CI 加 3.15 時同步 ci.yml。 ## 五、需要維護者決定 1. 雲端 session 對 microsoft/markitdown 無 API 權限(只能匿名 git 讀取)。 本輪 PR/issue 清單取自本 fork Upstream check log,狀態以 refs/pull/*/merge 判斷。 2. 產品程式變動只在 Linux 跑過;ci.yml 只跑維護 gate。請在 Windows 11 本機跑 pwsh -NoProfile -File tools\test_product.ps1 -AllPackages。 3. 「不 fork-ahead」政策的 4 筆例外移植;若不同意可 revert 1029094、9947ed1、38a2ae6、0d1140c。 STATUS: NEEDS-MAINTAINER Windows 11 本機跑 test_product.ps1 -AllPackages;確認是否接受 4 筆上游 open PR 例外移植 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CWBckUdMZcCAsc15iaJtm
San-Hsien (SanHsien)
pushed a commit
to SanHsien/markitdown
that referenced
this pull request
Oct 25, 2026
本 repo 已停用 issues,接續開發報告依規定寫在本 commit 訊息。 # 接續開發報告 2026-10-25 ## 一、線索與處理 - open/draft PR:無。PR #1 已關閉未合併,內容已 squash 進 main(bebd625), head 分支 ci/job-names-20261024 已不在遠端。 - 非預設分支:只有 claude/gifted-dirac-r9vpm0(本 session 工作分支,內容已 fast-forward 進 main)。 - open issue:無(issues 已停用)。 - main 紅燈 Dependency freshness:ruff 0.17.2。對 E9+F gate 全綠,記入 .github/dependency-deferrals.json(deferredLatest),未調高下限 → 已轉綠。 - main 紅燈 Upstream check:20 commit/153 PR/40 issue 未審 → 第三輪審查完成,已轉綠。 - HANDOFF.md/TODO.md:不存在。程式碼 TODO/FIXME 7 處皆為上游產品碼,不動。 - REVIEW.md:R-01~R-10 已修,無未修項。 - 2026-09-30 待辦 microsoft#2506:觸發條件成立(上游整併測試依賴它),已採用(4a377f9)。 ## 二、做了什麼(bebd625..本 commit) - 上游 commit:cherry-pick -x 本輪 20 筆中 19 筆(9a15f66..e211f83),microsoft#2731 部分採用(3e440d7), 補採 microsoft#2506(4a377f9)。 - 例外移植上游 OPEN PR,皆先重現缺陷、附 PR 測試: - microsoft#2674(1029094):短 UTF-8 文字被誤判 UTF-16 亂碼。 - microsoft#2742(9947ed1):UTF-8 BOM 殘留。 - microsoft#2738(38a2ae6):Outlook MSG 尾端 NUL。 - microsoft#2620(0d1140c):大寫副檔名音訊不轉譯。 - 依賴(c561006): - requirements 跟隨上游 magika/mammoth/certifi,補列 ocr 漏的 PyMuPDF、Pillow。 - dependabot 補 ocr 與 sample-plugin 目錄。 - ruff 延後。 - 文件(8f1db57、3382745、b618bc9、本 commit): - microsoft#1913 英文段落併入 README.en.md。 - 繁中 README text_content → markdown。 - DECISIONS/UPSTREAM/baseline 推進水位。 - CI(d4c2b7a):移除 microsoft#2586 帶進 tests.yml 的 Linux 專用 apt-get 步驟(R-09)。 - 驗證: - 每批推送前由全新審查員審 diff 並等 Windows CI 完成(一次 NO-SHIP,修正後重審 ship)。 - 維護 gate 與 Windows CI py3.10–3.14 全綠。 - 產品測試(Linux 雲端)1312 passed/12 skipped/2 failed,2 個失敗皆因沙箱無對外網路。 ## 三、上游結論 - 水位:commit 7482c09、PR microsoft#2765、issue microsoft#2762。 - commit:採用 18、部分採用 1(microsoft#2731 ARM/pre-commit CI 不適用),microsoft#2733 版本 bump 不適用。 - PR: - MERGED 12,例外移植 4。 - 其餘 OPEN 不 fork-ahead,等上游合併。 - 無 merge ref 12 筆多為重複,不採。 - issue:已修 2(microsoft#2646、microsoft#2719),16 筆對應 OPEN PR,其餘為不適用、觸發條件或垃圾。 - 逐筆見 docs/DECISIONS.md 2026-10-25。 ## 四、刻意不做(理由/觸發條件) - microsoft#2756 ZIP 檔名:會把 Big5「臺灣報告.pdf」解成亂碼(誤判為 shift_jis_2004)。 觸發:上游合併時先補 cp950 測試,或改為優先 metadata_encoding/locale。 - microsoft#2621/microsoft#2622 SSRF 政策:牽動 MCP/URI 擷取。 觸發:上游合併,或本 fork 對外提供 MCP HTTP 服務。 - microsoft#2679/microsoft#2723 cp1252 偵測:可能影響 CJK 舊碼頁。觸發:上游合併後跑 CJK charset 測試。 - microsoft#2407 youtube-transcript-api ~=1.2.3:維持本 fork >=1.0.0+freshness-hold。 - microsoft#2740 Python 3.15:上游 CI 加 3.15 時同步 ci.yml。 ## 五、需要維護者決定 1. 雲端 session 對 microsoft/markitdown 無 API 權限(只能匿名 git 讀取)。 本輪 PR/issue 清單取自本 fork Upstream check log,狀態以 refs/pull/*/merge 判斷。 2. 產品程式變動只在 Linux 跑過;ci.yml 只跑維護 gate。請在 Windows 11 本機跑 pwsh -NoProfile -File tools\test_product.ps1 -AllPackages。 3. 「不 fork-ahead」政策的 4 筆例外移植;若不同意可 revert 1029094、9947ed1、38a2ae6、0d1140c。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014CWBckUdMZcCAsc15iaJtm STATUS: NEEDS-MAINTAINER Windows 11 本機跑 test_product.ps1 -AllPackages;確認是否接受 4 筆上游 open PR 例外移植
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
OutlookMsgConverter._get_stream_datadecodes the PT_UNICODE string streams (__substg1.0_<tag>001F) and only callsstr.strip():Some
.msgwriters terminate or pad a string stream with NULs, andstr.strip()keeps NULs, so the terminator survives as a character. Converting such a message emits U+0000 at the end of every header value, the body and the document title:Subject'Confirmacion de la reunion\x00''Confirmacion de la reunion''\x00'The non-Unicode path already handles this -
_get_ansi_stream_datadoesdata.rstrip(b"\x00"), merged in #2462, and its tests treatb"\x00"/b"\x00\x00"as expected input. The Unicode path was simply missed. Per [MS-OXMSG] 2.1.4.2.2 the string values in these streams end with the NULL terminator, so the input is valid and the output should not carry it.Fix
used in place of the bare
.strip().The bytes themselves cannot simply be stripped the way
_get_ansi_stream_datadoes: in a UTF-16 stream the last byte is the high byte of the final character, sodata.rstrip(b"\x00")would corrupt the text. Stripping on the decoded string is safe and keeps the two paths equivalent. Removing the terminator before the strip is deliberate, so a value that holds nothing but terminators reads as empty exactly as it does for a non-Unicode message.Testing
packages/markitdown/tests/test_outlook_msg.pygainstest_unicode_terminators_are_removedandtest_empty_unicode_properties_are_omitted, both parametrized overb"\x00\x00"andb"\x00\x00\x00\x00", mirroring the existing ANSI cases and comparing the whole converted markdown / title:21d9c1d, with only the test file copied in andmarkitdown.__file__verified from that worktree): 4 failed, 42 passed - the 4 failures are exactly the new cases, and every pre-existing test in the module passespackages/markitdown/testssuite is unchanged apart from the 4 new cases:1 failed, 1103 passedon base vs1 failed, 1107 passedwith the fix, the single failure being a pre-existing environmental one (test_speech_transcriptioncannot resolve a host - there is no DNS on this machine)blackat the version.pre-commit-config.yamlpins (26.10.1):2 files would be left unchangedcheckscript) output is byte-identical before and after, with none of its 30 pre-existing errors in either changed file_get_stream_datahas exactly one caller,_get_property_data, which serves From/To/Subject and the body; nothing else in the repository references it, and the ANSI and ISO-2022-JP paths are untouched. No existing test asserted that a Unicode NUL is retained - every NUL assertion in the suite is on001E/ANSI streams.AI assistance: this change was produced with AI assistance (an autonomous coding agent); the analysis, the reproduction, the before/after test runs and the lint runs were executed locally, and a human reviewed the result before submission.