Skip to content

Commit ea0e3b0

Browse files
committed
do a backport of r75928
The added test does not fail without the patch, but we still fix the issue of surrogates being used in wide builds where they should not be.
1 parent a7d4400 commit ea0e3b0

2 files changed

Lines changed: 19 additions & 9 deletions

File tree

Lib/test/test_pep263.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ def test_compilestring(self):
2323
self.assertEqual(d['u'], u'\xf3')
2424

2525

26+
def test_issue3297(self):
27+
c = compile("a, b = '\U0001010F', '\\U0001010F'", "dummy", "exec")
28+
d = {}
29+
exec(c, d)
30+
self.assertEqual(d['a'], d['b'])
31+
self.assertEqual(len(d['a']), len(d['b']))
32+
2633
def test_main():
2734
test_support.run_unittest(PEP263Test)
2835

Python/ast.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3289,10 +3289,11 @@ decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, cons
32893289
u = NULL;
32903290
} else {
32913291
/* check for integer overflow */
3292-
if (len > PY_SIZE_MAX / 4)
3292+
if (len > PY_SIZE_MAX / 6)
32933293
return NULL;
3294-
/* "\XX" may become "\u005c\uHHLL" (12 bytes) */
3295-
u = PyString_FromStringAndSize((char *)NULL, len * 4);
3294+
/* "<C3><A4>" (2 bytes) may become "\U000000E4" (10 bytes), or 1:5
3295+
"\ä" (3 bytes) may become "\u005c\U000000E4" (16 bytes), or ~1:6 */
3296+
u = PyString_FromStringAndSize((char *)NULL, len * 6);
32963297
if (u == NULL)
32973298
return NULL;
32983299
p = buf = PyString_AsString(u);
@@ -3309,19 +3310,21 @@ decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, cons
33093310
PyObject *w;
33103311
char *r;
33113312
Py_ssize_t rn, i;
3312-
w = decode_utf8(c, &s, end, "utf-16-be");
3313+
w = decode_utf8(c, &s, end, "utf-32-be");
33133314
if (w == NULL) {
33143315
Py_DECREF(u);
33153316
return NULL;
33163317
}
33173318
r = PyString_AsString(w);
33183319
rn = PyString_Size(w);
3319-
assert(rn % 2 == 0);
3320-
for (i = 0; i < rn; i += 2) {
3321-
sprintf(p, "\\u%02x%02x",
3320+
assert(rn % 4 == 0);
3321+
for (i = 0; i < rn; i += 4) {
3322+
sprintf(p, "\\U%02x%02x%02x%02x",
33223323
r[i + 0] & 0xFF,
3323-
r[i + 1] & 0xFF);
3324-
p += 6;
3324+
r[i + 1] & 0xFF,
3325+
r[i + 2] & 0xFF,
3326+
r[i + 3] & 0xFF);
3327+
p += 10;
33253328
}
33263329
Py_DECREF(w);
33273330
} else {

0 commit comments

Comments
 (0)