From a85998af7c44c047cb4e35cfa8373330e3f45088 Mon Sep 17 00:00:00 2001 From: Alexandre Vassalotti Date: Sat, 3 May 2008 18:24:43 +0000 Subject: Issue #1950: Fixed misusage of PyUnicode_AsString(). --- Modules/datetimemodule.c | 3 +-- Modules/parsermodule.c | 14 ++++++-------- Modules/zipimport.c | 15 +++++++-------- Objects/typeobject.c | 21 ++++++++++++++------- Python/import.c | 13 +++++++++---- Python/structmember.c | 15 +++++++++++---- 6 files changed, 48 insertions(+), 33 deletions(-) diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c index 711adba..e64b230 100644 --- a/Modules/datetimemodule.c +++ b/Modules/datetimemodule.c @@ -1217,10 +1217,9 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, assert(object && format && timetuple); assert(PyUnicode_Check(format)); /* Convert the input format to a C string and size */ - pin = PyUnicode_AsString(format); + pin = PyUnicode_AsStringAndSize(format, &flen); if (!pin) return NULL; - flen = PyUnicode_GetSize(format); /* Give up if the year is before 1900. * Python strftime() plays games with the year, and different diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 9cc1227..497d4e6 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -717,11 +717,10 @@ build_node_children(PyObject *tuple, node *root, int *line_num) Py_DECREF(o); } } - temp_str = PyUnicode_AsString(temp); - len = PyUnicode_GET_SIZE(temp) + 1; - strn = (char *)PyObject_MALLOC(len); + temp_str = PyUnicode_AsStringAndSize(temp, &len); + strn = (char *)PyObject_MALLOC(len + 1); if (strn != NULL) - (void) memcpy(strn, temp_str, len); + (void) memcpy(strn, temp_str, len + 1); Py_DECREF(temp); } else if (!ISNONTERMINAL(type)) { @@ -807,11 +806,10 @@ build_node_tree(PyObject *tuple) if (res && encoding) { Py_ssize_t len; const char *temp; - temp = PyUnicode_AsString(encoding); - len = PyUnicode_GET_SIZE(encoding) + 1; - res->n_str = (char *)PyObject_MALLOC(len); + temp = PyUnicode_AsStringAndSize(encoding, &len); + res->n_str = (char *)PyObject_MALLOC(len + 1); if (res->n_str != NULL && temp != NULL) - (void) memcpy(res->n_str, temp, len); + (void) memcpy(res->n_str, temp, len + 1); Py_DECREF(encoding); Py_DECREF(tuple); } diff --git a/Modules/zipimport.c b/Modules/zipimport.c index cd56be3..3b8eb93 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -61,16 +61,14 @@ static int zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds) { char *path, *p, *prefix, buf[MAXPATHLEN+2]; - size_t len; + Py_ssize_t len; if (!_PyArg_NoKeywords("zipimporter()", kwds)) return -1; - if (!PyArg_ParseTuple(args, "s:zipimporter", - &path)) + if (!PyArg_ParseTuple(args, "s#:zipimporter", &path, &len)) return -1; - len = strlen(path); if (len == 0) { PyErr_SetString(ZipImportError, "archive path is empty"); return -1; @@ -329,7 +327,7 @@ zipimporter_load_module(PyObject *obj, PyObject *args) fullpath = PyUnicode_FromFormat("%s%c%s%s", PyUnicode_AsString(self->archive), SEP, - *prefix ? prefix : "", + prefix ? prefix : "", subname); if (fullpath == NULL) goto error; @@ -388,6 +386,7 @@ zipimporter_get_data(PyObject *obj, PyObject *args) #endif PyObject *toc_entry; Py_ssize_t len; + char *archive_str; if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path)) return NULL; @@ -404,9 +403,9 @@ zipimporter_get_data(PyObject *obj, PyObject *args) } path = buf; #endif - len = PyUnicode_GET_SIZE(self->archive); + archive_str = PyUnicode_AsStringAndSize(self->archive, &len); if ((size_t)len < strlen(path) && - strncmp(path, PyUnicode_AsString(self->archive), len) == 0 && + strncmp(path, archive_str, len) == 0 && path[len] == SEP) { path = path + len + 1; } @@ -416,7 +415,7 @@ zipimporter_get_data(PyObject *obj, PyObject *args) PyErr_SetFromErrnoWithFilename(PyExc_IOError, path); return NULL; } - return get_data(PyUnicode_AsString(self->archive), toc_entry); + return get_data(archive_str, toc_entry); } static PyObject * diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e2e365e..2d12a8b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1255,7 +1255,7 @@ check_duplicates(PyObject *list) if (PyList_GET_ITEM(list, j) == o) { o = class_name(o); PyErr_Format(PyExc_TypeError, - "duplicate base class %s", + "duplicate base class %.400s", o ? PyUnicode_AsString(o) : "?"); Py_XDECREF(o); return -1; @@ -2133,20 +2133,27 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) { PyObject *doc = PyDict_GetItemString(dict, "__doc__"); if (doc != NULL && PyUnicode_Check(doc)) { - size_t n; + Py_ssize_t len; + char *doc_str; char *tp_doc; - const char *str = PyUnicode_AsString(doc); - if (str == NULL) { + + doc_str = PyUnicode_AsStringAndSize(doc, &len); + if (doc_str == NULL) { + Py_DECREF(type); + return NULL; + } + if ((Py_ssize_t)strlen(doc_str) != len) { + PyErr_SetString(PyExc_TypeError, + "__doc__ contains null-bytes"); Py_DECREF(type); return NULL; } - n = strlen(str); - tp_doc = (char *)PyObject_MALLOC(n+1); + tp_doc = (char *)PyObject_MALLOC(len + 1); if (tp_doc == NULL) { Py_DECREF(type); return NULL; } - memcpy(tp_doc, str, n+1); + memcpy(tp_doc, doc_str, len + 1); type->tp_doc = tp_doc; } } diff --git a/Python/import.c b/Python/import.c index 8b11aad..5dabd9f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2131,13 +2131,15 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level) if ((pkgname != NULL) && (pkgname != Py_None)) { /* __package__ is set, so use it */ + char *pkgname_str; Py_ssize_t len; + if (!PyUnicode_Check(pkgname)) { PyErr_SetString(PyExc_ValueError, "__package__ set to non-string"); return NULL; } - len = PyUnicode_GET_SIZE(pkgname); + pkgname_str = PyUnicode_AsStringAndSize(pkgname, &len); if (len == 0) { if (level > 0) { PyErr_SetString(PyExc_ValueError, @@ -2151,7 +2153,7 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level) "Package name too long"); return NULL; } - strcpy(buf, PyUnicode_AsString(pkgname)); + strcpy(buf, pkgname_str); } else { /* __package__ not set, so figure it out and set it */ modname = PyDict_GetItem(globals, namestr); @@ -2161,14 +2163,17 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level) modpath = PyDict_GetItem(globals, pathstr); if (modpath != NULL) { /* __path__ is set, so modname is already the package name */ - Py_ssize_t len = PyUnicode_GET_SIZE(modname); + char *modname_str; + Py_ssize_t len; int error; + + modname_str = PyUnicode_AsStringAndSize(modname, &len); if (len > MAXPATHLEN) { PyErr_SetString(PyExc_ValueError, "Module name too long"); return NULL; } - strcpy(buf, PyUnicode_AsString(modname)); + strcpy(buf, modname_str); error = PyDict_SetItem(globals, pkgstr, modname); if (error) { PyErr_SetString(PyExc_ValueError, diff --git a/Python/structmember.c b/Python/structmember.c index 769acfc..6c1e932 100644 --- a/Python/structmember.c +++ b/Python/structmember.c @@ -239,15 +239,22 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) *(PyObject **)addr = v; Py_XDECREF(oldv); break; - case T_CHAR: - if (PyUnicode_Check(v) && PyUnicode_GetSize(v) == 1) { - *(char*)addr = PyUnicode_AsString(v)[0]; + case T_CHAR: { + char *string; + Py_ssize_t len; + + if (!PyUnicode_Check(v)) { + PyErr_BadArgument(); + return -1; } - else { + string = PyUnicode_AsStringAndSize(v, &len); + if (len != 1) { PyErr_BadArgument(); return -1; } + *(char*)addr = string[0]; break; + } #ifdef HAVE_LONG_LONG case T_LONGLONG:{ PY_LONG_LONG value; -- cgit v0.12