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:
parent
7b14f0c02c
commit
5f9cf23502
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Python initialization now fails if decoding ``pybuilddir.txt`` configuration
|
||||||
|
file fails at startup.
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue