Skip to content

Commit fefd70c

Browse files
author
Victor Stinner
committed
Issue python#3080: _PyImport_LoadDynamicModule() uses Unicode for name and path
Document also that dynamic module names are ASCII only
1 parent 4d6c1c4 commit fefd70c

File tree

3 files changed

+60
-66
lines changed

3 files changed

+60
-66
lines changed

Python/import.c

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,9 +2173,21 @@ load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
21732173
break;
21742174

21752175
#ifdef HAVE_DYNAMIC_LOADING
2176-
case C_EXTENSION:
2177-
m = _PyImport_LoadDynamicModule(name, pathname, fp);
2176+
case C_EXTENSION: {
2177+
PyObject *nameobj, *pathobj;
2178+
nameobj = PyUnicode_FromString(name);
2179+
if (nameobj == NULL)
2180+
return NULL;
2181+
pathobj = PyUnicode_DecodeFSDefault(pathname);
2182+
if (pathobj == NULL) {
2183+
Py_DECREF(nameobj);
2184+
return NULL;
2185+
}
2186+
m = _PyImport_LoadDynamicModule(nameobj, pathobj, fp);
2187+
Py_DECREF(nameobj);
2188+
Py_DECREF(pathobj);
21782189
break;
2190+
}
21792191
#endif
21802192

21812193
case PKG_DIRECTORY:
@@ -2185,11 +2197,10 @@ load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
21852197
case C_BUILTIN:
21862198
case PY_FROZEN: {
21872199
PyObject *nameobj = PyUnicode_FromString(name);
2188-
if (nameobj != NULL) {
2189-
m = load_builtin(nameobj, type);
2190-
Py_DECREF(nameobj);
2191-
} else
2192-
m = NULL;
2200+
if (nameobj == NULL)
2201+
return NULL;
2202+
m = load_builtin(nameobj, type);
2203+
Py_DECREF(nameobj);
21932204
break;
21942205
}
21952206

@@ -3443,28 +3454,23 @@ imp_load_compiled(PyObject *self, PyObject *args)
34433454
static PyObject *
34443455
imp_load_dynamic(PyObject *self, PyObject *args)
34453456
{
3446-
char *name;
3447-
PyObject *pathbytes;
3448-
char *pathname;
3449-
PyObject *fob = NULL;
3450-
PyObject *m;
3451-
FILE *fp = NULL;
3452-
if (!PyArg_ParseTuple(args, "sO&|O:load_dynamic",
3453-
&name, PyUnicode_FSConverter, &pathbytes, &fob))
3457+
PyObject *name, *pathname, *fob = NULL, *mod;
3458+
FILE *fp;
3459+
3460+
if (!PyArg_ParseTuple(args, "UO&|O:load_dynamic",
3461+
&name, PyUnicode_FSDecoder, &pathname, &fob))
34543462
return NULL;
3455-
pathname = PyBytes_AS_STRING(pathbytes);
3456-
if (fob) {
3457-
fp = get_file(pathname, fob, "r");
3458-
if (fp == NULL) {
3459-
Py_DECREF(pathbytes);
3463+
if (fob != NULL) {
3464+
fp = get_file(NULL, fob, "r");
3465+
if (fp == NULL)
34603466
return NULL;
3461-
}
34623467
}
3463-
m = _PyImport_LoadDynamicModule(name, pathname, fp);
3464-
Py_DECREF(pathbytes);
3468+
else
3469+
fp = NULL;
3470+
mod = _PyImport_LoadDynamicModule(name, pathname, fp);
34653471
if (fp)
34663472
fclose(fp);
3467-
return m;
3473+
return mod;
34683474
}
34693475

34703476
#endif /* HAVE_DYNAMIC_LOADING */

Python/importdl.c

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,67 +15,68 @@
1515
extern dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
1616
const char *pathname, FILE *fp);
1717

18-
18+
/* name should be ASCII only because the C language doesn't accept non-ASCII
19+
identifiers, and dynamic modules are written in C. */
1920

2021
PyObject *
21-
_PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp)
22+
_PyImport_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp)
2223
{
2324
PyObject *m;
24-
PyObject *path;
25-
char *lastdot, *shortname, *packagecontext, *oldcontext;
25+
PyObject *pathbytes;
26+
char *namestr, *lastdot, *shortname, *packagecontext, *oldcontext;
2627
dl_funcptr p0;
2728
PyObject* (*p)(void);
2829
struct PyModuleDef *def;
29-
PyObject *nameobj, *result;
3030

31-
path = PyUnicode_DecodeFSDefault(pathname);
32-
if (path == NULL)
31+
namestr = _PyUnicode_AsString(name);
32+
if (namestr == NULL)
3333
return NULL;
3434

35-
nameobj = PyUnicode_FromString(name);
36-
if (nameobj == NULL)
37-
return NULL;
38-
m = _PyImport_FindExtensionObject(nameobj, path);
35+
m = _PyImport_FindExtensionObject(name, path);
3936
if (m != NULL) {
40-
Py_DECREF(nameobj);
4137
Py_INCREF(m);
42-
result = m;
43-
goto finally;
38+
return m;
4439
}
45-
Py_DECREF(nameobj);
46-
lastdot = strrchr(name, '.');
40+
41+
lastdot = strrchr(namestr, '.');
4742
if (lastdot == NULL) {
4843
packagecontext = NULL;
49-
shortname = name;
44+
shortname = namestr;
5045
}
5146
else {
52-
packagecontext = name;
47+
packagecontext = namestr;
5348
shortname = lastdot+1;
5449
}
5550

56-
p0 = _PyImport_GetDynLoadFunc(shortname, pathname, fp);
51+
pathbytes = PyUnicode_EncodeFSDefault(path);
52+
if (pathbytes == NULL)
53+
return NULL;
54+
p0 = _PyImport_GetDynLoadFunc(shortname,
55+
PyBytes_AS_STRING(pathbytes), fp);
56+
Py_DECREF(pathbytes);
5757
p = (PyObject*(*)(void))p0;
5858
if (PyErr_Occurred())
59-
goto error;
59+
return NULL;
6060
if (p == NULL) {
6161
PyErr_Format(PyExc_ImportError,
62-
"dynamic module does not define init function (PyInit_%.200s)",
62+
"dynamic module does not define init function"
63+
" (PyInit_%s)",
6364
shortname);
64-
goto error;
65+
return NULL;
6566
}
6667
oldcontext = _Py_PackageContext;
6768
_Py_PackageContext = packagecontext;
6869
m = (*p)();
6970
_Py_PackageContext = oldcontext;
7071
if (m == NULL)
71-
goto error;
72+
return NULL;
7273

7374
if (PyErr_Occurred()) {
7475
Py_DECREF(m);
7576
PyErr_Format(PyExc_SystemError,
7677
"initialization of %s raised unreported exception",
7778
shortname);
78-
goto error;
79+
return NULL;
7980
}
8081

8182
/* Remember pointer to module init function. */
@@ -88,26 +89,13 @@ _PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp)
8889
else
8990
Py_INCREF(path);
9091

91-
nameobj = PyUnicode_FromString(name);
92-
if (nameobj == NULL)
92+
if (_PyImport_FixupExtensionObject(m, name, path) < 0)
9393
return NULL;
94-
if (_PyImport_FixupExtensionObject(m, nameobj, path) < 0) {
95-
Py_DECREF(nameobj);
96-
goto error;
97-
}
9894
if (Py_VerboseFlag)
9995
PySys_FormatStderr(
100-
"import %U # dynamically loaded from %s\n",
101-
nameobj, pathname);
102-
Py_DECREF(nameobj);
103-
result = m;
104-
goto finally;
105-
106-
error:
107-
result = NULL;
108-
finally:
109-
Py_DECREF(path);
110-
return result;
96+
"import %U # dynamically loaded from %R\n",
97+
name, path);
98+
return m;
11199
}
112100

113101
#endif /* HAVE_DYNAMIC_LOADING */

Python/importdl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct filedescr {
2828
extern struct filedescr * _PyImport_Filetab;
2929
extern const struct filedescr _PyImport_DynLoadFiletab[];
3030

31-
extern PyObject *_PyImport_LoadDynamicModule(char *name, char *pathname,
31+
extern PyObject *_PyImport_LoadDynamicModule(PyObject *name, PyObject *pathname,
3232
FILE *);
3333

3434
/* Max length of module suffix searched for -- accommodates "module.slb" */

0 commit comments

Comments
 (0)