Issue #3080: _PyImport_LoadDynamicModule() uses Unicode for name and path

Document also that dynamic module names are ASCII only
This commit is contained in:
Victor Stinner 2011-03-14 15:54:07 -04:00
parent 4d6c1c476a
commit fefd70c40d
3 changed files with 60 additions and 66 deletions

View File

@ -2173,9 +2173,21 @@ load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
break; break;
#ifdef HAVE_DYNAMIC_LOADING #ifdef HAVE_DYNAMIC_LOADING
case C_EXTENSION: case C_EXTENSION: {
m = _PyImport_LoadDynamicModule(name, pathname, fp); PyObject *nameobj, *pathobj;
nameobj = PyUnicode_FromString(name);
if (nameobj == NULL)
return NULL;
pathobj = PyUnicode_DecodeFSDefault(pathname);
if (pathobj == NULL) {
Py_DECREF(nameobj);
return NULL;
}
m = _PyImport_LoadDynamicModule(nameobj, pathobj, fp);
Py_DECREF(nameobj);
Py_DECREF(pathobj);
break; break;
}
#endif #endif
case PKG_DIRECTORY: case PKG_DIRECTORY:
@ -2185,11 +2197,10 @@ load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
case C_BUILTIN: case C_BUILTIN:
case PY_FROZEN: { case PY_FROZEN: {
PyObject *nameobj = PyUnicode_FromString(name); PyObject *nameobj = PyUnicode_FromString(name);
if (nameobj != NULL) { if (nameobj == NULL)
m = load_builtin(nameobj, type); return NULL;
Py_DECREF(nameobj); m = load_builtin(nameobj, type);
} else Py_DECREF(nameobj);
m = NULL;
break; break;
} }
@ -3443,28 +3454,23 @@ imp_load_compiled(PyObject *self, PyObject *args)
static PyObject * static PyObject *
imp_load_dynamic(PyObject *self, PyObject *args) imp_load_dynamic(PyObject *self, PyObject *args)
{ {
char *name; PyObject *name, *pathname, *fob = NULL, *mod;
PyObject *pathbytes; FILE *fp;
char *pathname;
PyObject *fob = NULL; if (!PyArg_ParseTuple(args, "UO&|O:load_dynamic",
PyObject *m; &name, PyUnicode_FSDecoder, &pathname, &fob))
FILE *fp = NULL;
if (!PyArg_ParseTuple(args, "sO&|O:load_dynamic",
&name, PyUnicode_FSConverter, &pathbytes, &fob))
return NULL; return NULL;
pathname = PyBytes_AS_STRING(pathbytes); if (fob != NULL) {
if (fob) { fp = get_file(NULL, fob, "r");
fp = get_file(pathname, fob, "r"); if (fp == NULL)
if (fp == NULL) {
Py_DECREF(pathbytes);
return NULL; return NULL;
}
} }
m = _PyImport_LoadDynamicModule(name, pathname, fp); else
Py_DECREF(pathbytes); fp = NULL;
mod = _PyImport_LoadDynamicModule(name, pathname, fp);
if (fp) if (fp)
fclose(fp); fclose(fp);
return m; return mod;
} }
#endif /* HAVE_DYNAMIC_LOADING */ #endif /* HAVE_DYNAMIC_LOADING */

View File

@ -15,67 +15,68 @@
extern dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, extern dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
const char *pathname, FILE *fp); const char *pathname, FILE *fp);
/* name should be ASCII only because the C language doesn't accept non-ASCII
identifiers, and dynamic modules are written in C. */
PyObject * PyObject *
_PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp) _PyImport_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp)
{ {
PyObject *m; PyObject *m;
PyObject *path; PyObject *pathbytes;
char *lastdot, *shortname, *packagecontext, *oldcontext; char *namestr, *lastdot, *shortname, *packagecontext, *oldcontext;
dl_funcptr p0; dl_funcptr p0;
PyObject* (*p)(void); PyObject* (*p)(void);
struct PyModuleDef *def; struct PyModuleDef *def;
PyObject *nameobj, *result;
path = PyUnicode_DecodeFSDefault(pathname); namestr = _PyUnicode_AsString(name);
if (path == NULL) if (namestr == NULL)
return NULL; return NULL;
nameobj = PyUnicode_FromString(name); m = _PyImport_FindExtensionObject(name, path);
if (nameobj == NULL)
return NULL;
m = _PyImport_FindExtensionObject(nameobj, path);
if (m != NULL) { if (m != NULL) {
Py_DECREF(nameobj);
Py_INCREF(m); Py_INCREF(m);
result = m; return m;
goto finally;
} }
Py_DECREF(nameobj);
lastdot = strrchr(name, '.'); lastdot = strrchr(namestr, '.');
if (lastdot == NULL) { if (lastdot == NULL) {
packagecontext = NULL; packagecontext = NULL;
shortname = name; shortname = namestr;
} }
else { else {
packagecontext = name; packagecontext = namestr;
shortname = lastdot+1; shortname = lastdot+1;
} }
p0 = _PyImport_GetDynLoadFunc(shortname, pathname, fp); pathbytes = PyUnicode_EncodeFSDefault(path);
if (pathbytes == NULL)
return NULL;
p0 = _PyImport_GetDynLoadFunc(shortname,
PyBytes_AS_STRING(pathbytes), fp);
Py_DECREF(pathbytes);
p = (PyObject*(*)(void))p0; p = (PyObject*(*)(void))p0;
if (PyErr_Occurred()) if (PyErr_Occurred())
goto error; return NULL;
if (p == NULL) { if (p == NULL) {
PyErr_Format(PyExc_ImportError, PyErr_Format(PyExc_ImportError,
"dynamic module does not define init function (PyInit_%.200s)", "dynamic module does not define init function"
" (PyInit_%s)",
shortname); shortname);
goto error; return NULL;
} }
oldcontext = _Py_PackageContext; oldcontext = _Py_PackageContext;
_Py_PackageContext = packagecontext; _Py_PackageContext = packagecontext;
m = (*p)(); m = (*p)();
_Py_PackageContext = oldcontext; _Py_PackageContext = oldcontext;
if (m == NULL) if (m == NULL)
goto error; return NULL;
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
Py_DECREF(m); Py_DECREF(m);
PyErr_Format(PyExc_SystemError, PyErr_Format(PyExc_SystemError,
"initialization of %s raised unreported exception", "initialization of %s raised unreported exception",
shortname); shortname);
goto error; return NULL;
} }
/* Remember pointer to module init function. */ /* Remember pointer to module init function. */
@ -88,26 +89,13 @@ _PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp)
else else
Py_INCREF(path); Py_INCREF(path);
nameobj = PyUnicode_FromString(name); if (_PyImport_FixupExtensionObject(m, name, path) < 0)
if (nameobj == NULL)
return NULL; return NULL;
if (_PyImport_FixupExtensionObject(m, nameobj, path) < 0) {
Py_DECREF(nameobj);
goto error;
}
if (Py_VerboseFlag) if (Py_VerboseFlag)
PySys_FormatStderr( PySys_FormatStderr(
"import %U # dynamically loaded from %s\n", "import %U # dynamically loaded from %R\n",
nameobj, pathname); name, path);
Py_DECREF(nameobj); return m;
result = m;
goto finally;
error:
result = NULL;
finally:
Py_DECREF(path);
return result;
} }
#endif /* HAVE_DYNAMIC_LOADING */ #endif /* HAVE_DYNAMIC_LOADING */

View File

@ -28,7 +28,7 @@ struct filedescr {
extern struct filedescr * _PyImport_Filetab; extern struct filedescr * _PyImport_Filetab;
extern const struct filedescr _PyImport_DynLoadFiletab[]; extern const struct filedescr _PyImport_DynLoadFiletab[];
extern PyObject *_PyImport_LoadDynamicModule(char *name, char *pathname, extern PyObject *_PyImport_LoadDynamicModule(PyObject *name, PyObject *pathname,
FILE *); FILE *);
/* Max length of module suffix searched for -- accommodates "module.slb" */ /* Max length of module suffix searched for -- accommodates "module.slb" */