bpo-36301: Error if decoding pybuilddir.txt fails (GH-12422) · python/cpython@5f9cf23 (original) (raw)
5 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -30,7 +30,8 @@ PyAPI_FUNC(int) _Py_EncodeUTF8Ex( | ||
30 | 30 | |
31 | 31 | PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape( |
32 | 32 | const char *arg, |
33 | -Py_ssize_t arglen); | |
33 | +Py_ssize_t arglen, | |
34 | +size_t *wlen); | |
34 | 35 | |
35 | 36 | PyAPI_FUNC(int) _Py_GetForceASCII(void); |
36 | 37 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
1 | +Python initialization now fails if decoding ``pybuilddir.txt`` configuration | |
2 | +file fails at startup. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -563,23 +563,27 @@ search_for_exec_prefix(const _PyCoreConfig *core_config, | ||
563 | 563 | } |
564 | 564 | else { |
565 | 565 | char buf[MAXPATHLEN+1]; |
566 | -wchar_t *rel_builddir_path; | |
567 | 566 | n = fread(buf, 1, MAXPATHLEN, f); |
568 | 567 | buf[n] = '\0'; |
569 | 568 | fclose(f); |
570 | -rel_builddir_path = _Py_DecodeUTF8_surrogateescape(buf, n); | |
571 | -if (rel_builddir_path) { | |
572 | -wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN); | |
573 | -exec_prefix[MAXPATHLEN] = L'\0'; | |
574 | -err = joinpath(exec_prefix, rel_builddir_path); | |
575 | -PyMem_RawFree(rel_builddir_path ); | |
576 | -if (_Py_INIT_FAILED(err)) { | |
577 | -return err; | |
578 | - } | |
579 | 569 | |
580 | -*found = -1; | |
581 | -return _Py_INIT_OK(); | |
570 | +size_t dec_len; | |
571 | +wchar_t *pybuilddir; | |
572 | +pybuilddir = _Py_DecodeUTF8_surrogateescape(buf, n, &dec_len); | |
573 | +if (!pybuilddir) { | |
574 | +return DECODE_LOCALE_ERR("pybuilddir.txt", dec_len); | |
582 | 575 | } |
576 | + | |
577 | +wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN); | |
578 | +exec_prefix[MAXPATHLEN] = L'\0'; | |
579 | +err = joinpath(exec_prefix, pybuilddir); | |
580 | +PyMem_RawFree(pybuilddir ); | |
581 | +if (_Py_INIT_FAILED(err)) { | |
582 | +return err; | |
583 | + } | |
584 | + | |
585 | +*found = -1; | |
586 | +return _Py_INIT_OK(); | |
583 | 587 | } |
584 | 588 | } |
585 | 589 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -5064,12 +5064,21 @@ _Py_DecodeUTF8Ex(const char *s, Py_ssize_t size, wchar_t **wstr, size_t *wlen, | ||
5064 | 5064 | return 0; |
5065 | 5065 | } |
5066 | 5066 | |
5067 | + | |
5067 | 5068 | wchar_t* |
5068 | -_Py_DecodeUTF8_surrogateescape(const char *arg, Py_ssize_t arglen) | |
5069 | +_Py_DecodeUTF8_surrogateescape(const char *arg, Py_ssize_t arglen, | |
5070 | +size_t *wlen) | |
5069 | 5071 | { |
5070 | 5072 | wchar_t *wstr; |
5071 | -int res = _Py_DecodeUTF8Ex(arg, arglen, &wstr, NULL, NULL, 1); | |
5073 | +int res = _Py_DecodeUTF8Ex(arg, arglen, | |
5074 | +&wstr, wlen, | |
5075 | +NULL, _Py_ERROR_SURROGATEESCAPE); | |
5072 | 5076 | if (res != 0) { |
5077 | +/* _Py_DecodeUTF8Ex() must support _Py_ERROR_SURROGATEESCAPE */ | |
5078 | +assert(res != -3); | |
5079 | +if (wlen) { | |
5080 | +*wlen = (size_t)res; | |
5081 | + } | |
5073 | 5082 | return NULL; |
5074 | 5083 | } |
5075 | 5084 | return wstr; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -712,7 +712,7 @@ _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key, | ||
712 | 712 | continue; |
713 | 713 | } |
714 | 714 | |
715 | -wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n); | |
715 | +wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n, NULL); | |
716 | 716 | if (tmpbuffer) { |
717 | 717 | wchar_t * state; |
718 | 718 | wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state); |