Commit c02b41b1 authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-38353: getpath.c: allocates strings on the heap (GH-16585)

* _Py_FindEnvConfigValue() now returns a string allocated
  by PyMem_RawMalloc().
* calculate_init() now decodes VPATH macro.
* Add calculate_open_pyenv() function.
* Add substring() and joinpath2() functions.

* Fix add_exe_suffix()

And a few cleanup changes.
parent abd7cd85
...@@ -56,11 +56,10 @@ extern PyStatus _PyPathConfig_Calculate( ...@@ -56,11 +56,10 @@ extern PyStatus _PyPathConfig_Calculate(
extern int _PyPathConfig_ComputeSysPath0( extern int _PyPathConfig_ComputeSysPath0(
const PyWideStringList *argv, const PyWideStringList *argv,
PyObject **path0); PyObject **path0);
extern int _Py_FindEnvConfigValue( extern PyStatus _Py_FindEnvConfigValue(
FILE *env_file, FILE *env_file,
const wchar_t *key, const wchar_t *key,
wchar_t *value, wchar_t **value_p);
size_t value_size);
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
extern wchar_t* _Py_GetDLLPath(void); extern wchar_t* _Py_GetDLLPath(void);
......
This diff is collapsed.
...@@ -752,7 +752,7 @@ calculate_pth_file(PyCalculatePath *calculate, _PyPathConfig *pathconfig, ...@@ -752,7 +752,7 @@ calculate_pth_file(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
executable's directory and then in the parent directory. executable's directory and then in the parent directory.
If found, open it for use when searching for prefixes. If found, open it for use when searching for prefixes.
*/ */
static void static PyStatus
calculate_pyvenv_file(PyCalculatePath *calculate, calculate_pyvenv_file(PyCalculatePath *calculate,
wchar_t *argv0_path, size_t argv0_path_len) wchar_t *argv0_path, size_t argv0_path_len)
{ {
...@@ -775,17 +775,23 @@ calculate_pyvenv_file(PyCalculatePath *calculate, ...@@ -775,17 +775,23 @@ calculate_pyvenv_file(PyCalculatePath *calculate,
env_file = _Py_wfopen(filename, L"r"); env_file = _Py_wfopen(filename, L"r");
if (env_file == NULL) { if (env_file == NULL) {
errno = 0; errno = 0;
return; return _PyStatus_OK();
} }
} }
/* Look for a 'home' variable and set argv0_path to it, if found */ /* Look for a 'home' variable and set argv0_path to it, if found */
wchar_t home[MAXPATHLEN+1]; wchar_t *home = NULL;
if (_Py_FindEnvConfigValue(env_file, L"home", PyStatus status = _Py_FindEnvConfigValue(env_file, L"home", &home);
home, Py_ARRAY_LENGTH(home))) { if (_PyStatus_EXCEPTION(status)) {
fclose(env_file);
return status;
}
if (home) {
wcscpy_s(argv0_path, argv0_path_len, home); wcscpy_s(argv0_path, argv0_path_len, home);
PyMem_RawFree(home);
} }
fclose(env_file); fclose(env_file);
return _PyStatus_OK();
} }
...@@ -1022,7 +1028,11 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig) ...@@ -1022,7 +1028,11 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
goto done; goto done;
} }
calculate_pyvenv_file(calculate, argv0_path, Py_ARRAY_LENGTH(argv0_path)); status = calculate_pyvenv_file(calculate,
argv0_path, Py_ARRAY_LENGTH(argv0_path));
if (_PyStatus_EXCEPTION(status)) {
return status;
}
/* Calculate zip archive path from DLL or exe path */ /* Calculate zip archive path from DLL or exe path */
wchar_t zip_path[MAXPATHLEN+1]; wchar_t zip_path[MAXPATHLEN+1];
......
...@@ -777,12 +777,17 @@ _PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p) ...@@ -777,12 +777,17 @@ _PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p)
#endif #endif
/* Search for a prefix value in an environment file (pyvenv.cfg). /* Search for a prefix value in an environment file (pyvenv.cfg).
If found, copy it into the provided buffer. */
int - If found, copy it into *value_p: string which must be freed by
PyMem_RawFree().
- If not found, *value_p is set to NULL.
*/
PyStatus
_Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key, _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key,
wchar_t *value, size_t value_size) wchar_t **value_p)
{ {
int result = 0; /* meaning not found */ *value_p = NULL;
char buffer[MAXPATHLEN * 2 + 1]; /* allow extra for key, '=', etc. */ char buffer[MAXPATHLEN * 2 + 1]; /* allow extra for key, '=', etc. */
buffer[Py_ARRAY_LENGTH(buffer)-1] = '\0'; buffer[Py_ARRAY_LENGTH(buffer)-1] = '\0';
...@@ -812,18 +817,24 @@ _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key, ...@@ -812,18 +817,24 @@ _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key,
if ((tok != NULL) && !wcscmp(tok, L"=")) { if ((tok != NULL) && !wcscmp(tok, L"=")) {
tok = WCSTOK(NULL, L"\r\n", &state); tok = WCSTOK(NULL, L"\r\n", &state);
if (tok != NULL) { if (tok != NULL) {
wcsncpy(value, tok, value_size - 1); *value_p = _PyMem_RawWcsdup(tok);
value[value_size - 1] = L'\0';
result = 1;
PyMem_RawFree(tmpbuffer); PyMem_RawFree(tmpbuffer);
break;
if (*value_p == NULL) {
return _PyStatus_NO_MEMORY();
}
/* found */
return _PyStatus_OK();
} }
} }
} }
PyMem_RawFree(tmpbuffer); PyMem_RawFree(tmpbuffer);
} }
} }
return result;
/* not found */
return _PyStatus_OK();
} }
#ifdef __cplusplus #ifdef __cplusplus
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment