Issue #3080: find_module() returns the path as Unicode

This commit is contained in:
Victor Stinner 2011-03-14 15:19:39 -04:00
parent c9a271cf2b
commit 2fd76e478f

View file

@ -1498,7 +1498,7 @@ unchanged:
/* Forward */ /* Forward */
static PyObject *load_module(PyObject *, FILE *, PyObject *, int, PyObject *); static PyObject *load_module(PyObject *, FILE *, PyObject *, int, PyObject *);
static struct filedescr *find_module(PyObject *, PyObject *, PyObject *, static struct filedescr *find_module(PyObject *, PyObject *, PyObject *,
char *, size_t, FILE **, PyObject **); PyObject **, FILE **, PyObject **);
static struct _frozen * find_frozen(PyObject *); static struct _frozen * find_frozen(PyObject *);
/* Load a package and return its module object WITH INCREMENTED /* Load a package and return its module object WITH INCREMENTED
@ -1510,7 +1510,6 @@ load_package(PyObject *name, PyObject *pathname)
PyObject *m, *d, *bufobj; PyObject *m, *d, *bufobj;
PyObject *file = NULL, *path_list = NULL; PyObject *file = NULL, *path_list = NULL;
int err; int err;
char buf[MAXPATHLEN+1];
FILE *fp = NULL; FILE *fp = NULL;
struct filedescr *fdp; struct filedescr *fdp;
@ -1538,7 +1537,7 @@ load_package(PyObject *name, PyObject *pathname)
return NULL; return NULL;
} }
fdp = find_module(name, initstr, path_list, fdp = find_module(name, initstr, path_list,
buf, sizeof(buf), &fp, NULL); &bufobj, &fp, NULL);
Py_DECREF(path_list); Py_DECREF(path_list);
if (fdp == NULL) { if (fdp == NULL) {
if (PyErr_ExceptionMatches(PyExc_ImportError)) { if (PyErr_ExceptionMatches(PyExc_ImportError)) {
@ -1549,13 +1548,8 @@ load_package(PyObject *name, PyObject *pathname)
else else
return NULL; return NULL;
} }
bufobj = PyUnicode_DecodeFSDefault(buf);
if (bufobj != NULL) {
m = load_module(name, fp, bufobj, fdp->type, NULL); m = load_module(name, fp, bufobj, fdp->type, NULL);
Py_DECREF(bufobj); Py_XDECREF(bufobj);
}
else
m = NULL;
if (fp != NULL) if (fp != NULL)
fclose(fp); fclose(fp);
return m; return m;
@ -1686,43 +1680,40 @@ static struct filedescr importhookdescr = {"", "", IMP_HOOK};
static int static int
find_module_path(PyObject *fullname, PyObject *name, PyObject *path, find_module_path(PyObject *fullname, PyObject *name, PyObject *path,
PyObject *path_hooks, PyObject *path_importer_cache, PyObject *path_hooks, PyObject *path_importer_cache,
char *buf, size_t buflen, PyObject **p_path, PyObject **p_loader, struct filedescr **p_fd)
PyObject **p_loader, struct filedescr **p_fd)
{ {
PyObject *path_bytes; Py_UNICODE buf[MAXPATHLEN+1];
const char *base; Py_ssize_t buflen = MAXPATHLEN+1;
PyObject *path_unicode, *filename;
const Py_UNICODE *base;
Py_ssize_t len; Py_ssize_t len;
size_t namelen;
struct stat statbuf; struct stat statbuf;
static struct filedescr fd_package = {"", "", PKG_DIRECTORY}; static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
char *namestr;
if (PyUnicode_Check(path)) { if (PyUnicode_Check(path)) {
path_bytes = PyUnicode_EncodeFSDefault(path); Py_INCREF(path);
if (path_bytes == NULL) path_unicode = path;
return -1;
} }
else if (PyBytes_Check(path)) { else if (PyBytes_Check(path)) {
Py_INCREF(path); path_unicode = PyUnicode_DecodeFSDefaultAndSize(
path_bytes = path; PyBytes_AS_STRING(path), PyBytes_GET_SIZE(path));
if (path_unicode == NULL)
return -1;
} }
else else
return 0; return 0;
namestr = _PyUnicode_AsString(name); base = PyUnicode_AS_UNICODE(path_unicode);
namelen = strlen(namestr); len = PyUnicode_GET_SIZE(path_unicode);
base = PyBytes_AS_STRING(path_bytes); if (len + 2 + PyUnicode_GET_SIZE(name) + MAXSUFFIXSIZE >= buflen) {
len = PyBytes_GET_SIZE(path_bytes); Py_DECREF(path_unicode);
if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) {
Py_DECREF(path_bytes);
return 0; /* Too long */ return 0; /* Too long */
} }
strcpy(buf, base); Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(path_unicode));
Py_DECREF(path_bytes); Py_DECREF(path_unicode);
if (strlen(buf) != len) { if (Py_UNICODE_strlen(buf) != len)
return 0; /* path_bytes contains '\0' */ return 0; /* path contains '\0' */
}
/* sys.path_hooks import hook */ /* sys.path_hooks import hook */
if (p_loader != NULL) { if (p_loader != NULL) {
@ -1758,21 +1749,21 @@ find_module_path(PyObject *fullname, PyObject *name, PyObject *path,
#endif #endif
) )
buf[len++] = SEP; buf[len++] = SEP;
strcpy(buf+len, namestr); Py_UNICODE_strcpy(buf+len, PyUnicode_AS_UNICODE(name));
len += namelen; len += PyUnicode_GET_SIZE(name);
filename = PyUnicode_FromUnicode(buf, len);
if (filename == NULL)
return -1;
/* Check for package import (buf holds a directory name, /* Check for package import (buf holds a directory name,
and there's an __init__ module in that directory */ and there's an __init__ module in that directory */
#ifdef HAVE_STAT #ifdef HAVE_STAT
if (stat(buf, &statbuf) == 0 && /* it exists */ if (_Py_stat(filename, &statbuf) == 0 && /* it exists */
S_ISDIR(statbuf.st_mode)) /* it's a directory */ S_ISDIR(statbuf.st_mode)) /* it's a directory */
{ {
int match; int match;
PyObject *filename;
filename = PyUnicode_DecodeFSDefault(buf);
if (filename == NULL)
return -1;
match = case_ok(filename, 0, name); match = case_ok(filename, 0, name);
if (match < 0) { if (match < 0) {
Py_DECREF(filename); Py_DECREF(filename);
@ -1780,7 +1771,7 @@ find_module_path(PyObject *fullname, PyObject *name, PyObject *path,
} }
if (match) { /* case matches */ if (match) { /* case matches */
if (find_init_module(filename)) { /* and has __init__.py */ if (find_init_module(filename)) { /* and has __init__.py */
Py_DECREF(filename); *p_path = filename;
*p_fd = &fd_package; *p_fd = &fd_package;
return 2; return 2;
} }
@ -1795,9 +1786,9 @@ find_module_path(PyObject *fullname, PyObject *name, PyObject *path,
} }
} }
} }
Py_DECREF(filename);
} }
#endif #endif
*p_path = filename;
return 1; return 1;
} }
@ -1814,21 +1805,16 @@ static struct filedescr*
find_module_path_list(PyObject *fullname, PyObject *name, find_module_path_list(PyObject *fullname, PyObject *name,
PyObject *search_path_list, PyObject *path_hooks, PyObject *search_path_list, PyObject *path_hooks,
PyObject *path_importer_cache, PyObject *path_importer_cache,
char *buf, size_t buflen, PyObject **p_path, FILE **p_fp, PyObject **p_loader)
FILE **p_fp, PyObject **p_loader)
{ {
Py_ssize_t i, npath; Py_ssize_t i, npath;
size_t len, namelen;
struct filedescr *fdp = NULL; struct filedescr *fdp = NULL;
char *filemode; char *filemode;
FILE *fp = NULL; FILE *fp = NULL;
char *namestr; PyObject *prefix, *filename;
PyObject *filename;
int match; int match;
npath = PyList_Size(search_path_list); npath = PyList_Size(search_path_list);
namestr = _PyUnicode_AsString(name);
namelen = strlen(namestr);
for (i = 0; i < npath; i++) { for (i = 0; i < npath; i++) {
PyObject *path; PyObject *path;
int ok; int ok;
@ -1837,27 +1823,29 @@ find_module_path_list(PyObject *fullname, PyObject *name,
if (path == NULL) if (path == NULL)
return NULL; return NULL;
prefix = NULL;
ok = find_module_path(fullname, name, path, ok = find_module_path(fullname, name, path,
path_hooks, path_importer_cache, path_hooks, path_importer_cache,
buf, buflen, &prefix, p_loader, &fdp);
p_loader, &fdp);
if (ok < 0) if (ok < 0)
return NULL; return NULL;
if (ok == 0) if (ok == 0)
continue; continue;
if (ok == 2) if (ok == 2) {
*p_path = prefix;
return fdp; return fdp;
}
len = strlen(buf);
for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) { for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
filemode = fdp->mode; filemode = fdp->mode;
if (filemode[0] == 'U') if (filemode[0] == 'U')
filemode = "r" PY_STDIOTEXTMODE; filemode = "r" PY_STDIOTEXTMODE;
strcpy(buf+len, fdp->suffix); filename = PyUnicode_FromFormat("%U%s", prefix, fdp->suffix);
filename = PyUnicode_DecodeFSDefault(buf); if (filename == NULL) {
if (filename == NULL) Py_DECREF(prefix);
return NULL; return NULL;
}
if (Py_VerboseFlag > 1) if (Py_VerboseFlag > 1)
PySys_FormatStderr("# trying %R\n", filename); PySys_FormatStderr("# trying %R\n", filename);
@ -1869,11 +1857,13 @@ find_module_path_list(PyObject *fullname, PyObject *name,
} }
match = case_ok(filename, -(Py_ssize_t)strlen(fdp->suffix), name); match = case_ok(filename, -(Py_ssize_t)strlen(fdp->suffix), name);
if (match < 0) { if (match < 0) {
Py_DECREF(prefix);
Py_DECREF(filename); Py_DECREF(filename);
return NULL; return NULL;
} }
if (match) { if (match) {
Py_DECREF(filename); Py_DECREF(prefix);
*p_path = filename;
*p_fp = fp; *p_fp = fp;
return fdp; return fdp;
} }
@ -1882,6 +1872,7 @@ find_module_path_list(PyObject *fullname, PyObject *name,
fclose(fp); fclose(fp);
fp = NULL; fp = NULL;
} }
Py_DECREF(prefix);
} }
PyErr_Format(PyExc_ImportError, PyErr_Format(PyExc_ImportError,
"No module named %U", name); "No module named %U", name);
@ -1897,32 +1888,35 @@ find_module_path_list(PyObject *fullname, PyObject *name,
- otherwise, call find_module_path_list() with search_path_list (if not - otherwise, call find_module_path_list() with search_path_list (if not
NULL) or sys.path NULL) or sys.path
fullname can be NULL, but only if p_loader is NULL.
Return: Return:
- &fd_builtin (C_BUILTIN) if it is a builtin - &fd_builtin (C_BUILTIN) if it is a builtin
- &fd_frozen (PY_FROZEN) if it is frozen - &fd_frozen (PY_FROZEN) if it is frozen
- &fd_package (PKG_DIRECTORY) and write the filename into *buf - &fd_package (PKG_DIRECTORY) and write the filename into *p_path
if it is a package if it is a package
- &importhookdescr (IMP_HOOK) and write the loader into *p_loader if a - &importhookdescr (IMP_HOOK) and write the loader into *p_loader if a
importer loader was found importer loader was found
- a file descriptor (PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE or - a file descriptor (PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE or
PY_CODERESOURCE: see _PyImport_Filetab), write the filename into PY_CODERESOURCE: see _PyImport_Filetab), write the filename into
*buf and the pointer to the open file into *p_fp *p_path and the pointer to the open file into *p_fp
- NULL on error - NULL on error
By default, write an empty string into *buf, and *p_fp and *p_loader (if By default, *p_path, *p_fp and *p_loader (if set) are set to NULL.
set) are set to NULL. Eg. *buf is an empty string for a builtin package. */ Eg. *p_path is set to NULL for a builtin package.
*/
static struct filedescr * static struct filedescr *
find_module(PyObject *fullname, PyObject *name, PyObject *search_path_list, find_module(PyObject *fullname, PyObject *name, PyObject *search_path_list,
char *buf, size_t buflen, FILE **p_fp, PyObject **p_loader) PyObject **p_path, FILE **p_fp, PyObject **p_loader)
{ {
Py_ssize_t i, npath; Py_ssize_t i, npath;
static struct filedescr fd_frozen = {"", "", PY_FROZEN}; static struct filedescr fd_frozen = {"", "", PY_FROZEN};
static struct filedescr fd_builtin = {"", "", C_BUILTIN}; static struct filedescr fd_builtin = {"", "", C_BUILTIN};
PyObject *path_hooks, *path_importer_cache; PyObject *path_hooks, *path_importer_cache;
*buf = '\0'; *p_path = NULL;
*p_fp = NULL; *p_fp = NULL;
if (p_loader != NULL) if (p_loader != NULL)
*p_loader = NULL; *p_loader = NULL;
@ -1975,20 +1969,12 @@ find_module(PyObject *fullname, PyObject *name, PyObject *search_path_list,
#ifdef MS_COREDLL #ifdef MS_COREDLL
FILE *fp; FILE *fp;
struct filedescr *fdp; struct filedescr *fdp;
PyObject *filename, *filename_bytes;
#endif #endif
if (is_builtin(name)) if (is_builtin(name))
return &fd_builtin; return &fd_builtin;
#ifdef MS_COREDLL #ifdef MS_COREDLL
fp = _PyWin_FindRegisteredModule(name, &fdp, &filename); fp = _PyWin_FindRegisteredModule(name, &fdp, p_path);
if (fp != NULL) { if (fp != NULL) {
filename_bytes = PyUnicode_EncodeFSDefault(filename);
Py_DECREF(filename);
if (filename_bytes == NULL)
return NULL;
strncpy(buf, PyBytes_AS_STRING(filename_bytes), buflen);
buf[buflen-1] = '\0';
Py_DECREF(filename_bytes);
*p_fp = fp; *p_fp = fp;
return fdp; return fdp;
} }
@ -2022,8 +2008,7 @@ find_module(PyObject *fullname, PyObject *name, PyObject *search_path_list,
return find_module_path_list(fullname, name, return find_module_path_list(fullname, name,
search_path_list, path_hooks, search_path_list, path_hooks,
path_importer_cache, path_importer_cache,
buf, buflen, p_path, p_fp, p_loader);
p_fp, p_loader);
} }
/* case_bytes(char* buf, Py_ssize_t len, Py_ssize_t namelen, char* name) /* case_bytes(char* buf, Py_ssize_t len, Py_ssize_t namelen, char* name)
@ -3185,7 +3170,6 @@ import_submodule(PyObject *mod, PyObject *subname, PyObject *fullname)
{ {
PyObject *modules = PyImport_GetModuleDict(); PyObject *modules = PyImport_GetModuleDict();
PyObject *m = NULL, *bufobj, *path_list, *loader; PyObject *m = NULL, *bufobj, *path_list, *loader;
char buf[MAXPATHLEN+1];
struct filedescr *fdp; struct filedescr *fdp;
FILE *fp; FILE *fp;
@ -3211,7 +3195,7 @@ import_submodule(PyObject *mod, PyObject *subname, PyObject *fullname)
} }
fdp = find_module(fullname, subname, path_list, fdp = find_module(fullname, subname, path_list,
buf, MAXPATHLEN+1, &fp, &loader); &bufobj, &fp, &loader);
Py_XDECREF(path_list); Py_XDECREF(path_list);
if (fdp == NULL) { if (fdp == NULL) {
if (!PyErr_ExceptionMatches(PyExc_ImportError)) if (!PyErr_ExceptionMatches(PyExc_ImportError))
@ -3220,13 +3204,8 @@ import_submodule(PyObject *mod, PyObject *subname, PyObject *fullname)
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
bufobj = PyUnicode_DecodeFSDefault(buf);
if (bufobj != NULL) {
m = load_module(fullname, fp, bufobj, fdp->type, loader); m = load_module(fullname, fp, bufobj, fdp->type, loader);
Py_DECREF(bufobj); Py_XDECREF(bufobj);
}
else
m = NULL;
Py_XDECREF(loader); Py_XDECREF(loader);
if (fp) if (fp)
fclose(fp); fclose(fp);
@ -3249,7 +3228,6 @@ PyImport_ReloadModule(PyObject *m)
PyInterpreterState *interp = PyThreadState_Get()->interp; PyInterpreterState *interp = PyThreadState_Get()->interp;
PyObject *modules_reloading = interp->modules_reloading; PyObject *modules_reloading = interp->modules_reloading;
PyObject *modules = PyImport_GetModuleDict(); PyObject *modules = PyImport_GetModuleDict();
char buf[MAXPATHLEN+1];
PyObject *path_list = NULL, *loader = NULL, *existing_m = NULL; PyObject *path_list = NULL, *loader = NULL, *existing_m = NULL;
PyObject *nameobj, *bufobj, *subnameobj; PyObject *nameobj, *bufobj, *subnameobj;
Py_UNICODE *name, *subname; Py_UNICODE *name, *subname;
@ -3324,7 +3302,7 @@ PyImport_ReloadModule(PyObject *m)
if (subnameobj == NULL) if (subnameobj == NULL)
goto error; goto error;
fdp = find_module(nameobj, subnameobj, path_list, fdp = find_module(nameobj, subnameobj, path_list,
buf, MAXPATHLEN+1, &fp, &loader); &bufobj, &fp, &loader);
Py_DECREF(subnameobj); Py_DECREF(subnameobj);
Py_XDECREF(path_list); Py_XDECREF(path_list);
@ -3333,13 +3311,8 @@ PyImport_ReloadModule(PyObject *m)
goto error; goto error;
} }
bufobj = PyUnicode_DecodeFSDefault(buf);
if (bufobj != NULL) {
newm = load_module(nameobj, fp, bufobj, fdp->type, loader); newm = load_module(nameobj, fp, bufobj, fdp->type, loader);
Py_DECREF(bufobj); Py_XDECREF(bufobj);
}
else
newm = NULL;
Py_XDECREF(loader); Py_XDECREF(loader);
if (fp) if (fp)
@ -3509,17 +3482,15 @@ call_find_module(PyObject *name, PyObject *path_list)
PyObject *fob, *ret; PyObject *fob, *ret;
PyObject *pathobj; PyObject *pathobj;
struct filedescr *fdp; struct filedescr *fdp;
char pathname[MAXPATHLEN+1];
FILE *fp; FILE *fp;
int fd = -1; int fd = -1;
char *found_encoding = NULL; char *found_encoding = NULL;
char *encoding = NULL; char *encoding = NULL;
pathname[0] = '\0';
if (path_list == Py_None) if (path_list == Py_None)
path_list = NULL; path_list = NULL;
fdp = find_module(NULL, name, path_list, fdp = find_module(NULL, name, path_list,
pathname, MAXPATHLEN+1, &fp, NULL); &pathobj, &fp, NULL);
if (fdp == NULL) if (fdp == NULL)
return NULL; return NULL;
if (fp != NULL) { if (fp != NULL) {
@ -3535,14 +3506,17 @@ call_find_module(PyObject *name, PyObject *path_list)
memory. */ memory. */
found_encoding = PyTokenizer_FindEncoding(fd); found_encoding = PyTokenizer_FindEncoding(fd);
lseek(fd, 0, 0); /* Reset position */ lseek(fd, 0, 0); /* Reset position */
if (found_encoding == NULL && PyErr_Occurred()) if (found_encoding == NULL && PyErr_Occurred()) {
Py_XDECREF(pathobj);
return NULL; return NULL;
}
encoding = (found_encoding != NULL) ? found_encoding : encoding = (found_encoding != NULL) ? found_encoding :
(char*)PyUnicode_GetDefaultEncoding(); (char*)PyUnicode_GetDefaultEncoding();
} }
fob = PyFile_FromFd(fd, pathname, fdp->mode, -1, fob = PyFile_FromFd(fd, NULL, fdp->mode, -1,
(char*)encoding, NULL, NULL, 1); (char*)encoding, NULL, NULL, 1);
if (fob == NULL) { if (fob == NULL) {
Py_XDECREF(pathobj);
close(fd); close(fd);
PyMem_FREE(found_encoding); PyMem_FREE(found_encoding);
return NULL; return NULL;
@ -3552,7 +3526,10 @@ call_find_module(PyObject *name, PyObject *path_list)
fob = Py_None; fob = Py_None;
Py_INCREF(fob); Py_INCREF(fob);
} }
pathobj = PyUnicode_DecodeFSDefault(pathname); if (pathobj == NULL) {
Py_INCREF(Py_None);
pathobj = Py_None;
}
ret = Py_BuildValue("NN(ssi)", ret = Py_BuildValue("NN(ssi)",
fob, pathobj, fdp->suffix, fdp->mode, fdp->type); fob, pathobj, fdp->suffix, fdp->mode, fdp->type);
PyMem_FREE(found_encoding); PyMem_FREE(found_encoding);