summaryrefslogtreecommitdiffstats
path: root/Modules/zipimport.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@haypocalc.com>2010-08-14 14:54:10 (GMT)
committerVictor Stinner <victor.stinner@haypocalc.com>2010-08-14 14:54:10 (GMT)
commit2b8dab7050fa678de448260bf3670029afe0dc56 (patch)
tree5715fe687856393ba5c432d1c948118c3b8321b0 /Modules/zipimport.c
parent4f4402c4bb780a89c1d1c2564522e8ca901cbe17 (diff)
downloadcpython-2b8dab7050fa678de448260bf3670029afe0dc56.zip
cpython-2b8dab7050fa678de448260bf3670029afe0dc56.tar.gz
cpython-2b8dab7050fa678de448260bf3670029afe0dc56.tar.bz2
Issue #9425: zipimporter_init() is fully unicode compliant
Diffstat (limited to 'Modules/zipimport.c')
-rw-r--r--Modules/zipimport.c90
1 files changed, 53 insertions, 37 deletions
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
index 8d04f17..519d575 100644
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -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. */