bpo-36301: Error if decoding pybuilddir.txt fails (GH-12422) · python/cpython@5f9cf23

GitHub

Original file line numberDiff line numberDiff line change@@ -30,7 +30,8 @@ PyAPI_FUNC(int) _Py_EncodeUTF8Ex(

30303131PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape(

3232constchar*arg,

33-Py_ssize_targlen);

33+Py_ssize_targlen,

34+size_t*wlen);

34353536PyAPI_FUNC(int) _Py_GetForceASCII(void);

3637Original file line numberDiff line numberDiff line change@@ -0,0 +1,2 @@

1+Python initialization now fails if decoding ``pybuilddir.txt`` configuration

2+file fails at startup.

Original file line numberDiff line numberDiff line change@@ -563,23 +563,27 @@ search_for_exec_prefix(const _PyCoreConfig *core_config,

563563 }

564564else {

565565charbuf[MAXPATHLEN+1];

566-wchar_t*rel_builddir_path;

567566n=fread(buf, 1, MAXPATHLEN, f);

568567buf[n] ='\0';

569568fclose(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-returnerr;

578- }

579569580-*found=-1;

581-return_Py_INIT_OK();

570+size_tdec_len;

571+wchar_t*pybuilddir;

572+pybuilddir=_Py_DecodeUTF8_surrogateescape(buf, n, &dec_len);

573+if (!pybuilddir) {

574+returnDECODE_LOCALE_ERR("pybuilddir.txt", dec_len);

582575 }

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+returnerr;

583+ }

584+585+*found=-1;

586+return_Py_INIT_OK();

583587 }

584588 }

585589Original file line numberDiff line numberDiff line change@@ -5064,12 +5064,21 @@ _Py_DecodeUTF8Ex(const char *s, Py_ssize_t size, wchar_t **wstr, size_t *wlen,

50645064return0;

50655065}

506650665067+50675068wchar_t*

5068-_Py_DecodeUTF8_surrogateescape(constchar*arg, Py_ssize_targlen)

5069+_Py_DecodeUTF8_surrogateescape(constchar*arg, Py_ssize_targlen,

5070+size_t*wlen)

50695071{

50705072wchar_t*wstr;

5071-intres=_Py_DecodeUTF8Ex(arg, arglen, &wstr, NULL, NULL, 1);

5073+intres=_Py_DecodeUTF8Ex(arg, arglen,

5074+&wstr, wlen,

5075+NULL, _Py_ERROR_SURROGATEESCAPE);

50725076if (res!=0) {

5077+/* _Py_DecodeUTF8Ex() must support _Py_ERROR_SURROGATEESCAPE */

5078+assert(res!=-3);

5079+if (wlen) {

5080+*wlen= (size_t)res;

5081+ }

50735082returnNULL;

50745083 }

50755084returnwstr;

Original file line numberDiff line numberDiff line change@@ -712,7 +712,7 @@ _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key,

712712continue;

713713 }

714714715-wchar_t*tmpbuffer=_Py_DecodeUTF8_surrogateescape(buffer, n);

715+wchar_t*tmpbuffer=_Py_DecodeUTF8_surrogateescape(buffer, n, NULL);

716716if (tmpbuffer) {

717717wchar_t*state;

718718wchar_t*tok=WCSTOK(tmpbuffer, L" \t\r\n", &state);