diff options
author | Kevin Adler <kadler@us.ibm.com> | 2020-10-15 01:53:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-15 01:53:27 (GMT) |
commit | 2d2af320d94afc6561e8f8adf174c9d3fd9065bc (patch) | |
tree | a07d903e46e157773c58f3682ee7886685ab04d6 /Python/dynload_aix.c | |
parent | c13b847a6f913b72eeb71651ff626390b738d973 (diff) | |
download | cpython-2d2af320d94afc6561e8f8adf174c9d3fd9065bc.zip cpython-2d2af320d94afc6561e8f8adf174c9d3fd9065bc.tar.gz cpython-2d2af320d94afc6561e8f8adf174c9d3fd9065bc.tar.bz2 |
bpo-41894: Fix UnicodeDecodeError while loading native module (GH-22466)
When running in a non-UTF-8 locale, if an error occurs while importing a
native Python module (say because a dependent share library is missing),
the error message string returned may contain non-ASCII code points
causing a UnicodeDecodeError.
PyUnicode_DecodeFSDefault is used for buffers which may contain
filesystem paths. For consistency with os.strerror(),
PyUnicode_DecodeLocale is used for buffers which contain system error
messages. While the shortname parameter is always encoded in ASCII
according to PEP 489, it is left decoded using PyUnicode_FromString to
minimize the changes and since it should not affect the decoding (albeit
_potentially_ slower).
In dynload_hpux, since the error buffer contains a message generated
from a static ASCII string and the module filesystem path,
PyUnicode_DecodeFSDefault is used instead of PyUnicode_DecodeLocale as
is used elsewhere.
* bpo-41894: Fix bugs in dynload error msg handling
For both dynload_aix and dynload_hpux, properly handle the possibility
that decoding strings may return NULL and when such an error happens,
properly decrement any previously decoded strings and return early.
In addition, in dynload_aix, ensure that we pass the decoded string
*object* pathname_ob to PyErr_SetImportError instead of the original
pathname buffer.
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Python/dynload_aix.c')
-rw-r--r-- | Python/dynload_aix.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/Python/dynload_aix.c b/Python/dynload_aix.c index 684f10a..97f7698 100644 --- a/Python/dynload_aix.c +++ b/Python/dynload_aix.c @@ -144,10 +144,16 @@ aix_loaderror(const char *pathname) ERRBUF_APPEND(message[i]); ERRBUF_APPEND("\n"); } - errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */ - pathname_ob = PyUnicode_FromString(pathname); - errbuf_ob = PyUnicode_FromString(errbuf); - PyErr_SetImportError(errbuf_ob, NULL, pathname); + /* Subtract 1 from the length to trim off trailing newline */ + errbuf_ob = PyUnicode_DecodeLocaleAndSize(errbuf, strlen(errbuf)-1, "surrogateescape"); + if (errbuf_ob == NULL) + return; + pathname_ob = PyUnicode_DecodeFSDefault(pathname); + if (pathname_ob == NULL) { + Py_DECREF(errbuf_ob); + return; + } + PyErr_SetImportError(errbuf_ob, NULL, pathname_ob); Py_DECREF(pathname_ob); Py_DECREF(errbuf_ob); return; |