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.
This commit is contained in:
parent
abd7cd856b
commit
c02b41b1fb
|
@ -56,11 +56,10 @@ extern PyStatus _PyPathConfig_Calculate(
|
|||
extern int _PyPathConfig_ComputeSysPath0(
|
||||
const PyWideStringList *argv,
|
||||
PyObject **path0);
|
||||
extern int _Py_FindEnvConfigValue(
|
||||
extern PyStatus _Py_FindEnvConfigValue(
|
||||
FILE *env_file,
|
||||
const wchar_t *key,
|
||||
wchar_t *value,
|
||||
size_t value_size);
|
||||
wchar_t **value_p);
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
extern wchar_t* _Py_GetDLLPath(void);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -752,7 +752,7 @@ calculate_pth_file(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
|||
executable's directory and then in the parent directory.
|
||||
If found, open it for use when searching for prefixes.
|
||||
*/
|
||||
static void
|
||||
static PyStatus
|
||||
calculate_pyvenv_file(PyCalculatePath *calculate,
|
||||
wchar_t *argv0_path, size_t argv0_path_len)
|
||||
{
|
||||
|
@ -775,17 +775,23 @@ calculate_pyvenv_file(PyCalculatePath *calculate,
|
|||
env_file = _Py_wfopen(filename, L"r");
|
||||
if (env_file == NULL) {
|
||||
errno = 0;
|
||||
return;
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for a 'home' variable and set argv0_path to it, if found */
|
||||
wchar_t home[MAXPATHLEN+1];
|
||||
if (_Py_FindEnvConfigValue(env_file, L"home",
|
||||
home, Py_ARRAY_LENGTH(home))) {
|
||||
wchar_t *home = NULL;
|
||||
PyStatus status = _Py_FindEnvConfigValue(env_file, L"home", &home);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
fclose(env_file);
|
||||
return status;
|
||||
}
|
||||
if (home) {
|
||||
wcscpy_s(argv0_path, argv0_path_len, home);
|
||||
PyMem_RawFree(home);
|
||||
}
|
||||
fclose(env_file);
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1022,7 +1028,11 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|||
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 */
|
||||
wchar_t zip_path[MAXPATHLEN+1];
|
||||
|
|
|
@ -777,12 +777,17 @@ _PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p)
|
|||
#endif
|
||||
|
||||
/* 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,
|
||||
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. */
|
||||
buffer[Py_ARRAY_LENGTH(buffer)-1] = '\0';
|
||||
|
||||
|
@ -812,18 +817,24 @@ _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key,
|
|||
if ((tok != NULL) && !wcscmp(tok, L"=")) {
|
||||
tok = WCSTOK(NULL, L"\r\n", &state);
|
||||
if (tok != NULL) {
|
||||
wcsncpy(value, tok, value_size - 1);
|
||||
value[value_size - 1] = L'\0';
|
||||
result = 1;
|
||||
*value_p = _PyMem_RawWcsdup(tok);
|
||||
PyMem_RawFree(tmpbuffer);
|
||||
break;
|
||||
|
||||
if (*value_p == NULL) {
|
||||
return _PyStatus_NO_MEMORY();
|
||||
}
|
||||
|
||||
/* found */
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
}
|
||||
}
|
||||
PyMem_RawFree(tmpbuffer);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
/* not found */
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
Loading…
Reference in New Issue