Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e239d23

Browse files
committed
Issue #6697: Fixed instances of _PyUnicode_AsString() result not checked for NULL
1 parent 1b2bd3b commit e239d23

13 files changed

Lines changed: 145 additions & 79 deletions

Lib/test/datetimetester.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2508,11 +2508,17 @@ def test_zones(self):
25082508

25092509
# Check that an invalid tzname result raises an exception.
25102510
class Badtzname(tzinfo):
2511-
def tzname(self, dt): return 42
2511+
tz = 42
2512+
def tzname(self, dt): return self.tz
25122513
t = time(2, 3, 4, tzinfo=Badtzname())
25132514
self.assertEqual(t.strftime("%H:%M:%S"), "02:03:04")
25142515
self.assertRaises(TypeError, t.strftime, "%Z")
25152516

2517+
# Issue #6697:
2518+
if '_Fast' in str(type(self)):
2519+
Badtzname.tz = '\ud800'
2520+
self.assertRaises(ValueError, t.strftime, "%Z")
2521+
25162522
def test_hash_edge_cases(self):
25172523
# Offsets that overflow a basic time.
25182524
t1 = self.theclass(0, 1, 2, 3, tzinfo=FixedOffset(1439, ""))

Lib/test/test_pyexpat.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ def test_unicode(self):
203203

204204
operations = out.out
205205
self._verify_parse_output(operations)
206+
# Issue #6697.
207+
self.assertRaises(AttributeError, getattr, parser, '\uD800')
206208

207209
def test_parse_file(self):
208210
# Try parsing a file

Lib/test/test_socket.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,8 @@ def testGetaddrinfo(self):
667667
type=socket.SOCK_STREAM, proto=0,
668668
flags=socket.AI_PASSIVE)
669669
self.assertEqual(a, b)
670+
# Issue #6697.
671+
self.assertRaises(UnicodeEncodeError, socket.getaddrinfo, 'localhost', '\uD800')
670672

671673
def test_getnameinfo(self):
672674
# only IP addresses are allowed

Lib/test/test_syslog.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class Test(unittest.TestCase):
1111

1212
def test_openlog(self):
1313
syslog.openlog('python')
14+
# Issue #6697.
15+
self.assertRaises(UnicodeEncodeError, syslog.openlog, '\uD800')
1416

1517
def test_syslog(self):
1618
syslog.openlog('python')

Lib/test/test_xml_etree_c.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,26 @@
88
# cElementTree specific tests
99

1010
def sanity():
11-
"""
11+
r"""
1212
Import sanity.
1313
1414
>>> from xml.etree import cElementTree
15+
16+
Issue #6697.
17+
18+
>>> e = cElementTree.Element('a')
19+
>>> getattr(e, '\uD800') # doctest: +ELLIPSIS
20+
Traceback (most recent call last):
21+
...
22+
UnicodeEncodeError: ...
23+
24+
>>> p = cElementTree.XMLParser()
25+
>>> p.version.split()[0]
26+
'Expat'
27+
>>> getattr(p, '\uD800')
28+
Traceback (most recent call last):
29+
...
30+
AttributeError: 'XMLParser' object has no attribute '\ud800'
1531
"""
1632

1733

Modules/_datetimemodule.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,8 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
12571257
assert(PyUnicode_Check(Zreplacement));
12581258
ptoappend = _PyUnicode_AsStringAndSize(Zreplacement,
12591259
&ntoappend);
1260-
ntoappend = Py_SIZE(Zreplacement);
1260+
if (ptoappend == NULL)
1261+
goto Done;
12611262
}
12621263
else if (ch == 'f') {
12631264
/* format microseconds */

Modules/_elementtree.c

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,9 @@ element_getattro(ElementObject* self, PyObject* nameobj)
14831483

14841484
if (PyUnicode_Check(nameobj))
14851485
name = _PyUnicode_AsString(nameobj);
1486+
1487+
if (name == NULL)
1488+
return NULL;
14861489

14871490
/* handle common attributes first */
14881491
if (strcmp(name, "tag") == 0) {
@@ -2139,7 +2142,7 @@ expat_set_error(const char* message, int line, int column)
21392142
PyObject *position;
21402143
char buffer[256];
21412144

2142-
sprintf(buffer, "%s: line %d, column %d", message, line, column);
2145+
sprintf(buffer, "%.100s: line %d, column %d", message, line, column);
21432146

21442147
error = PyObject_CallFunction(elementtree_parseerror_obj, "s", buffer);
21452148
if (!error)
@@ -2194,8 +2197,8 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
21942197
Py_XDECREF(res);
21952198
} else if (!PyErr_Occurred()) {
21962199
/* Report the first error, not the last */
2197-
char message[128];
2198-
sprintf(message, "undefined entity &%.100s;", _PyUnicode_AsString(key));
2200+
char message[128] = "undefined entity ";
2201+
strncat(message, data_in, data_len < 100?data_len:100);
21992202
expat_set_error(
22002203
message,
22012204
EXPAT(GetErrorLineNumber)(self->parser),
@@ -2796,29 +2799,25 @@ static PyMethodDef xmlparser_methods[] = {
27962799
static PyObject*
27972800
xmlparser_getattro(XMLParserObject* self, PyObject* nameobj)
27982801
{
2799-
PyObject* res;
2800-
char *name = "";
2801-
2802-
if (PyUnicode_Check(nameobj))
2803-
name = _PyUnicode_AsString(nameobj);
2804-
2805-
PyErr_Clear();
2806-
2807-
if (strcmp(name, "entity") == 0)
2808-
res = self->entity;
2809-
else if (strcmp(name, "target") == 0)
2810-
res = self->target;
2811-
else if (strcmp(name, "version") == 0) {
2812-
char buffer[100];
2813-
sprintf(buffer, "Expat %d.%d.%d", XML_MAJOR_VERSION,
2802+
if (PyUnicode_Check(nameobj)) {
2803+
PyObject* res;
2804+
if (PyUnicode_CompareWithASCIIString(nameobj, "entity") == 0)
2805+
res = self->entity;
2806+
else if (PyUnicode_CompareWithASCIIString(nameobj, "target") == 0)
2807+
res = self->target;
2808+
else if (PyUnicode_CompareWithASCIIString(nameobj, "version") == 0) {
2809+
return PyUnicode_FromFormat(
2810+
"Expat %d.%d.%d", XML_MAJOR_VERSION,
28142811
XML_MINOR_VERSION, XML_MICRO_VERSION);
2815-
return PyUnicode_DecodeUTF8(buffer, strlen(buffer), "strict");
2816-
} else {
2817-
return PyObject_GenericGetAttr((PyObject*) self, nameobj);
2818-
}
2812+
}
2813+
else
2814+
goto generic;
28192815

2820-
Py_INCREF(res);
2821-
return res;
2816+
Py_INCREF(res);
2817+
return res;
2818+
}
2819+
generic:
2820+
return PyObject_GenericGetAttr((PyObject*) self, nameobj);
28222821
}
28232822

28242823
static PyTypeObject XMLParser_Type = {

Modules/_lsprof.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,16 @@ normalizeUserObj(PyObject *obj)
178178
PyObject *mod = fn->m_module;
179179
const char *modname;
180180
if (mod && PyUnicode_Check(mod)) {
181+
/* XXX: The following will truncate module names with embedded
182+
* null-characters. It is unlikely that this can happen in
183+
* practice and the concequences are not serious enough to
184+
* introduce extra checks here.
185+
*/
181186
modname = _PyUnicode_AsString(mod);
187+
if (modname == NULL) {
188+
modname = "<encoding error>";
189+
PyErr_Clear();
190+
}
182191
}
183192
else if (mod && PyModule_Check(mod)) {
184193
modname = PyModule_GetName(mod);

Modules/_testcapimodule.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,15 +1741,16 @@ test_string_from_format(PyObject *self, PyObject *args)
17411741
{
17421742
PyObject *result;
17431743
char *msg;
1744-
1745-
#define CHECK_1_FORMAT(FORMAT, TYPE) \
1746-
result = PyUnicode_FromFormat(FORMAT, (TYPE)1); \
1747-
if (result == NULL) \
1748-
return NULL; \
1749-
if (strcmp(_PyUnicode_AsString(result), "1")) { \
1750-
msg = FORMAT " failed at 1"; \
1751-
goto Fail; \
1752-
} \
1744+
static const Py_UNICODE one[] = {'1', 0};
1745+
1746+
#define CHECK_1_FORMAT(FORMAT, TYPE) \
1747+
result = PyUnicode_FromFormat(FORMAT, (TYPE)1); \
1748+
if (result == NULL) \
1749+
return NULL; \
1750+
if (Py_UNICODE_strcmp(PyUnicode_AS_UNICODE(result), one)) { \
1751+
msg = FORMAT " failed at 1"; \
1752+
goto Fail; \
1753+
} \
17531754
Py_DECREF(result)
17541755

17551756
CHECK_1_FORMAT("%d", int);

Modules/parsermodule.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,11 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
792792
}
793793
}
794794
temp_str = _PyUnicode_AsStringAndSize(temp, &len);
795+
if (temp_str == NULL) {
796+
Py_DECREF(temp);
797+
Py_XDECREF(elem);
798+
return 0;
799+
}
795800
strn = (char *)PyObject_MALLOC(len + 1);
796801
if (strn != NULL)
797802
(void) memcpy(strn, temp_str, len + 1);
@@ -870,6 +875,8 @@ build_node_tree(PyObject *tuple)
870875
encoding = PySequence_GetItem(tuple, 2);
871876
/* tuple isn't borrowed anymore here, need to DECREF */
872877
tuple = PySequence_GetSlice(tuple, 0, 2);
878+
if (tuple == NULL)
879+
return NULL;
873880
}
874881
res = PyNode_New(num);
875882
if (res != NULL) {
@@ -881,6 +888,12 @@ build_node_tree(PyObject *tuple)
881888
Py_ssize_t len;
882889
const char *temp;
883890
temp = _PyUnicode_AsStringAndSize(encoding, &len);
891+
if (temp == NULL) {
892+
Py_DECREF(res);
893+
Py_DECREF(encoding);
894+
Py_DECREF(tuple);
895+
return NULL;
896+
}
884897
res->n_str = (char *)PyObject_MALLOC(len + 1);
885898
if (res->n_str != NULL && temp != NULL)
886899
(void) memcpy(res->n_str, temp, len + 1);

0 commit comments

Comments
 (0)