Skip to content

Commit e844cda

Browse files
committed
don't segfault when \N escapes are used and unicodedata fails to load
Fixes #4367
1 parent 9bfb37e commit e844cda

3 files changed

Lines changed: 30 additions & 3 deletions

File tree

Lib/test/test_unicodedata.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@
44
55
(c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
66
7-
"""#"
8-
import unittest, test.test_support
7+
"""
8+
9+
import sys
10+
import unittest
911
import hashlib
12+
import subprocess
13+
import test.test_support
1014

1115
encoding = 'utf-8'
1216

@@ -196,6 +200,25 @@ def test_east_asian_width(self):
196200

197201
class UnicodeMiscTest(UnicodeDatabaseTest):
198202

203+
def test_failed_import_during_compiling(self):
204+
# Issue 4367
205+
# Decoding \N escapes requires the unicodedata module. If it can't be
206+
# imported, we shouldn't segfault.
207+
208+
# This program should raise a SyntaxError in the eval.
209+
code = "import sys;" \
210+
"sys.modules['unicodedata'] = None;" \
211+
"""eval("u'\N{SOFT HYPHEN}'")"""
212+
args = [sys.executable, "-c", code]
213+
# We use a subprocess because the unicodedata module may already have
214+
# been loaded in this process.
215+
popen = subprocess.Popen(args, stderr=subprocess.PIPE)
216+
popen.wait()
217+
self.assertEqual(popen.returncode, 1)
218+
error = "SyntaxError: (unicode error) \N escapes not supported " \
219+
"(can't load unicodedata module)"
220+
self.assertTrue(error in popen.stderr.read())
221+
199222
def test_decimal_numeric_consistent(self):
200223
# Test that decimal and numeric are consistent,
201224
# i.e. if a character has a decimal value,

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 1
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #4367: Python would segfault during compiling when the unicodedata
16+
module couldn't be imported and \N escapes were present.
17+
1518
- Issue #4233: Changed semantic of ``_fileio.FileIO``'s ``close()``
1619
method on file objects with closefd=False. The file descriptor is still
1720
kept open but the file object behaves like a closed file. The ``FileIO``

Python/ast.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1294,13 +1294,14 @@ ast_for_atom(struct compiling *c, const node *n)
12941294
if (PyErr_ExceptionMatches(PyExc_UnicodeError)){
12951295
PyObject *type, *value, *tback, *errstr;
12961296
PyErr_Fetch(&type, &value, &tback);
1297-
errstr = ((PyUnicodeErrorObject *)value)->reason;
1297+
errstr = PyObject_Str(value);
12981298
if (errstr) {
12991299
char *s = "";
13001300
char buf[128];
13011301
s = PyString_AsString(errstr);
13021302
PyOS_snprintf(buf, sizeof(buf), "(unicode error) %s", s);
13031303
ast_error(n, buf);
1304+
Py_DECREF(errstr);
13041305
} else {
13051306
ast_error(n, "(unicode error) unknown error");
13061307
}

0 commit comments

Comments
 (0)