Skip to content

Commit 65b7eff

Browse files
author
Victor Stinner
committed
_PyImport_LoadDynamicModule() encodes the module name explicitly to ASCII
The name must be encodable to ASCII because dynamic module must have a function called "PyInit_NAME", they are written in C, and the C language doesn't accept non-ASCII identifiers.
1 parent 7bba62f commit 65b7eff

1 file changed

Lines changed: 25 additions & 15 deletions

File tree

‎Python/importdl.c‎

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,36 @@ extern dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
2020
const char *pathname, FILE *fp);
2121
#endif
2222

23-
/* name should be ASCII only because the C language doesn't accept non-ASCII
24-
identifiers, and dynamic modules are written in C. */
25-
2623
PyObject *
2724
_PyImport_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp)
2825
{
29-
PyObject *m;
26+
PyObject *m = NULL;
3027
#ifndef MS_WINDOWS
3128
PyObject *pathbytes;
3229
#endif
30+
PyObject *nameascii;
3331
char *namestr, *lastdot, *shortname, *packagecontext, *oldcontext;
3432
dl_funcptr p0;
3533
PyObject* (*p)(void);
3634
struct PyModuleDef *def;
3735

38-
namestr = _PyUnicode_AsString(name);
39-
if (namestr == NULL)
40-
return NULL;
41-
4236
m = _PyImport_FindExtensionObject(name, path);
4337
if (m != NULL) {
4438
Py_INCREF(m);
4539
return m;
4640
}
4741

42+
/* name must be encodable to ASCII because dynamic module must have a
43+
function called "PyInit_NAME", they are written in C, and the C language
44+
doesn't accept non-ASCII identifiers. */
45+
nameascii = PyUnicode_AsEncodedString(name, "ascii", NULL);
46+
if (nameascii == NULL)
47+
return NULL;
48+
49+
namestr = PyBytes_AS_STRING(nameascii);
50+
if (namestr == NULL)
51+
goto error;
52+
4853
lastdot = strrchr(namestr, '.');
4954
if (lastdot == NULL) {
5055
packagecontext = NULL;
@@ -60,34 +65,33 @@ _PyImport_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp)
6065
#else
6166
pathbytes = PyUnicode_EncodeFSDefault(path);
6267
if (pathbytes == NULL)
63-
return NULL;
68+
goto error;
6469
p0 = _PyImport_GetDynLoadFunc(shortname,
6570
PyBytes_AS_STRING(pathbytes), fp);
6671
Py_DECREF(pathbytes);
6772
#endif
6873
p = (PyObject*(*)(void))p0;
6974
if (PyErr_Occurred())
70-
return NULL;
75+
goto error;
7176
if (p == NULL) {
7277
PyErr_Format(PyExc_ImportError,
7378
"dynamic module does not define init function"
7479
" (PyInit_%s)",
7580
shortname);
76-
return NULL;
81+
goto error;
7782
}
7883
oldcontext = _Py_PackageContext;
7984
_Py_PackageContext = packagecontext;
8085
m = (*p)();
8186
_Py_PackageContext = oldcontext;
8287
if (m == NULL)
83-
return NULL;
88+
goto error;
8489

8590
if (PyErr_Occurred()) {
86-
Py_DECREF(m);
8791
PyErr_Format(PyExc_SystemError,
8892
"initialization of %s raised unreported exception",
8993
shortname);
90-
return NULL;
94+
goto error;
9195
}
9296

9397
/* Remember pointer to module init function. */
@@ -101,12 +105,18 @@ _PyImport_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp)
101105
Py_INCREF(path);
102106

103107
if (_PyImport_FixupExtensionObject(m, name, path) < 0)
104-
return NULL;
108+
goto error;
105109
if (Py_VerboseFlag)
106110
PySys_FormatStderr(
107111
"import %U # dynamically loaded from %R\n",
108112
name, path);
113+
Py_DECREF(nameascii);
109114
return m;
115+
116+
error:
117+
Py_DECREF(nameascii);
118+
Py_XDECREF(m);
119+
return NULL;
110120
}
111121

112122
#endif /* HAVE_DYNAMIC_LOADING */

0 commit comments

Comments
 (0)