Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit e800941

Browse files
Issue python#25709: Fixed problem with in-place string concatenation and utf-8 cache.
1 parent a8f4405 commit e800941

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

Lib/test/test_unicode.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,6 +2699,23 @@ def test_compare(self):
26992699
self.assertTrue(astral >= bmp2)
27002700
self.assertFalse(astral >= astral2)
27012701

2702+
@support.cpython_only
2703+
def test_pep393_utf8_caching_bug(self):
2704+
# Issue #25709: Problem with string concatenation and utf-8 cache
2705+
from _testcapi import getargs_s_hash
2706+
for k in 0x24, 0xa4, 0x20ac, 0x1f40d:
2707+
s = ''
2708+
for i in range(5):
2709+
# Due to CPython specific optimization the 's' string can be
2710+
# resized in-place.
2711+
s += chr(k)
2712+
# Parsing with the "s#" format code calls indirectly
2713+
# PyUnicode_AsUTF8AndSize() which creates the UTF-8
2714+
# encoded string cached in the Unicode object.
2715+
self.assertEqual(getargs_s_hash(s), chr(k).encode() * (i + 1))
2716+
# Check that the second call returns the same result
2717+
self.assertEqual(getargs_s_hash(s), chr(k).encode() * (i + 1))
2718+
27022719

27032720
class StringModuleTest(unittest.TestCase):
27042721
def test_formatter_parser(self):

Misc/NEWS

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@ Release date: 2015-12-06
1010
Core and Builtins
1111
-----------------
1212

13-
Library
13+
- Issue #25709: Fixed problem with in-place string concatenation and utf-8 cache.
14+
15+
Windows
1416
-------
1517

18+
- Issue #25715: Python 3.5.1 installer shows wrong upgrade path and incorrect
19+
logic for launcher detection.
20+
1621

1722
What's New in Python 3.5.1 release candidate 1?
1823
===============================================

Objects/unicodeobject.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,11 @@ resize_compact(PyObject *unicode, Py_ssize_t length)
722722
}
723723
new_size = (struct_size + (length + 1) * char_size);
724724

725+
if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) {
726+
PyObject_DEL(_PyUnicode_UTF8(unicode));
727+
_PyUnicode_UTF8(unicode) = NULL;
728+
_PyUnicode_UTF8_LENGTH(unicode) = 0;
729+
}
725730
_Py_DEC_REFTOTAL;
726731
_Py_ForgetReference(unicode);
727732

0 commit comments

Comments
 (0)