Skip to content

fix(Net): keep =? and delimiters when text is not an encoded word #5564 - #5596

Open
aouxwoux wants to merge 2 commits into
pocoproject:mainfrom
aouxwoux:5564-decode-word-delimiters
Open

aouxwoux wants to merge 2 commits into
pocoproject:mainfrom
aouxwoux:5564-decode-word-delimiters

Conversation

@aouxwoux

@aouxwoux aouxwoux commented Oct 24, 2026 •

Copy link
Copy Markdown

fixes #5564

what changed

  • add parseEncodedWord in Net/src/MessageHeader.cpp to validate RFC 2047 encoded-word structure (=?charset?encoding?encoded-text?=) and check that encoding is B or Q.
  • in MessageHeader::decodeWord, retain =? when text is not a complete valid encoded word.
  • per RFC 2047 section 6.2, only ignore linear-white-space between adjacent words when both are valid and decode successfully; keep linear-white-space if either word is displayed verbatim.
  • in decodeRFC2047, return malformed Base64 and invalid Q-encoding sequences verbatim with original delimiters instead of silently corrupting or deleting values.
  • add unit tests in Net/testsuite/src/MessageHeaderTest.cpp covering incomplete words (=?base64?...?=), non-encoded =? in query strings (https://example.com/?a=?b), unknown encodings (=?x?y?z?=), malformed Base64/Q-encoding sequences, adjacent word whitespace handling, delimiter preservation in decodeRFC2047, and header deserialization with MessageHeader::read.

why

MessageHeader::decodeWord stripped =? as soon as it matched, but if the following text was not a complete encoded word (missing delimiters, malformed tokens, or ordinary text like URL query parameters), the stripped =? was dropped from the output. Additionally, decodeRFC2047 dropped delimiters on unrecognized encodings (such as neither B nor Q), violating RFC 2047 section 6.1 which requires unencoded or unrecognized words to be emitted verbatim. Furthermore, whitespace between adjacent words was collapsed even when one of the words was displayed verbatim, and decoding errors in Base64 or Q-encoding produced empty/corrupted strings instead of verbatim words.

checks

  • built Net-testrunner with GCC 13.3 on Linux.
  • MessageHeaderTest passes (all 31 test cases pass).
  • MessagesTestSuite passes (all 50 test cases pass).
  • HTTPTestSuite passes (all 80 test cases pass).
  • HTTPClientTestSuite passes (all 81 test cases pass).
  • HTTPServerTestSuite passes (all 35 test cases pass).
  • HTMLTestSuite passes (all 15 test cases pass).

@aouxwoux
aouxwoux force-pushed the 5564-decode-word-delimiters branch from 84e9a99 to 3449cbb Compare October 24, 2026 23:56
@aleks-f
aleks-f requested a balanced review from Copilot October 24, 2026 23:59

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.

🟡 Changes recommended

Incomplete Base64 and encoded-word validation still allows malformed header values to be altered or deleted.

2 open issues
What changed in this PR

This PR addresses #5564 by preserving non-encoded and malformed header text during POCO’s RFC 2047 decoding, including automatic decoding in MessageHeader::read().

Changes:

  • Adds encoded-word parsing and preserves delimiters when decoding fails.
  • Limits whitespace removal to successfully decoded adjacent words.
  • Adds regression tests for malformed inputs, delimiter preservation and header deserialization.
File Description
Net/​testsuite/​src/​MessageHeaderTest.cpp Adds decoding and header-reading regression cases.
Net/​src/​MessageHeader.cpp Adds validation and verbatim fallback; revises adjacent-word whitespace handling.

Review effort: Balanced

Comment thread Net/src/MessageHeader.cpp Outdated
Comment thread Net/src/MessageHeader.cpp
@aouxwoux
aouxwoux force-pushed the 5564-decode-word-delimiters branch from e6562bd to 8adad33 Compare October 25, 2026 13:43
@aleks-f
aleks-f requested a balanced review from Copilot October 26, 2026 02:17

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.

🔵 Needs a closer look

Repeated malformed encoded-word prefixes cause quadratic scanning during automatic header decoding.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Medium severity Avoid quadratic scans for incomplete encoded-word prefixes

Net/​src/​MessageHeader.cpp:136

Repeated incomplete prefixes such as =?UTF-8?Q?abc make this search scan the remaining suffix for every retry in decodeWord(), causing quadratic work in automatically decoded header values. Search for the next ? and reject the candidate unless it is followed by =; encoded-text cannot contain ?, so scanning beyond it is unnecessary.

2 resolved since last review

Review effort: Balanced

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.

Net: MessageHeader::decodeWord() drops the =? of text that is not a complete encoded word

2 participants