From a8fbfc73fae5334868ca8a4238952572c3863083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20C=C3=A9sar=20Su=C3=A1stegui?= Date: Sat, 25 Apr 2026 03:24:59 -0600 Subject: [PATCH] fix: avoid IndexError in is_mostly_bin for short tails (#8196) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: avoid IndexError in is_mostly_bin for short tails `is_mostly_bin` looks up to 4 bytes past the 100-byte cutoff to find a clean UTF-8 character boundary. when the input is just over 100 bytes and starts with a continuation byte at index 100, the lookahead reads past the end of the buffer. cap the loop end at `len(s)`. existing fallback to `s[:100]` still covers the case where every byte in the lookahead window is a continuation byte. fixes #8188 * [autofix.ci] apply automated fixes --------- Co-authored-by: Julio César Suástegui Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- CHANGELOG.md | 3 +++ mitmproxy/utils/strutils.py | 2 +- test/mitmproxy/utils/test_strutils.py | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 109f8e799..713ea6c21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ ## Unreleased: mitmproxy next +- Fix `IndexError` in `is_mostly_bin` when exporting flows to HAR with payloads + that have a UTF-8 continuation byte at the 100-byte cutoff. + ([#8196](https://github.com/mitmproxy/mitmproxy/pull/8196), @juliosuas) ## 12 April 2026: mitmproxy 12.2.2 diff --git a/mitmproxy/utils/strutils.py b/mitmproxy/utils/strutils.py index d7ab4a8e1..9c5cb7273 100644 --- a/mitmproxy/utils/strutils.py +++ b/mitmproxy/utils/strutils.py @@ -132,7 +132,7 @@ def is_mostly_bin(s: bytes) -> bool: # Cut off at ~100 chars, but do it smartly so that if the input is UTF-8, we don't # chop a multibyte code point in half. if len(s) > 100: - for cut in range(100, 104): + for cut in range(100, min(104, len(s))): is_continuation_byte = (s[cut] >> 6) == 0b10 if not is_continuation_byte: # A new character starts here, so we cut off just before that. diff --git a/test/mitmproxy/utils/test_strutils.py b/test/mitmproxy/utils/test_strutils.py index 644e4ea0a..0a3c9f95d 100644 --- a/test/mitmproxy/utils/test_strutils.py +++ b/test/mitmproxy/utils/test_strutils.py @@ -94,6 +94,11 @@ def test_is_mostly_bin(): assert not strutils.is_mostly_bin(b"aaaaa" + 50 * "𐍅".encode()) # only utf8 continuation chars assert strutils.is_mostly_bin(150 * b"\x80") + # regression #8188: payloads with len 101-103 and a continuation byte at + # the 100-byte cutoff used to raise IndexError because the lookahead loop + # ran past the end of the string. Should not raise. + for tail in (1, 2, 3): + strutils.is_mostly_bin(b"a" * 100 + b"\x80" * tail) def test_is_xml():