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

Skip to content

Commit 547a2a6

Browse files
author
Victor Stinner
committed
Issue #3080: find_init_module() expects Unicode
1 parent d029621 commit 547a2a6

1 file changed

Lines changed: 45 additions & 43 deletions

File tree

Python/import.c

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,8 +1668,9 @@ extern FILE *_PyWin_FindRegisteredModule(PyObject *, struct filedescr **,
16681668
PyObject **p_path);
16691669
#endif
16701670

1671+
/* Forward */
16711672
static int case_ok(char *, Py_ssize_t, Py_ssize_t, const char *);
1672-
static int find_init_module(char *); /* Forward */
1673+
static int find_init_module(PyObject *);
16731674
static struct filedescr importhookdescr = {"", "", IMP_HOOK};
16741675

16751676
/* Get the path of a module: get its importer and call importer.find_module()
@@ -1766,24 +1767,27 @@ find_module_path(PyObject *fullname, PyObject *name, PyObject *path,
17661767
if (stat(buf, &statbuf) == 0 && /* it exists */
17671768
S_ISDIR(statbuf.st_mode)) /* it's a directory */
17681769
{
1770+
PyObject *bufobj = PyUnicode_DecodeFSDefault(buf);
1771+
if (bufobj == NULL)
1772+
return -1;
17691773
if (case_ok(buf, len, namelen, namestr)) { /* case matches */
1770-
if (find_init_module(buf)) { /* and has __init__.py */
1774+
if (find_init_module(bufobj)) { /* and has __init__.py */
1775+
Py_DECREF(bufobj);
17711776
*p_fd = &fd_package;
17721777
return 2;
17731778
}
17741779
else {
17751780
int err;
1776-
PyObject *unicode = PyUnicode_DecodeFSDefault(buf);
1777-
if (unicode == NULL)
1778-
return -1;
17791781
err = PyErr_WarnFormat(PyExc_ImportWarning, 1,
1780-
"Not importing directory '%U': missing __init__.py",
1781-
unicode);
1782-
Py_DECREF(unicode);
1783-
if (err)
1782+
"Not importing directory %R: missing __init__.py",
1783+
bufobj);
1784+
if (err) {
1785+
Py_DECREF(bufobj);
17841786
return -1;
1787+
}
17851788
}
17861789
}
1790+
Py_DECREF(bufobj);
17871791
}
17881792
#endif
17891793
return 1;
@@ -2154,49 +2158,47 @@ case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, const char *name)
21542158

21552159
#ifdef HAVE_STAT
21562160

2157-
/* Helper to look for __init__.py or __init__.py[co] in potential package */
2161+
/* Helper to look for __init__.py or __init__.py[co] in potential package.
2162+
Return 1 if __init__ was found, 0 if not, or -1 on error. */
21582163
static int
2159-
find_init_module(char *buf)
2164+
find_init_module(PyObject *directory)
21602165
{
2161-
const size_t save_len = strlen(buf);
2162-
size_t i = save_len;
2163-
char *pname; /* pointer to start of __init__ */
2166+
size_t len;
21642167
struct stat statbuf;
2165-
2166-
/* For calling case_ok(buf, len, namelen, name):
2167-
* /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
2168-
* ^ ^ ^ ^
2169-
* |--------------------- buf ---------------------|
2170-
* |------------------- len ------------------|
2171-
* |------ name -------|
2172-
* |----- namelen -----|
2173-
*/
2174-
if (save_len + 13 >= MAXPATHLEN)
2175-
return 0;
2176-
buf[i++] = SEP;
2177-
pname = buf + i;
2178-
strcpy(pname, "__init__.py");
2179-
if (stat(buf, &statbuf) == 0) {
2180-
if (case_ok(buf,
2181-
save_len + 9, /* len("/__init__") */
2182-
8, /* len("__init__") */
2183-
pname)) {
2184-
buf[save_len] = '\0';
2168+
PyObject *filename;
2169+
int match;
2170+
char *filestr;
2171+
size_t filelen;
2172+
2173+
len = PyUnicode_GET_SIZE(directory);
2174+
filename = PyUnicode_FromFormat("%U%c__init__.py", directory, SEP);
2175+
if (filename == NULL)
2176+
return -1;
2177+
if (_Py_stat(filename, &statbuf) == 0) {
2178+
/* 9=len("/__init__") */
2179+
filestr = _PyUnicode_AsString(filename);
2180+
filelen = strlen(filestr);
2181+
if (case_ok(filestr, filelen-9, 8, "__init__")) {
2182+
Py_DECREF(filename);
21852183
return 1;
21862184
}
21872185
}
2188-
i += strlen(pname);
2189-
strcpy(buf+i, Py_OptimizeFlag ? "o" : "c");
2190-
if (stat(buf, &statbuf) == 0) {
2191-
if (case_ok(buf,
2192-
save_len + 9, /* len("/__init__") */
2193-
8, /* len("__init__") */
2194-
pname)) {
2195-
buf[save_len] = '\0';
2186+
Py_DECREF(filename);
2187+
2188+
filename = PyUnicode_FromFormat("%U%c__init__.py%c",
2189+
directory, SEP, Py_OptimizeFlag ? 'o' : 'c');
2190+
if (filename == NULL)
2191+
return -1;
2192+
if (_Py_stat(filename, &statbuf) == 0) {
2193+
/* 9=len("/__init__") */
2194+
filestr = _PyUnicode_AsString(filename);
2195+
filelen = strlen(filestr);
2196+
if (case_ok(filestr, filelen-9, 8, "__init__")) {
2197+
Py_DECREF(filename);
21962198
return 1;
21972199
}
21982200
}
2199-
buf[save_len] = '\0';
2201+
Py_DECREF(filename);
22002202
return 0;
22012203
}
22022204

0 commit comments

Comments
 (0)