Add case checking feature on import.

This is an option for OS-es with case-insensitive but case-preserving
filesystems.  It is currently supported for Win32 and MacOS.  To
enable it, #define CHECK_IMPORT_CASE in your platform specific
config.h.  It is enabled by default on those systems where it is
supported.  On Win32, it can be disabled at runtime by setting the
environment variable PYTHONCASEOK (to any value).

When enabled, the feature checks that the case of the requested module
name matches that of the filename found in the filesystem, and raises
a NameError exception when they don't match.
This commit is contained in:
Guido van Rossum 1998-02-13 17:18:36 +00:00
parent 4c6896304b
commit 0980bd9233
1 changed files with 78 additions and 1 deletions

View File

@ -796,6 +796,10 @@ is_builtin(name)
extern FILE *PyWin_FindRegisteredModule(); extern FILE *PyWin_FindRegisteredModule();
#endif #endif
#ifdef CHECK_IMPORT_CASE
static int check_case(char *, int, int, char *);
#endif
static int find_init_module Py_PROTO((char *)); /* Forward */ static int find_init_module Py_PROTO((char *)); /* Forward */
static struct filedescr * static struct filedescr *
@ -896,10 +900,16 @@ find_module(name, path, buf, buflen, p_fp)
if (stat(buf, &statbuf) == 0) { if (stat(buf, &statbuf) == 0) {
static struct filedescr fd = {"", "", PKG_DIRECTORY}; static struct filedescr fd = {"", "", PKG_DIRECTORY};
if (S_ISDIR(statbuf.st_mode)) { if (S_ISDIR(statbuf.st_mode)) {
if (find_init_module(buf)) if (find_init_module(buf)) {
#ifdef CHECK_IMPORT_CASE
if (!check_case(buf, len, namelen,
name))
return NULL;
#endif
return &fd; return &fd;
} }
} }
}
#else #else
/* XXX How are you going to test for directories? */ /* XXX How are you going to test for directories? */
#endif #endif
@ -925,11 +935,78 @@ find_module(name, path, buf, buflen, p_fp)
"No module named %.200s", name); "No module named %.200s", name);
return NULL; return NULL;
} }
#ifdef CHECK_IMPORT_CASE
if (!check_case(buf, len, namelen, name)) {
fclose(fp);
return NULL;
}
#endif
*p_fp = fp; *p_fp = fp;
return fdp; return fdp;
} }
#ifdef CHECK_IMPORT_CASE
#ifdef MS_WIN32
#include <windows.h>
static int
check_case(char *buf, int len, int namelen, char *name)
{
WIN32_FIND_DATA data;
HANDLE h;
if (getenv("PYTHONCASEOK") != NULL)
return 1;
h = FindFirstFile(buf, &data);
if (h == INVALID_HANDLE_VALUE) {
PyErr_Format(PyExc_NameError,
"Can't find file for module %.100s\n(filename %.300s)",
name, buf);
return 0;
}
FindClose(h);
if (strncmp(data.cFileName, name, namelen) != 0) {
strcpy(buf+len-namelen, data.cFileName);
PyErr_Format(PyExc_NameError,
"Case mismatch for module name %.100s\n(filename %.300s)",
name, buf);
return 0;
}
return 1;
}
#endif /* MS_WIN32 */
#ifdef macintosh
#include <TextUtils.h>
static int
check_case(char *buf, int len, int namelen, char *name)
{
FSSpec fss;
OSErr err;
unsigned char mybuf[MAXPATHLEN+1];
strcpy((char *)mybuf, buf);
c2pstr((char *)mybuf);
err = FSMakeFSSpec(0, 0, mybuf, &fss);
if (err) {
PyErr_Format(PyExc_NameError,
"Can't find file for module %.100s\n(filename %.300s)",
name, buf);
return 0;
}
p2cstr(fss.name);
if ( strncmp(name, (char *)fss.name, namelen) != 0 ) {
PyErr_Format(PyExc_NameError,
"Case mismatch for module name %.100s\n(filename %.300s)",
name, fss.name);
return 0;
}
return 1;
}
#endif /* macintosh */
#endif CHECK_IMPORT_CASE
#ifdef HAVE_STAT #ifdef HAVE_STAT
/* Helper to look for __init__.py or __init__.py[co] in potential package */ /* Helper to look for __init__.py or __init__.py[co] in potential package */
static int static int