diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-09-23 17:50:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-23 17:50:27 (GMT) |
commit | 3f5409a3f13c59baa34656bccefdc3728e46c9ef (patch) | |
tree | 4c8ccb6d3ab77b882186bdcaa6af208e7cc9db30 /Modules/getpath.c | |
parent | c5c642565e260477ae2fb29d0c86a91e19702ae3 (diff) | |
download | cpython-3f5409a3f13c59baa34656bccefdc3728e46c9ef.zip cpython-3f5409a3f13c59baa34656bccefdc3728e46c9ef.tar.gz cpython-3f5409a3f13c59baa34656bccefdc3728e46c9ef.tar.bz2 |
bpo-38234: Fix _PyConfig_InitPathConfig() (GH-16335) (GH-16336)
* _PyConfig_InitPathConfig() now starts by copying the global path
configuration, and then override values set in PyConfig.
* _PyPathConfig_Calculate() implementations no longer override
_PyPathConfig fields which are already computed. For example,
if _PyPathConfig.prefix is not NULL, leave it unchanged.
* If Py_SetPath() has been called, _PyConfig_InitPathConfig() doesn't
call _PyPathConfig_Calculate() anymore.
* _PyPathConfig_Calculate() no longer uses PyConfig,
except to initialize PyCalculatePath structure.
* pathconfig_calculate(): remove useless temporary
"_PyPathConfig new_config" variable.
* calculate_module_search_path(): remove hack to workaround memory
allocation failure, call Py_FatalError() instead.
* Fix get_program_full_path(): handle memory allocation failure.
(cherry picked from commit 9c42f8cda552694f3b47d6388d4ae84d61731872)
Diffstat (limited to 'Modules/getpath.c')
-rw-r--r-- | Modules/getpath.c | 140 |
1 files changed, 78 insertions, 62 deletions
diff --git a/Modules/getpath.c b/Modules/getpath.c index 5afb5b1..f60fe3c 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -133,6 +133,9 @@ typedef struct { int prefix_found; /* found platform independent libraries? */ int exec_prefix_found; /* found the platform dependent libraries? */ + + int warnings; + const wchar_t *pythonpath_env; } PyCalculatePath; static const wchar_t delimiter[2] = {DELIM, '\0'}; @@ -365,17 +368,16 @@ add_exe_suffix(wchar_t *progpath, size_t progpathlen) bytes long. */ static PyStatus -search_for_prefix(const PyConfig *config, PyCalculatePath *calculate, - wchar_t *prefix, size_t prefix_len, - int *found) +search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + wchar_t *prefix, size_t prefix_len, int *found) { PyStatus status; size_t n; wchar_t *vpath; /* If PYTHONHOME is set, we believe it unconditionally */ - if (config->home) { - if (safe_wcscpy(prefix, config->home, prefix_len) < 0) { + if (pathconfig->home) { + if (safe_wcscpy(prefix, pathconfig->home, prefix_len) < 0) { return PATHLEN_ERR(); } wchar_t *delim = wcschr(prefix, DELIM); @@ -482,19 +484,19 @@ search_for_prefix(const PyConfig *config, PyCalculatePath *calculate, static PyStatus -calculate_prefix(const PyConfig *config, - PyCalculatePath *calculate, wchar_t *prefix, size_t prefix_len) +calculate_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, + wchar_t *prefix, size_t prefix_len) { PyStatus status; - status = search_for_prefix(config, calculate, prefix, prefix_len, - &calculate->prefix_found); + status = search_for_prefix(calculate, pathconfig, prefix, prefix_len, + &calculate->prefix_found); if (_PyStatus_EXCEPTION(status)) { return status; } if (!calculate->prefix_found) { - if (config->pathconfig_warnings) { + if (calculate->warnings) { fprintf(stderr, "Could not find platform independent libraries <prefix>\n"); } @@ -544,8 +546,7 @@ calculate_reduce_prefix(PyCalculatePath *calculate, MAXPATHLEN bytes long. */ static PyStatus -search_for_exec_prefix(const PyConfig *config, - PyCalculatePath *calculate, +search_for_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, wchar_t *exec_prefix, size_t exec_prefix_len, int *found) { @@ -553,15 +554,15 @@ search_for_exec_prefix(const PyConfig *config, size_t n; /* If PYTHONHOME is set, we believe it unconditionally */ - if (config->home) { - wchar_t *delim = wcschr(config->home, DELIM); + if (pathconfig->home) { + wchar_t *delim = wcschr(pathconfig->home, DELIM); if (delim) { if (safe_wcscpy(exec_prefix, delim+1, exec_prefix_len) < 0) { return PATHLEN_ERR(); } } else { - if (safe_wcscpy(exec_prefix, config->home, exec_prefix_len) < 0) { + if (safe_wcscpy(exec_prefix, pathconfig->home, exec_prefix_len) < 0) { return PATHLEN_ERR(); } } @@ -668,21 +669,20 @@ search_for_exec_prefix(const PyConfig *config, static PyStatus -calculate_exec_prefix(const PyConfig *config, - PyCalculatePath *calculate, +calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, wchar_t *exec_prefix, size_t exec_prefix_len) { PyStatus status; - status = search_for_exec_prefix(config, calculate, - exec_prefix, exec_prefix_len, - &calculate->exec_prefix_found); + status = search_for_exec_prefix(calculate, pathconfig, + exec_prefix, exec_prefix_len, + &calculate->exec_prefix_found); if (_PyStatus_EXCEPTION(status)) { return status; } if (!calculate->exec_prefix_found) { - if (config->pathconfig_warnings) { + if (calculate->warnings) { fprintf(stderr, "Could not find platform dependent libraries <exec_prefix>\n"); } @@ -721,8 +721,7 @@ calculate_reduce_exec_prefix(PyCalculatePath *calculate, static PyStatus -calculate_program_full_path(const PyConfig *config, - PyCalculatePath *calculate, _PyPathConfig *pathconfig) +calculate_program_full_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) { PyStatus status; wchar_t program_full_path[MAXPATHLEN + 1]; @@ -743,8 +742,8 @@ calculate_program_full_path(const PyConfig *config, * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ - if (wcschr(config->program_name, SEP)) { - if (safe_wcscpy(program_full_path, config->program_name, + if (wcschr(pathconfig->program_name, SEP)) { + if (safe_wcscpy(program_full_path, pathconfig->program_name, program_full_path_len) < 0) { return PATHLEN_ERR(); } @@ -795,8 +794,8 @@ calculate_program_full_path(const PyConfig *config, } } - status = joinpath(program_full_path, config->program_name, - program_full_path_len); + status = joinpath(program_full_path, pathconfig->program_name, + program_full_path_len); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1030,15 +1029,14 @@ calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix) static PyStatus -calculate_module_search_path(const PyConfig *config, - PyCalculatePath *calculate, - const wchar_t *prefix, const wchar_t *exec_prefix, - _PyPathConfig *pathconfig) +calculate_module_search_path(PyCalculatePath *calculate, + _PyPathConfig *pathconfig, + const wchar_t *prefix, const wchar_t *exec_prefix) { /* Calculate size of return buffer */ size_t bufsz = 0; - if (config->pythonpath_env != NULL) { - bufsz += wcslen(config->pythonpath_env) + 1; + if (calculate->pythonpath_env != NULL) { + bufsz += wcslen(calculate->pythonpath_env) + 1; } wchar_t *defpath = calculate->pythonpath; @@ -1072,8 +1070,8 @@ calculate_module_search_path(const PyConfig *config, buf[0] = '\0'; /* Run-time value of $PYTHONPATH goes first */ - if (config->pythonpath_env) { - wcscpy(buf, config->pythonpath_env); + if (calculate->pythonpath_env) { + wcscpy(buf, calculate->pythonpath_env); wcscat(buf, delimiter); } @@ -1149,6 +1147,10 @@ calculate_init(PyCalculatePath *calculate, if (!calculate->lib_python) { return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); } + + calculate->warnings = config->pathconfig_warnings; + calculate->pythonpath_env = config->pythonpath_env; + return _PyStatus_OK(); } @@ -1165,14 +1167,15 @@ calculate_free(PyCalculatePath *calculate) static PyStatus -calculate_path_impl(const PyConfig *config, - PyCalculatePath *calculate, _PyPathConfig *pathconfig) +calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) { PyStatus status; - status = calculate_program_full_path(config, calculate, pathconfig); - if (_PyStatus_EXCEPTION(status)) { - return status; + if (pathconfig->program_full_path == NULL) { + status = calculate_program_full_path(calculate, pathconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } status = calculate_argv0_path(calculate, pathconfig->program_full_path); @@ -1187,8 +1190,8 @@ calculate_path_impl(const PyConfig *config, wchar_t prefix[MAXPATHLEN+1]; memset(prefix, 0, sizeof(prefix)); - status = calculate_prefix(config, calculate, - prefix, Py_ARRAY_LENGTH(prefix)); + status = calculate_prefix(calculate, pathconfig, + prefix, Py_ARRAY_LENGTH(prefix)); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1200,52 +1203,65 @@ calculate_path_impl(const PyConfig *config, wchar_t exec_prefix[MAXPATHLEN+1]; memset(exec_prefix, 0, sizeof(exec_prefix)); - status = calculate_exec_prefix(config, calculate, - exec_prefix, Py_ARRAY_LENGTH(exec_prefix)); + status = calculate_exec_prefix(calculate, pathconfig, + exec_prefix, Py_ARRAY_LENGTH(exec_prefix)); if (_PyStatus_EXCEPTION(status)) { return status; } if ((!calculate->prefix_found || !calculate->exec_prefix_found) && - config->pathconfig_warnings) + calculate->warnings) { fprintf(stderr, "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); } if (pathconfig->module_search_path == NULL) { - status = calculate_module_search_path(config, calculate, - prefix, exec_prefix, pathconfig); + status = calculate_module_search_path(calculate, pathconfig, + prefix, exec_prefix); if (_PyStatus_EXCEPTION(status)) { return status; } } - status = calculate_reduce_prefix(calculate, prefix, Py_ARRAY_LENGTH(prefix)); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - pathconfig->prefix = _PyMem_RawWcsdup(prefix); if (pathconfig->prefix == NULL) { - return _PyStatus_NO_MEMORY(); - } + status = calculate_reduce_prefix(calculate, prefix, Py_ARRAY_LENGTH(prefix)); + if (_PyStatus_EXCEPTION(status)) { + return status; + } - status = calculate_reduce_exec_prefix(calculate, - exec_prefix, Py_ARRAY_LENGTH(exec_prefix)); - if (_PyStatus_EXCEPTION(status)) { - return status; + pathconfig->prefix = _PyMem_RawWcsdup(prefix); + if (pathconfig->prefix == NULL) { + return _PyStatus_NO_MEMORY(); + } } - pathconfig->exec_prefix = _PyMem_RawWcsdup(exec_prefix); if (pathconfig->exec_prefix == NULL) { - return _PyStatus_NO_MEMORY(); + status = calculate_reduce_exec_prefix(calculate, + exec_prefix, + Py_ARRAY_LENGTH(exec_prefix)); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + pathconfig->exec_prefix = _PyMem_RawWcsdup(exec_prefix); + if (pathconfig->exec_prefix == NULL) { + return _PyStatus_NO_MEMORY(); + } } return _PyStatus_OK(); } +/* Calculate 'pathconfig' attributes: + + - program_full_path + - module_search_path + - prefix + - exec_prefix + + If an attribute is already set (non NULL), it is left unchanged. */ PyStatus _PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config) { @@ -1258,7 +1274,7 @@ _PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config) goto done; } - status = calculate_path_impl(config, &calculate, pathconfig); + status = calculate_path(&calculate, pathconfig); if (_PyStatus_EXCEPTION(status)) { goto done; } |