10000 bpo-31592: Fix an assertion failure in Python parser in case of a bad… · python/cpython@7dc46d8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7dc46d8

Browse files
orenmnserhiy-storchaka
authored andcommitted
bpo-31592: Fix an assertion failure in Python parser in case of a bad unicodedata.normalize(). (#3767)
1 parent f4ea642 commit 7dc46d8

File tree

3 files changed

+28
-12
lines changed

3 files changed

+28
-12
lines changed

Lib/test/test_ast.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,16 @@ def test_empty_yield_from(self):
431431
compile(empty_yield_from, "<test>", "exec")
432432
self.assertIn("field value is required", str(cm.exception))
433433

434+
@support.cpython_only
435+
def test_issue31592(self):
436+
# There shouldn't be an assertion failure in case of a bad
437+
# unicodedata.normalize().
438+
import unicodedata
439+
def bad_normalize(*args):
440+
return None
441+
with support.swap_attr(unicodedata, 'normalize', bad_normalize):
442+
self.assertRaises(TypeError, ast.parse, '\u03D5')
443+
434444

435445
class ASTHelpers_Test(unittest.TestCase):
436446

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed an assertion failure in Python parser in case of a bad `unicodedata.normalize()`.
2+
Patch by Oren Milman.

Python/ast.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,6 @@ struct compiling {
594594
PyArena *c_arena; /* Arena for allocating memory. */
595595
PyObject *c_filename; /* filename */
596596
PyObject *c_normalize; /* Normalization function from unicodedata. */
597-
PyObject *c_normalize_args; /* Normalization argument tuple. */
598597
};
599598

600599
static asdl_seq *seq_for_testlist(struct compiling *, const node *);
@@ -631,12 +630,6 @@ init_normalization(struct compiling *c)
631630
Py_DECREF(m);
632631
if (!c->c_normalize)
633632
return 0;
634-
c->c_normalize_args = Py_BuildValue("(sN)", "NFKC", Py_None);
635-
if (!c->c_normalize_args) {
636-
Py_CLEAR(c->c_normalize);
637-
return 0;
638-
}
639-
PyTuple_SET_ITEM(c->c_normalize_args, 1, NULL);
640633
return 1;
641634
}
642635

@@ -652,15 +645,29 @@ new_identifier(const char *n, struct compiling *c)
652645
identifier; if so, normalize to NFKC. */
653646
if (!PyUnicode_IS_ASCII(id)) {
654647
PyObject *id2;
648+
_Py_IDENTIFIER(NFKC);
655649
if (!c->c_normalize && !init_normalization(c)) {
656650
Py_DECREF(id);
657651
return NULL;
658652
}
659-
PyTuple_SET_ITEM(c->c_normalize_args, 1, id);
660-
id2 = PyObject_Call(c->c_normalize, c->c_normalize_args, NULL);
653+
PyObject *form = _PyUnicode_FromId(&PyId_NFKC);
654+
if (form == NULL) {
655+
Py_DECREF(id);
656+
return NULL;
657+
}
658+
PyObject *args[2] = {form, id};
659+
id2 = _PyObject_FastCall(c->c_normalize, args, 2);
661660
Py_DECREF(id);
662661
if (!id2)
663662
return NULL;
663+
if (!PyUnicode_Check(id2)) {
664+
PyErr_Format(PyExc_TypeError,
665+
"unicodedata.normalize() must return a string, not "
666+
"%.200s",
667+
Py_TYPE(id2)->tp_name);
668+
Py_DECREF(id2);
669+
return NULL;
670+
}
664671
id = id2;
665672
}
666673
PyUnicode_InternInPlace(&id);
@@ -779,7 +786,6 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
779786
/* borrowed reference */
780787
c.c_filename = filename;
781788
c.c_normalize = NULL;
782-
c.c_normalize_args = NULL;
783789

784790
if (TYPE(n) == encoding_decl)
785791
n = CHILD(n, 0);
@@ -872,8 +878,6 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
872878
out:
873879
if (c.c_normalize) {
874880
Py_DECREF(c.c_normalize);
875-
PyTuple_SET_ITEM(c.c_normalize_args, 1, NULL);
876-
Py_DECREF(c.c_normalize_args);
877881
}
878882
return res;
879883
}

0 commit comments

Comments
 (0)
0