Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2b8dab7

Browse files
author
Victor Stinner
committed
Issue #9425: zipimporter_init() is fully unicode compliant
1 parent 4f4402c commit 2b8dab7

1 file changed

Lines changed: 53 additions & 37 deletions

File tree

Modules/zipimport.c

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -60,26 +60,29 @@ static PyObject *get_module_code(ZipImporter *self, char *fullname,
6060
static int
6161
zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
6262
{
63-
char *path, *p, *prefix, buf[MAXPATHLEN+2];
64-
size_t len;
63+
PyObject *pathobj, *path_bytes, *files;
64+
Py_UNICODE *path, *p, *prefix, buf[MAXPATHLEN+2];
65+
Py_ssize_t len;
6566

6667
if (!_PyArg_NoKeywords("zipimporter()", kwds))
6768
return -1;
6869

69-
if (!PyArg_ParseTuple(args, "s:zipimporter", &path))
70+
if (!PyArg_ParseTuple(args, "O&:zipimporter",
71+
PyUnicode_FSDecoder, &pathobj))
7072
return -1;
7173

72-
len = strlen(path);
74+
/* copy path to buf */
75+
len = PyUnicode_GET_SIZE(pathobj);
7376
if (len == 0) {
7477
PyErr_SetString(ZipImportError, "archive path is empty");
75-
return -1;
78+
goto error;
7679
}
7780
if (len >= MAXPATHLEN) {
7881
PyErr_SetString(ZipImportError,
7982
"archive path too long");
80-
return -1;
83+
goto error;
8184
}
82-
strcpy(buf, path);
85+
Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(pathobj));
8386

8487
#ifdef ALTSEP
8588
for (p = buf; *p; p++) {
@@ -94,64 +97,77 @@ zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
9497
struct stat statbuf;
9598
int rv;
9699

97-
rv = stat(buf, &statbuf);
100+
if (pathobj == NULL) {
101+
pathobj = PyUnicode_FromUnicode(buf, len);
102+
if (pathobj == NULL)
103+
goto error;
104+
}
105+
rv = _Py_stat(pathobj, &statbuf);
98106
if (rv == 0) {
99107
/* it exists */
100108
if (S_ISREG(statbuf.st_mode))
101109
/* it's a file */
102110
path = buf;
103111
break;
104112
}
113+
else if (PyErr_Occurred())
114+
goto error;
105115
/* back up one path element */
106-
p = strrchr(buf, SEP);
116+
p = Py_UNICODE_strrchr(buf, SEP);
107117
if (prefix != NULL)
108118
*prefix = SEP;
109119
if (p == NULL)
110120
break;
111121
*p = '\0';
122+
len = p - buf;
112123
prefix = p;
124+
Py_CLEAR(pathobj);
113125
}
114-
if (path != NULL) {
115-
PyObject *files;
116-
files = PyDict_GetItemString(zip_directory_cache, path);
117-
if (files == NULL) {
118-
files = read_directory(buf);
119-
if (files == NULL)
120-
return -1;
121-
if (PyDict_SetItemString(zip_directory_cache, path,
122-
files) != 0)
123-
return -1;
124-
}
125-
else
126-
Py_INCREF(files);
127-
self->files = files;
128-
}
129-
else {
126+
if (path == NULL) {
130127
PyErr_SetString(ZipImportError, "not a Zip file");
131-
return -1;
128+
goto error;
132129
}
133130

134-
if (prefix == NULL)
135-
prefix = "";
136-
else {
131+
files = PyDict_GetItem(zip_directory_cache, pathobj);
132+
if (files == NULL) {
133+
path_bytes = PyUnicode_EncodeFSDefault(pathobj);
134+
if (path_bytes == NULL)
135+
goto error;
136+
files = read_directory(PyBytes_AS_STRING(path_bytes));
137+
Py_DECREF(path_bytes);
138+
if (files == NULL)
139+
goto error;
140+
if (PyDict_SetItem(zip_directory_cache, pathobj, files) != 0)
141+
goto error;
142+
}
143+
else
144+
Py_INCREF(files);
145+
self->files = files;
146+
147+
self->archive = pathobj;
148+
pathobj = NULL;
149+
150+
if (prefix != NULL) {
137151
prefix++;
138-
len = strlen(prefix);
152+
len = Py_UNICODE_strlen(prefix);
139153
if (prefix[len-1] != SEP) {
140154
/* add trailing SEP */
141155
prefix[len] = SEP;
142156
prefix[len + 1] = '\0';
157+
len++;
143158
}
144159
}
145-
146-
self->archive = PyUnicode_FromString(buf);
147-
if (self->archive == NULL)
148-
return -1;
149-
150-
self->prefix = PyUnicode_FromString(prefix);
160+
else
161+
len = 0;
162+
self->prefix = PyUnicode_FromUnicode(prefix, len);
151163
if (self->prefix == NULL)
152-
return -1;
164+
goto error;
153165

154166
return 0;
167+
168+
error:
169+
Py_XDECREF(pathobj);
170+
return -1;
155171
}
156172

157173
/* GC support. */

0 commit comments

Comments
 (0)