Issue #9425: zipimporter_init() is fully unicode compliant

This commit is contained in:
Victor Stinner 2010-08-14 14:54:10 +00:00
parent 4f4402c4bb
commit 2b8dab7050
1 changed files with 53 additions and 37 deletions

View File

@ -60,26 +60,29 @@ static PyObject *get_module_code(ZipImporter *self, char *fullname,
static int
zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
{
char *path, *p, *prefix, buf[MAXPATHLEN+2];
size_t len;
PyObject *pathobj, *path_bytes, *files;
Py_UNICODE *path, *p, *prefix, buf[MAXPATHLEN+2];
Py_ssize_t len;
if (!_PyArg_NoKeywords("zipimporter()", kwds))
return -1;
if (!PyArg_ParseTuple(args, "s:zipimporter", &path))
if (!PyArg_ParseTuple(args, "O&:zipimporter",
PyUnicode_FSDecoder, &pathobj))
return -1;
len = strlen(path);
/* copy path to buf */
len = PyUnicode_GET_SIZE(pathobj);
if (len == 0) {
PyErr_SetString(ZipImportError, "archive path is empty");
return -1;
goto error;
}
if (len >= MAXPATHLEN) {
PyErr_SetString(ZipImportError,
"archive path too long");
return -1;
goto error;
}
strcpy(buf, path);
Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(pathobj));
#ifdef ALTSEP
for (p = buf; *p; p++) {
@ -94,7 +97,12 @@ zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
struct stat statbuf;
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) {
/* it exists */
if (S_ISREG(statbuf.st_mode))
@ -102,56 +110,64 @@ zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
path = buf;
break;
}
else if (PyErr_Occurred())
goto error;
/* back up one path element */
p = strrchr(buf, SEP);
p = Py_UNICODE_strrchr(buf, SEP);
if (prefix != NULL)
*prefix = SEP;
if (p == NULL)
break;
*p = '\0';
len = p - buf;
prefix = p;
Py_CLEAR(pathobj);
}
if (path != NULL) {
PyObject *files;
files = PyDict_GetItemString(zip_directory_cache, path);
if (files == NULL) {
files = read_directory(buf);
if (files == NULL)
return -1;
if (PyDict_SetItemString(zip_directory_cache, path,
files) != 0)
return -1;
}
else
Py_INCREF(files);
self->files = files;
}
else {
if (path == NULL) {
PyErr_SetString(ZipImportError, "not a Zip file");
return -1;
goto error;
}
if (prefix == NULL)
prefix = "";
else {
files = PyDict_GetItem(zip_directory_cache, pathobj);
if (files == NULL) {
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)
goto error;
if (PyDict_SetItem(zip_directory_cache, pathobj, files) != 0)
goto error;
}
else
Py_INCREF(files);
self->files = files;
self->archive = pathobj;
pathobj = NULL;
if (prefix != NULL) {
prefix++;
len = strlen(prefix);
len = Py_UNICODE_strlen(prefix);
if (prefix[len-1] != SEP) {
/* add trailing SEP */
prefix[len] = SEP;
prefix[len + 1] = '\0';
len++;
}
}
self->archive = PyUnicode_FromString(buf);
if (self->archive == NULL)
return -1;
self->prefix = PyUnicode_FromString(prefix);
else
len = 0;
self->prefix = PyUnicode_FromUnicode(prefix, len);
if (self->prefix == NULL)
return -1;
goto error;
return 0;
error:
Py_XDECREF(pathobj);
return -1;
}
/* GC support. */