Commit 2b8dab70 authored by Victor Stinner's avatar Victor Stinner

Issue #9425: zipimporter_init() is fully unicode compliant

parent 4f4402c4
...@@ -60,26 +60,29 @@ static PyObject *get_module_code(ZipImporter *self, char *fullname, ...@@ -60,26 +60,29 @@ static PyObject *get_module_code(ZipImporter *self, char *fullname,
static int static int
zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds) zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
{ {
char *path, *p, *prefix, buf[MAXPATHLEN+2]; PyObject *pathobj, *path_bytes, *files;
size_t len; Py_UNICODE *path, *p, *prefix, buf[MAXPATHLEN+2];
Py_ssize_t len;
if (!_PyArg_NoKeywords("zipimporter()", kwds)) if (!_PyArg_NoKeywords("zipimporter()", kwds))
return -1; return -1;
if (!PyArg_ParseTuple(args, "s:zipimporter", &path)) if (!PyArg_ParseTuple(args, "O&:zipimporter",
PyUnicode_FSDecoder, &pathobj))
return -1; return -1;
len = strlen(path); /* copy path to buf */
len = PyUnicode_GET_SIZE(pathobj);
if (len == 0) { if (len == 0) {
PyErr_SetString(ZipImportError, "archive path is empty"); PyErr_SetString(ZipImportError, "archive path is empty");
return -1; goto error;
} }
if (len >= MAXPATHLEN) { if (len >= MAXPATHLEN) {
PyErr_SetString(ZipImportError, PyErr_SetString(ZipImportError,
"archive path too long"); "archive path too long");
return -1; goto error;
} }
strcpy(buf, path); Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(pathobj));
#ifdef ALTSEP #ifdef ALTSEP
for (p = buf; *p; p++) { for (p = buf; *p; p++) {
...@@ -94,7 +97,12 @@ zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds) ...@@ -94,7 +97,12 @@ zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
struct stat statbuf; struct stat statbuf;
int rv; int rv;
rv = stat(buf, &statbuf); if (pathobj == NULL) {
pathobj = PyUnicode_FromUnicode(buf, len);
if (pathobj == NULL)
goto error;
}
rv = _Py_stat(pathobj, &statbuf);
if (rv == 0) { if (rv == 0) {
/* it exists */ /* it exists */
if (S_ISREG(statbuf.st_mode)) if (S_ISREG(statbuf.st_mode))
...@@ -102,56 +110,64 @@ zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds) ...@@ -102,56 +110,64 @@ zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
path = buf; path = buf;
break; break;
} }
else if (PyErr_Occurred())
goto error;
/* back up one path element */ /* back up one path element */
p = strrchr(buf, SEP); p = Py_UNICODE_strrchr(buf, SEP);
if (prefix != NULL) if (prefix != NULL)
*prefix = SEP; *prefix = SEP;
if (p == NULL) if (p == NULL)
break; break;
*p = '\0'; *p = '\0';
len = p - buf;
prefix = p; prefix = p;
Py_CLEAR(pathobj);
} }
if (path != NULL) { if (path == NULL) {
PyObject *files; PyErr_SetString(ZipImportError, "not a Zip file");
files = PyDict_GetItemString(zip_directory_cache, path); goto error;
}
files = PyDict_GetItem(zip_directory_cache, pathobj);
if (files == NULL) { if (files == NULL) {
files = read_directory(buf); path_bytes = PyUnicode_EncodeFSDefault(pathobj);
if (path_bytes == NULL)
goto error;
files = read_directory(PyBytes_AS_STRING(path_bytes));
Py_DECREF(path_bytes);
if (files == NULL) if (files == NULL)
return -1; goto error;
if (PyDict_SetItemString(zip_directory_cache, path, if (PyDict_SetItem(zip_directory_cache, pathobj, files) != 0)
files) != 0) goto error;
return -1;
} }
else else
Py_INCREF(files); Py_INCREF(files);
self->files = files; self->files = files;
}
else {
PyErr_SetString(ZipImportError, "not a Zip file");
return -1;
}
if (prefix == NULL) self->archive = pathobj;
prefix = ""; pathobj = NULL;
else {
if (prefix != NULL) {
prefix++; prefix++;
len = strlen(prefix); len = Py_UNICODE_strlen(prefix);
if (prefix[len-1] != SEP) { if (prefix[len-1] != SEP) {
/* add trailing SEP */ /* add trailing SEP */
prefix[len] = SEP; prefix[len] = SEP;
prefix[len + 1] = '\0'; prefix[len + 1] = '\0';
len++;
} }
} }
else
self->archive = PyUnicode_FromString(buf); len = 0;
if (self->archive == NULL) self->prefix = PyUnicode_FromUnicode(prefix, len);
return -1;
self->prefix = PyUnicode_FromString(prefix);
if (self->prefix == NULL) if (self->prefix == NULL)
return -1; goto error;
return 0; return 0;
error:
Py_XDECREF(pathobj);
return -1;
} }
/* GC support. */ /* GC support. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment