]> granicus.if.org Git - python/commitdiff
bpo-36301: Error if decoding pybuilddir.txt fails (GH-12422)
authorVictor Stinner <vstinner@redhat.com>
Tue, 19 Mar 2019 00:46:25 +0000 (01:46 +0100)
committerGitHub <noreply@github.com>
Tue, 19 Mar 2019 00:46:25 +0000 (01:46 +0100)
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.

Include/internal/pycore_fileutils.h
Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst [new file with mode: 0644]
Modules/getpath.c
Objects/unicodeobject.c
Python/pathconfig.c

index 23ae2013c0eeb50dfca97aadec9b50c329910701..bbee58617fd05e45ddc9adf146cf3ebb903e4551 100644 (file)
@@ -30,7 +30,8 @@ PyAPI_FUNC(int) _Py_EncodeUTF8Ex(
 
 PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape(
     const char *arg,
-    Py_ssize_t arglen);
+    Py_ssize_t arglen,
+    size_t *wlen);
 
 PyAPI_FUNC(int) _Py_GetForceASCII(void);
 
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-19-00-54-31.bpo-36301.xvOCJb.rst
new file mode 100644 (file)
index 0000000..84e4b8a
--- /dev/null
@@ -0,0 +1,2 @@
+Python initialization now fails if decoding ``pybuilddir.txt`` configuration
+file fails at startup.
index 4dafc8b24e4678a603f1ef42636fdd7c83f441dc..4364317494943b192b3c8e53e611ccf07063f72c 100644 (file)
@@ -563,23 +563,27 @@ search_for_exec_prefix(const _PyCoreConfig *core_config,
         }
         else {
             char buf[MAXPATHLEN+1];
-            wchar_t *rel_builddir_path;
             n = fread(buf, 1, MAXPATHLEN, f);
             buf[n] = '\0';
             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;
-                return _Py_INIT_OK();
+            size_t dec_len;
+            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();
         }
     }
 
index b3a851a9f8142ba628703a5d43f4f25bff52054f..9d3ed0d18b159e60924295cc5a2fc5ccf59d7dc2 100644 (file)
@@ -5064,12 +5064,21 @@ _Py_DecodeUTF8Ex(const char *s, Py_ssize_t size, wchar_t **wstr, size_t *wlen,
     return 0;
 }
 
+
 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;
-    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) {
+        /* _Py_DecodeUTF8Ex() must support _Py_ERROR_SURROGATEESCAPE */
+        assert(res != -3);
+        if (wlen) {
+            *wlen = (size_t)res;
+        }
         return NULL;
     }
     return wstr;
index 0ee87c42525f49bc5ecd6934b4f44902e9e112c8..87db66b7528c0dc72fac0e3711c877aad1dcb6a9 100644 (file)
@@ -712,7 +712,7 @@ _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key,
             continue;
         }
 
-        wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n);
+        wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n, NULL);
         if (tmpbuffer) {
             wchar_t * state;
             wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state);