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.
This commit is contained in:
Victor Stinner 2019-03-19 01:46:25 +01:00 committed by GitHub
parent 7b14f0c02c
commit 5f9cf23502
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 16 deletions

View File

@ -30,7 +30,8 @@ PyAPI_FUNC(int) _Py_EncodeUTF8Ex(
PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape( PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape(
const char *arg, const char *arg,
Py_ssize_t arglen); Py_ssize_t arglen,
size_t *wlen);
PyAPI_FUNC(int) _Py_GetForceASCII(void); PyAPI_FUNC(int) _Py_GetForceASCII(void);

View File

@ -0,0 +1,2 @@
Python initialization now fails if decoding ``pybuilddir.txt`` configuration
file fails at startup.

View File

@ -563,23 +563,27 @@ search_for_exec_prefix(const _PyCoreConfig *core_config,
} }
else { else {
char buf[MAXPATHLEN+1]; char buf[MAXPATHLEN+1];
wchar_t *rel_builddir_path;
n = fread(buf, 1, MAXPATHLEN, f); n = fread(buf, 1, MAXPATHLEN, f);
buf[n] = '\0'; buf[n] = '\0';
fclose(f); 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; size_t dec_len;
return _Py_INIT_OK(); 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();
} }
} }

View File

@ -5064,12 +5064,21 @@ _Py_DecodeUTF8Ex(const char *s, Py_ssize_t size, wchar_t **wstr, size_t *wlen,
return 0; return 0;
} }
wchar_t* 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; 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) { if (res != 0) {
/* _Py_DecodeUTF8Ex() must support _Py_ERROR_SURROGATEESCAPE */
assert(res != -3);
if (wlen) {
*wlen = (size_t)res;
}
return NULL; return NULL;
} }
return wstr; return wstr;

View File

@ -712,7 +712,7 @@ _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key,
continue; continue;
} }
wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n); wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n, NULL);
if (tmpbuffer) { if (tmpbuffer) {
wchar_t * state; wchar_t * state;
wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state); wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state);