mirror of https://github.com/python/cpython.git
Issue #9425: zipimporter_init() is fully unicode compliant
This commit is contained in:
parent
4f4402c4bb
commit
2b8dab7050
|
@ -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)
|
||||||
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)
|
||||||
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. */
|
||||||
|
|
Loading…
Reference in New Issue