Skip to content

Commit faa0dce

Browse files
committed
Fix StringIO Content-Length calculation for multi-byte chars
Correctly calculate Content-Length for io.StringIO objects containing multi-byte characters by measuring the UTF-8 encoded byte length. Added test case with emoji character to verify the fix. Fixes: psf#6917
1 parent 1764cc9 commit faa0dce

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

Diff for: src/requests/utils.py

+12
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,18 @@ def super_len(o):
195195
# seek back to current position to support
196196
# partially read file-like objects
197197
o.seek(current_position or 0)
198+
199+
# Handle StringIO with multi-byte characters by correctly measuring UTF-8 byte length
200+
if isinstance(o, io.StringIO):
201+
# Save current position
202+
current_pos = o.tell()
203+
# Get entire content and calculate byte length after UTF-8 encoding
204+
o.seek(0)
205+
content = o.read()
206+
# Restore original position
207+
o.seek(current_pos)
208+
# Set total_length to the byte length, not character count
209+
total_length = len(content.encode("utf-8"))
198210
except OSError:
199211
total_length = 0
200212

Diff for: tests/test_utils.py

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import copy
22
import filecmp
3+
import io
34
import os
45
import tarfile
56
import zipfile
@@ -151,6 +152,13 @@ def test_super_len_with_no_matches(self):
151152
"""Ensure that objects without any length methods default to 0"""
152153
assert super_len(object()) == 0
153154

155+
def test_super_len_with_stringio_containing_multibyte_chars(self):
156+
"""Ensure StringIO with multi-byte characters reports correct byte length"""
157+
# emoji takes 4 bytes in UTF-8 but is 1 character
158+
s = io.StringIO("💩")
159+
# Super len should return 4 (byte length) not 1 (character length)
160+
assert super_len(s) == 4
161+
154162

155163
class TestToKeyValList:
156164
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)