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);