Treat carriage return as whitespace in strutils.is_xml (#8243)

* Treat carriage return as whitespace in strutils.is_xml

is_xml() skipped only tab, LF and space before checking for the
opening "<", so a response body that started with a leading CR
or CRLF (which is what HTTP frames look like, and what some
Windows-side XML producers emit) was not detected as XML.
The XML/HTML content view's auto-detection score then dropped
to 0 instead of the usual 0.4 for those bodies.

XML 1.0 §2.3 defines whitespace as (#x20 | #x9 | #xD | #xA), so
\r (0x0D) belongs in the skip set alongside the other three.
Adds the missing byte plus three assertions in the existing
test_is_xml: \r<foo and \r\n<foo are now recognised, and a
sanity check that \r\nfoo is still rejected.

* [autofix.ci] apply automated fixes

* simplify wording

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Hils <git@maximilianhils.com>
This commit is contained in:
Aditya Raj 2026-05-21 22:45:31 +05:30 committed by GitHub
parent 782af067f1
commit 12a292c2e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 10 additions and 1 deletions

View file

@ -7,6 +7,8 @@
## Unreleased: mitmproxy next
- Fix contentview detection for XML files that start with CRLF.
([#8243](https://github.com/mitmproxy/mitmproxy/pull/8243), @ADiTyaRaj8969)
- mitmweb: Fix the filter input losing half-typed text on unrelated parent re-renders.
([#8234](https://github.com/mitmproxy/mitmproxy/pull/8234), @ariel42)
- mitmweb: Fix an infinite update cycle in `FlowTable` by only recomputing the virtual-scroll window in `componentDidUpdate` when `flowView` or `rowHeight` actually change.

View file

@ -163,8 +163,10 @@ def is_mostly_bin(s: bytes) -> bool:
def is_xml(s: bytes) -> bool:
# XML 1.0 §2.3 defines whitespace as (#x20 | #x9 | #xD | #xA), so a
# leading \r before "<" should also be skipped here.
for char in s:
if char in (9, 10, 32): # is space?
if char in (9, 10, 13, 32): # is whitespace?
continue
return char == 60 # is a "<"?
return False

View file

@ -106,6 +106,11 @@ def test_is_xml():
assert not strutils.is_xml(b"foo")
assert strutils.is_xml(b"<foo")
assert strutils.is_xml(b" \n<foo")
# XML 1.0 §2.3 lists CR as whitespace, so bodies that arrive with
# CRLF (or a stray \r) before the root element must still be detected.
assert strutils.is_xml(b"\r<foo")
assert strutils.is_xml(b"\r\n<foo")
assert not strutils.is_xml(b"\r\nfoo")
def test_clean_hanging_newline():