bpo-45211: Move helpers from getpath.c to internal API. by ericsnowcurrently · Pull Request #28550 · python/cpython
#ifndef LANDMARK # define LANDMARK L"lib\\os.py" #endif
#define INIT_ERR_BUFFER_OVERFLOW() _PyStatus_ERR("buffer overflow")
/* gotlandmark only called by search_for_prefix, which ensures 'prefix' is null terminated in bounds. join() ensures 'landmark' can not overflow prefix if too long. */ static int gotlandmark(const wchar_t *prefix, const wchar_t *landmark) is_stdlibdir(wchar_t *stdlibdir) { wchar_t filename[MAXPATHLEN+1]; memset(filename, 0, sizeof(filename)); wcscpy_s(filename, Py_ARRAY_LENGTH(filename), prefix); join(filename, landmark); return ismodule(filename, FALSE); wchar_t *filename = stdlibdir; #ifndef LANDMARK # define LANDMARK L"os.py" #endif /* join() ensures 'landmark' can not overflow prefix if too long. */ join(filename, LANDMARK); return ismodule(filename); }
/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd. assumption provided by only caller, calculate_path() */ static int search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *landmark) search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path) { /* Search from argv0_path, until landmark is found */ wcscpy_s(prefix, MAXPATHLEN + 1, argv0_path); /* Search from argv0_path, until LANDMARK is found. We guarantee 'prefix' is null terminated in bounds. */ wcscpy_s(prefix, MAXPATHLEN+1, argv0_path); wchar_t stdlibdir[MAXPATHLEN+1]; wcscpy_s(stdlibdir, Py_ARRAY_LENGTH(stdlibdir), prefix); /* We initialize with the longest possible path, in case it doesn't fit. This also gives us an initial SEP at stdlibdir[wcslen(prefix)]. */ join(stdlibdir, L"lib"); do { if (gotlandmark(prefix, landmark)) { assert(stdlibdir[wcslen(prefix)] == SEP); /* Due to reduce() and our initial value, this result is guaranteed to fit. */ wcscpy(&stdlibdir[wcslen(prefix) + 1], L"lib"); if (is_stdlibdir(stdlibdir)) { return 1; } reduce(prefix);