From 376d1c8f738136a7e21a192580be1024e1dbf81c Mon Sep 17 00:00:00 2001 From: Harish Date: Fri, 9 Jan 2026 13:40:57 +0530 Subject: [PATCH] Fix: Correct Content-Length for StringIO with multi-byte characters --- src/requests/utils.py | 5 +++++ tests/test_utils.py | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/requests/utils.py b/src/requests/utils.py index 8ab55852cc..b63468c981 100644 --- a/src/requests/utils.py +++ b/src/requests/utils.py @@ -142,6 +142,11 @@ def super_len(o): # of latin-1 (iso-8859-1) like http.client. o = o.encode("utf-8") + if isinstance(o, io.StringIO): + total_length = len(o.getvalue().encode("utf-8")) + current_position = len(o.getvalue()[: o.tell()].encode("utf-8")) + return max(0, total_length - current_position) + if hasattr(o, "__len__"): total_length = len(o) diff --git a/tests/test_utils.py b/tests/test_utils.py index f9a287af1b..40f75f923e 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -142,6 +142,18 @@ def test_super_len_with_tell(self): foo.read(2) assert super_len(foo) == 3 + def test_super_len_stringio_multibyte(self): + # UTF-8: "👍" is 4 bytes + data = "👍" + s = StringIO.StringIO(data) + assert super_len(s) == 4 + + # Test partial read + data_mixed = "abc👍" + s = StringIO.StringIO(data_mixed) + s.read(3) + assert super_len(s) == 4 + def test_super_len_with_fileno(self): with open(__file__, "rb") as f: length = super_len(f)