[Python-checkins] cpython: Issue #3080: case_ok() expects Unicode strings (original) (raw)

victor.stinner python-checkins at python.org
Sun Mar 20 04:14:00 CET 2011


http://hg.python.org/cpython/rev/066b399a8477 changeset: 68734:066b399a8477 user: Victor Stinner <victor.stinner at haypocalc.com> date: Mon Mar 14 14:34:13 2011 -0400 summary: Issue #3080: case_ok() expects Unicode strings

files: Python/import.c

diff --git a/Python/import.c b/Python/import.c --- a/Python/import.c +++ b/Python/import.c @@ -1669,7 +1669,7 @@ #endif /* Forward */ -static int case_ok(char *, Py_ssize_t, Py_ssize_t, const char *); +static int case_ok(PyObject *, Py_ssize_t, PyObject *); static int find_init_module(PyObject ); static struct filedescr importhookdescr = {"", "", IMP_HOOK}; @@ -1767,12 +1767,20 @@ if (stat(buf, &statbuf) == 0 && / it exists / S_ISDIR(statbuf.st_mode)) / it's a directory */ { - PyObject *bufobj = PyUnicode_DecodeFSDefault(buf); - if (bufobj == NULL) + int match; + PyObject filename; + + filename = PyUnicode_DecodeFSDefault(buf); + if (filename == NULL) return -1; - if (case_ok(buf, len, namelen, namestr)) { / case matches / - if (find_init_module(bufobj)) { / and has init.py */ - Py_DECREF(bufobj); + match = case_ok(filename, 0, name); + if (match < 0) { + Py_DECREF(filename); + return -1; + } + if (match) { /* case matches */ + if (find_init_module(filename)) { /* and has __init__.py */ + Py_DECREF(filename); *p_fd = &fd_package; return 2; } @@ -1780,14 +1788,14 @@ int err; err = PyErr_WarnFormat(PyExc_ImportWarning, 1, "Not importing directory %R: missing __init__.py", - bufobj); + filename); if (err) { - Py_DECREF(bufobj); + Py_DECREF(filename); return -1; } } } - Py_DECREF(bufobj); + Py_DECREF(filename); } #endif return 1; @@ -1815,6 +1823,8 @@ char *filemode; FILE *fp = NULL; char *namestr; + PyObject *filename; + int match; npath = PyList_Size(search_path_list); namestr = _PyUnicode_AsString(name); @@ -1840,20 +1850,34 @@ len = strlen(buf); for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) { - strcpy(buf+len, fdp->suffix); - if (Py_VerboseFlag > 1) - PySys_WriteStderr("# trying %s\n", buf); filemode = fdp->mode; if (filemode[0] == 'U') filemode = "r" PY_STDIOTEXTMODE; - fp = fopen(buf, filemode); - if (fp == NULL) + + strcpy(buf+len, fdp->suffix); + filename = PyUnicode_DecodeFSDefault(buf); + if (filename == NULL) + return NULL; + + if (Py_VerboseFlag > 1) + PySys_FormatStderr("# trying %R\n", filename); + + fp = _Py_fopen(filename, filemode); + if (fp == NULL) { + Py_DECREF(filename); continue;

@@ -2002,7 +2026,7 @@ p_fp, p_loader); } -/* case_ok(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) * The arguments here are tricky, best shown by example: * /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0 * ^ ^ ^ ^ @@ -2016,18 +2040,18 @@ * We've already done a successful stat() or fopen() on buf, so know that * there's some match, possibly case-insensitive. * - * case_ok() is to return 1 if there's a case-sensitive match for - * name, else 0. case_ok() is also to return 1 if envar PYTHONCASEOK + * case_bytes() is to return 1 if there's a case-sensitive match for + * name, else 0. case_bytes() is also to return 1 if envar PYTHONCASEOK * exists. * - * case_ok() is used to implement case-sensitive import semantics even + * case_bytes() is used to implement case-sensitive import semantics even * on platforms with case-insensitive filesystems. It's trivial to implement * for case-sensitive filesystems. It's pretty much a cross-platform * nightmare for systems with case-insensitive filesystems. / / First we may need a pile of platform-specific header files; the sequence - * of #if's here should match the sequence in the body of case_ok(). + * of #if's here should match the sequence in the body of case_bytes(). */ #if defined(MS_WINDOWS) #include <windows.h> @@ -2046,33 +2070,24 @@ #include <os2.h> #endif +#if defined(DJGPP)
+ || ((defined(MACH) && defined(APPLE) || defined(CYGWIN))
+ && defined(HAVE_DIRENT_H))
+ || defined(PYOS_OS2) +# define USE_CASE_OK_BYTES +#endif + + +#ifdef USE_CASE_OK_BYTES static int -case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, const char *name) +case_bytes(char *buf, Py_ssize_t len, Py_ssize_t namelen, const char name) { / Pick a platform-specific implementation; the sequence of #if's here should * match the sequence just above. / -/ MS_WINDOWS */ -#if defined(MS_WINDOWS) - WIN32_FIND_DATA data; - HANDLE h;

+#if defined(DJGPP) struct ffblk ffblk; int done;

@@ -2151,6 +2166,70 @@

/* assuming it's a case-sensitive filesystem, so there's nothing to do! / #else +# error "USE_CASE_OK_BYTES is not correctly defined" +#endif +} +#endif + +/

+#elif defined(USE_CASE_OK_BYTES)

+#else

#endif @@ -2167,8 +2246,6 @@ struct stat statbuf; PyObject *filename; int match;

@@ -2176,9 +2253,12 @@ return -1; if (_Py_stat(filename, &statbuf) == 0) { /* 9=len("/init") */

@@ -2191,9 +2271,12 @@ return -1; if (_Py_stat(filename, &statbuf) == 0) { /* 9=len("/init") */

-- Repository URL: http://hg.python.org/cpython



More information about the Python-checkins mailing list