summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-03-19 01:46:25 +0100
committerGitHub <noreply@github.com>2019-03-19 01:46:25 +0100
commit5f9cf23502febe0eb3bc02e45c7d2bfc79424757 (patch)
tree66e3e75c52201876c33fb90c9036420687f60dfb
parent7b14f0c02ce9d919c503119db190dbca0e703393 (diff)
downloadcpython-git-5f9cf23502febe0eb3bc02e45c7d2bfc79424757.tar.gz
bpo-36301: Error if decoding pybuilddir.txt fails (GH-12422)
Python initialization now fails if decoding pybuilddir.txt configuration file fails at startup. _PyPathConfig_Calculate() now reports memory allocation failure and decoding error on decoding pybuilddir.txt content from UTF-8/surrogateescape.
-rw-r--r--Include/internal/pycore_fileutils.h3
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst2
-rw-r--r--Modules/getpath.c28
-rw-r--r--Objects/unicodeobject.c13
-rw-r--r--Python/pathconfig.c2
5 files changed, 32 insertions, 16 deletions
diff --git a/Include/internal/pycore_fileutils.h b/Include/internal/pycore_fileutils.h
index 23ae2013c0..bbee58617f 100644
--- a/Include/internal/pycore_fileutils.h
+++ b/Include/internal/pycore_fileutils.h
@@ -30,7 +30,8 @@ PyAPI_FUNC(int) _Py_EncodeUTF8Ex(
PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape(
const char *arg,
- Py_ssize_t arglen);
+ Py_ssize_t arglen,
+ size_t *wlen);
PyAPI_FUNC(int) _Py_GetForceASCII(void);
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst
new file mode 100644
index 0000000000..84e4b8a852
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst
@@ -0,0 +1,2 @@
+Python initialization now fails if decoding ``pybuilddir.txt`` configuration
+file fails at startup.
diff --git a/Modules/getpath.c b/Modules/getpath.c
index 4dafc8b24e..4364317494 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -563,23 +563,27 @@ search_for_exec_prefix(const _PyCoreConfig *core_config,
}
else {
char buf[MAXPATHLEN+1];
- wchar_t *rel_builddir_path;
n = fread(buf, 1, MAXPATHLEN, f);
buf[n] = '\0';
fclose(f);
- rel_builddir_path = _Py_DecodeUTF8_surrogateescape(buf, n);
- if (rel_builddir_path) {
- wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
- exec_prefix[MAXPATHLEN] = L'\0';
- err = joinpath(exec_prefix, rel_builddir_path);
- PyMem_RawFree(rel_builddir_path );
- if (_Py_INIT_FAILED(err)) {
- return err;
- }
- *found = -1;
- return _Py_INIT_OK();
+ size_t dec_len;
+ wchar_t *pybuilddir;
+ pybuilddir = _Py_DecodeUTF8_surrogateescape(buf, n, &dec_len);
+ if (!pybuilddir) {
+ return DECODE_LOCALE_ERR("pybuilddir.txt", dec_len);
}
+
+ wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
+ exec_prefix[MAXPATHLEN] = L'\0';
+ err = joinpath(exec_prefix, pybuilddir);
+ PyMem_RawFree(pybuilddir );
+ if (_Py_INIT_FAILED(err)) {
+ return err;
+ }
+
+ *found = -1;
+ return _Py_INIT_OK();
}
}
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index b3a851a9f8..9d3ed0d18b 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -5064,12 +5064,21 @@ _Py_DecodeUTF8Ex(const char *s, Py_ssize_t size, wchar_t **wstr, size_t *wlen,
return 0;
}
+
wchar_t*
-_Py_DecodeUTF8_surrogateescape(const char *arg, Py_ssize_t arglen)
+_Py_DecodeUTF8_surrogateescape(const char *arg, Py_ssize_t arglen,
+ size_t *wlen)
{
wchar_t *wstr;
- int res = _Py_DecodeUTF8Ex(arg, arglen, &wstr, NULL, NULL, 1);
+ int res = _Py_DecodeUTF8Ex(arg, arglen,
+ &wstr, wlen,
+ NULL, _Py_ERROR_SURROGATEESCAPE);
if (res != 0) {
+ /* _Py_DecodeUTF8Ex() must support _Py_ERROR_SURROGATEESCAPE */
+ assert(res != -3);
+ if (wlen) {
+ *wlen = (size_t)res;
+ }
return NULL;
}
return wstr;
diff --git a/Python/pathconfig.c b/Python/pathconfig.c
index 0ee87c4252..87db66b752 100644
--- a/Python/pathconfig.c
+++ b/Python/pathconfig.c
@@ -712,7 +712,7 @@ _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key,
continue;
}
- wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n);
+ wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n, NULL);
if (tmpbuffer) {
wchar_t * state;
wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state);