From b58b1fa962bdfeaeb6ef76d8af53baa9b14a01ae Mon Sep 17 00:00:00 2001 From: liuhao1024 Date: Mon, 13 Jul 2026 15:04:33 +0800 Subject: [PATCH] fix(gateway): allow [[as_document]] glued directly to MEDIA path (#63632) MEDIA_TAG_CLEANUP_RE failed to match when a directive like [[as_document]] was concatenated directly to the file extension without whitespace (e.g., MEDIA:/home/user/report.xlsx[[as_document]]). This caused the file to be silently not delivered while the gateway reported success. Root cause: the lookahead character class [\s`",;:)\}\]|$) did not include [, so [[as_document]] immediately after the extension broke the lookahead assertion. Fix: add \[ to the lookahead class so directives can follow the path without whitespace. This is safe because [ is already stripped elsewhere in the same file via .replace("[[as_document]]", ""). Added regression tests covering: - Directive glued to extension (issue case) - Directive with whitespace (baseline) - Tag at end of string ($ anchor) --- gateway/platforms/base.py | 2 +- tests/gateway/test_media_tag_cleanup.py | 61 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 tests/gateway/test_media_tag_cleanup.py diff --git a/gateway/platforms/base.py b/gateway/platforms/base.py index 4f2c0e98fa4f..af74265d9a17 100644 --- a/gateway/platforms/base.py +++ b/gateway/platforms/base.py @@ -1514,7 +1514,7 @@ MEDIA_TAG_CLEANUP_RE = re.compile( r'''[`"']?MEDIA:\s*''' r'''(?P`[^`\n]+`|"[^"\n]+"|'[^'\n]+'|''' r'''(?:~/|/|[A-Za-z]:[/\\])\S+(?:[^\S\n]+\S+)*?\.(?:''' + _MEDIA_EXT_ALTERNATION + r'''))''' - r'''(?=[\s`"',;:)\]}]|$)[`"']?''', + r'''(?=[\s`"',;:)\]}\[]|$)[`"']?''', re.IGNORECASE, ) diff --git a/tests/gateway/test_media_tag_cleanup.py b/tests/gateway/test_media_tag_cleanup.py new file mode 100644 index 000000000000..2bf77845c232 --- /dev/null +++ b/tests/gateway/test_media_tag_cleanup.py @@ -0,0 +1,61 @@ +"""Tests for MEDIA_TAG_CLEANUP_RE regex matching behavior (#63632).""" + + +class TestMediaTagCleanup: + """Tests for MEDIA_TAG_CLEANUP_RE regex matching behavior.""" + + def test_media_tag_with_directive_glued_to_extension(self): + """Regression: MEDIA:[[as_document]] must match when directive is glued + directly to the extension without whitespace (#63632). + + The fix adds `\\[` to the lookahead character class in MEDIA_TAG_CLEANUP_RE. + """ + from gateway.platforms.base import MEDIA_TAG_CLEANUP_RE + + # Issue case: [[as_document]] glued directly to .xlsx + text = "Готово. MEDIA:/home/hermes/report.xlsx[[as_document]]" + assert MEDIA_TAG_CLEANUP_RE.search(text) is not None + stripped = MEDIA_TAG_CLEANUP_RE.sub("", text) + assert "MEDIA:" not in stripped + assert "/home/hermes/report.xlsx" not in stripped + + # Same with whitespace (should still work) + text_with_space = "Готово. MEDIA:/home/hermes/report.xlsx [[as_document]]" + assert MEDIA_TAG_CLEANUP_RE.search(text_with_space) is not None + stripped = MEDIA_TAG_CLEANUP_RE.sub("", text_with_space) + assert "MEDIA:" not in stripped + assert "/home/hermes/report.xlsx" not in stripped + + # Other directives ([[as_image]]) should also work + text_image = "Done. MEDIA:/tmp/chart.png[[as_image]]" + assert MEDIA_TAG_CLEANUP_RE.search(text_image) is not None + stripped = MEDIA_TAG_CLEANUP_RE.sub("", text_image) + assert "MEDIA:" not in stripped + assert "/tmp/chart.png" not in stripped + + def test_media_tag_with_whitespace_still_works(self): + """Baseline: MEDIA tags with whitespace before/after still match.""" + from gateway.platforms.base import MEDIA_TAG_CLEANUP_RE + + # Space before closing quote + text = "Here is your report: MEDIA:/tmp/report.md " + stripped = MEDIA_TAG_CLEANUP_RE.sub("", text).strip() + assert "MEDIA:" not in stripped + assert "/tmp/report.md" not in stripped + + # Multiple spaces (regex removes tag but preserves surrounding whitespace) + text = "Report at MEDIA:/tmp/data.pdf done" + stripped = MEDIA_TAG_CLEANUP_RE.sub("", text) + assert "MEDIA:" not in stripped + assert "/tmp/data.pdf" not in stripped + assert "Report at" in stripped and "done" in stripped + + def test_media_tag_at_end_of_string(self): + """MEDIA tags at the end of a string should match ($ anchor).""" + from gateway.platforms.base import MEDIA_TAG_CLEANUP_RE + + text = "Here is the file: MEDIA:/tmp/file.docx" + stripped = MEDIA_TAG_CLEANUP_RE.sub("", text).strip() + assert "MEDIA:" not in stripped + assert "/tmp/file.docx" not in stripped + assert "Here is the file:" in stripped