Skip to content

Decode percent-encoded data URI parameters - #2547

Open
Newman Gao (bozarnr) wants to merge 1 commit into
microsoft:mainfrom
bozarnr:audit/ingestion-edge-cases
Open

Newman Gao (bozarnr) wants to merge 1 commit into
microsoft:mainfrom
bozarnr:audit/ingestion-edge-cases

Conversation

@bozarnr

Copy link
Copy Markdown

Summary

  • decode percent-encoded data URI parameter values while parsing the media type metadata
  • cover percent-encoded charset values so downstream stream decoding receives the declared charset

Validation

  • direct regression check for data:text/plain;charset=utf%2D8,...
  • python -m py_compile packages/markitdown/src/markitdown/_uri_utils.py packages/markitdown/tests/test_module_misc.py
  • git diff --check

The existing base64-data URI work addresses escapes in the payload. This change covers the independent metadata parameter path consumed by MarkItDown.convert_uri().

Copilot AI lite review requested due to automatic review settings September 23, 2026 06:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

No unresolved review issues were identified, and regression coverage is included.

Review effort: Lite
Findings: None

What changed in this PR

Updates data URI parsing to decode percent-encoded metadata parameters, including charset, before conversion.

Changes:

  • Decode parameter values with urllib.parse.unquote.
  • Add regression coverage for encoded charset and content values.
File Description
packages/​markitdown/​tests/​test_module_misc.py Tests percent-encoded data URI parsing.
packages/​markitdown/​src/​markitdown/​_uri_utils.py Decodes data URI parameter values.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Community review, does not clear the merge gate.

I read the diff and the full parse_data_uri function in packages/markitdown/src/markitdown/_uri_utils.py on main to check how the changed line interacts with the rest of the parsing.

The function splits the data URI header on ;, pops a trailing base64 flag (checked as an exact-match string comparison on parts[-1], unaffected by this change) and the mime type (parts.pop(0), also unaffected), then parses the remaining key=value parts into the attributes dict. Before this fix, the value half of each key=value pair was stored raw, with no percent-decoding, even though the body of the data URI (content = ... unquote_to_bytes(data)) was already correctly percent-decoded. That's an inconsistency: a produced URI like data:text/plain;charset=utf%2D8,Hello%2C%20World%21 would give attributes["charset"] == "utf%2D8" instead of "utf-8", which would break any caller doing a codec/charset lookup with that value.

The fix wraps the value in unquote(value). I traced the new test case by hand: meta = "text/plain;charset=utf%2D8" splits into ["text/plain", "charset=utf%2D8"], mime_type pops "text/plain", the remaining part splits into key="charset", value="utf%2D8", and unquote("utf%2D8") correctly gives "utf-8" (%2D is -). That matches the test's assertion.

This is a narrow, correctly scoped fix (only the attribute-value branch changes, not the base64-flag or bare-flag branches, which don't need decoding since they're compared as exact tokens) and the new test exercises the actual percent-encoded case rather than just re-asserting the old behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants