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

bpo-38353: Rework ismodule() in getpath.c (GH-16574)

* ismodule() no longer modify the input string.
* copy_absolute(), joinpath(): rename parameters and local variables.
parent 03a8a56f
...@@ -183,25 +183,6 @@ isfile(const wchar_t *filename) ...@@ -183,25 +183,6 @@ isfile(const wchar_t *filename)
} }
/* Is module -- check for .pyc too */
static int
ismodule(wchar_t *filename, size_t filename_len)
{
if (isfile(filename)) {
return 1;
}
/* Check for the compiled version of prefix. */
if (wcslen(filename) + 2 <= filename_len) {
wcscat(filename, L"c");
if (isfile(filename)) {
return 1;
}
}
return 0;
}
/* Is executable file */ /* Is executable file */
static int static int
isxfile(const wchar_t *filename) isxfile(const wchar_t *filename)
...@@ -222,7 +203,7 @@ isxfile(const wchar_t *filename) ...@@ -222,7 +203,7 @@ isxfile(const wchar_t *filename)
/* Is directory */ /* Is directory */
static int static int
isdir(wchar_t *filename) isdir(const wchar_t *filename)
{ {
struct stat buf; struct stat buf;
if (_Py_wstat(filename, &buf) != 0) { if (_Py_wstat(filename, &buf) != 0) {
...@@ -238,29 +219,29 @@ isdir(wchar_t *filename) ...@@ -238,29 +219,29 @@ isdir(wchar_t *filename)
/* Add a path component, by appending stuff to buffer. /* Add a path component, by appending stuff to buffer.
buflen: 'buffer' length in characters including trailing NUL. */ buflen: 'buffer' length in characters including trailing NUL. */
static PyStatus static PyStatus
joinpath(wchar_t *buffer, const wchar_t *stuff, size_t buflen) joinpath(wchar_t *path, const wchar_t *path2, size_t path_len)
{ {
size_t n, k; size_t n;
if (!_Py_isabs(stuff)) { if (!_Py_isabs(path2)) {
n = wcslen(buffer); n = wcslen(path);
if (n >= buflen) { if (n >= path_len) {
return PATHLEN_ERR(); return PATHLEN_ERR();
} }
if (n > 0 && buffer[n-1] != SEP) { if (n > 0 && path[n-1] != SEP) {
buffer[n++] = SEP; path[n++] = SEP;
} }
} }
else { else {
n = 0; n = 0;
} }
k = wcslen(stuff); size_t k = wcslen(path2);
if (n + k >= buflen) { if (n + k >= path_len) {
return PATHLEN_ERR(); return PATHLEN_ERR();
} }
wcsncpy(buffer+n, stuff, k); wcsncpy(path + n, path2, k);
buffer[n+k] = '\0'; path[n + k] = '\0';
return _PyStatus_OK(); return _PyStatus_OK();
} }
...@@ -280,27 +261,27 @@ safe_wcscpy(wchar_t *dst, const wchar_t *src, size_t n) ...@@ -280,27 +261,27 @@ safe_wcscpy(wchar_t *dst, const wchar_t *src, size_t n)
/* copy_absolute requires that path be allocated at least /* copy_absolute requires that path be allocated at least
'pathlen' characters (including trailing NUL). */ 'abs_path_len' characters (including trailing NUL). */
static PyStatus static PyStatus
copy_absolute(wchar_t *path, const wchar_t *p, size_t pathlen) copy_absolute(wchar_t *abs_path, const wchar_t *path, size_t abs_path_len)
{ {
if (_Py_isabs(p)) { if (_Py_isabs(path)) {
if (safe_wcscpy(path, p, pathlen) < 0) { if (safe_wcscpy(abs_path, path, abs_path_len) < 0) {
return PATHLEN_ERR(); return PATHLEN_ERR();
} }
} }
else { else {
if (!_Py_wgetcwd(path, pathlen)) { if (!_Py_wgetcwd(abs_path, abs_path_len)) {
/* unable to get the current directory */ /* unable to get the current directory */
if (safe_wcscpy(path, p, pathlen) < 0) { if (safe_wcscpy(abs_path, path, abs_path_len) < 0) {
return PATHLEN_ERR(); return PATHLEN_ERR();
} }
return _PyStatus_OK(); return _PyStatus_OK();
} }
if (p[0] == '.' && p[1] == SEP) { if (path[0] == '.' && path[1] == SEP) {
p += 2; path += 2;
} }
PyStatus status = joinpath(path, p, pathlen); PyStatus status = joinpath(abs_path, path, abs_path_len);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
...@@ -330,6 +311,41 @@ absolutize(wchar_t *path, size_t path_len) ...@@ -330,6 +311,41 @@ absolutize(wchar_t *path, size_t path_len)
} }
/* Is module -- check for .pyc too */
static PyStatus
ismodule(const wchar_t *path, int *result)
{
wchar_t filename[MAXPATHLEN+1];
size_t filename_len = Py_ARRAY_LENGTH(filename);
if (safe_wcscpy(filename, path, filename_len) < 0) {
return PATHLEN_ERR();
}
PyStatus status = joinpath(filename, LANDMARK, filename_len);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
if (isfile(filename)) {
*result = 1;
return _PyStatus_OK();
}
/* Check for the compiled version of prefix. */
if (wcslen(filename) + 2 <= filename_len) {
wcscat(filename, L"c");
if (isfile(filename)) {
*result = 1;
return _PyStatus_OK();
}
}
*result = 0;
return _PyStatus_OK();
}
#if defined(__CYGWIN__) || defined(__MINGW32__) #if defined(__CYGWIN__) || defined(__MINGW32__)
#ifndef EXE_SUFFIX #ifndef EXE_SUFFIX
#define EXE_SUFFIX L".exe" #define EXE_SUFFIX L".exe"
...@@ -337,26 +353,25 @@ absolutize(wchar_t *path, size_t path_len) ...@@ -337,26 +353,25 @@ absolutize(wchar_t *path, size_t path_len)
/* pathlen: 'path' length in characters including trailing NUL */ /* pathlen: 'path' length in characters including trailing NUL */
static PyStatus static PyStatus
add_exe_suffix(wchar_t *progpath, size_t progpathlen) add_exe_suffix(wchar_t *path, size_t pathlen)
{ {
/* Check for already have an executable suffix */ /* Check for already have an executable suffix */
size_t n = wcslen(progpath); size_t n = wcslen(path);
size_t s = wcslen(EXE_SUFFIX); size_t s = wcslen(EXE_SUFFIX);
if (wcsncasecmp(EXE_SUFFIX, progpath + n - s, s) == 0) { if (wcsncasecmp(EXE_SUFFIX, path + n - s, s) == 0) {
return _PyStatus_OK(); return _PyStatus_OK();
} }
if (n + s >= progpathlen) { if (n + s >= pathlen) {
return PATHLEN_ERR(); return PATHLEN_ERR();
} }
wcsncpy(progpath + n, EXE_SUFFIX, s); wcsncpy(path + n, EXE_SUFFIX, s);
progpath[n+s] = '\0'; path[n + s] = '\0';
if (!isxfile(progpath)) { if (!isxfile(path)) {
/* Path that added suffix is invalid: truncate (remove suffix) */ /* Path that added suffix is invalid: truncate (remove suffix) */
progpath[n] = '\0'; path[n] = '\0';
} }
return _PyStatus_OK(); return _PyStatus_OK();
} }
#endif #endif
...@@ -422,14 +437,14 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, ...@@ -422,14 +437,14 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
status = joinpath(prefix, LANDMARK, prefix_len);
int module;
status = ismodule(prefix, &module);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
if (module) {
if (ismodule(prefix, prefix_len)) {
*found = -1; *found = -1;
reduce(prefix);
return _PyStatus_OK(); return _PyStatus_OK();
} }
} }
...@@ -448,14 +463,14 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, ...@@ -448,14 +463,14 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
status = joinpath(prefix, LANDMARK, prefix_len);
int module;
status = ismodule(prefix, &module);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
if (module) {
if (ismodule(prefix, prefix_len)) {
*found = 1; *found = 1;
reduce(prefix);
return _PyStatus_OK(); return _PyStatus_OK();
} }
prefix[n] = L'\0'; prefix[n] = L'\0';
...@@ -471,14 +486,14 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig, ...@@ -471,14 +486,14 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
status = joinpath(prefix, LANDMARK, prefix_len);
int module;
status = ismodule(prefix, &module);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
if (module) {
if (ismodule(prefix, prefix_len)) {
*found = 1; *found = 1;
reduce(prefix);
return _PyStatus_OK(); return _PyStatus_OK();
} }
...@@ -1038,12 +1053,13 @@ calculate_argv0_path_framework(PyCalculatePath *calculate, ...@@ -1038,12 +1053,13 @@ calculate_argv0_path_framework(PyCalculatePath *calculate,
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
goto done; goto done;
} }
status = joinpath(argv0_path, LANDMARK, argv0_path_len);
int module;
status = ismodule(argv0_path, &module);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
goto done; goto done;
} }
if (module) {
if (ismodule(argv0_path, Py_ARRAY_LENGTH(argv0_path))) {
/* Use the location of the library as argv0_path */ /* Use the location of the library as argv0_path */
if (safe_wcscpy(argv0_path, wbuf, argv0_path_len) < 0) { if (safe_wcscpy(argv0_path, wbuf, argv0_path_len) < 0) {
status = PATHLEN_ERR(); status = PATHLEN_ERR();
......
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