mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	bpo-36236: Fix _PyPathConfig_ComputeSysPath0() for empty argv (GH-12441)
* _PyPathConfig_ComputeSysPath0() now returns 0 if argv is empty. * Cleanup also _PyPathConfig_ComputeSysPath0() code: move variables definitions closer to where they are used.
This commit is contained in:
		
							parent
							
								
									cb90c89de1
								
							
						
					
					
						commit
						fc96e5474a
					
				
					 1 changed files with 63 additions and 55 deletions
				
			
		| 
						 | 
					@ -573,79 +573,84 @@ Py_GetProgramName(void)
 | 
				
			||||||
   Return 1 if the path is correctly resolved, but *path0_p can be NULL
 | 
					   Return 1 if the path is correctly resolved, but *path0_p can be NULL
 | 
				
			||||||
   if the Unicode object fail to be created.
 | 
					   if the Unicode object fail to be created.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   Return 0 if it fails to resolve the full path (and *path0_p will be NULL),
 | 
					   Return 0 if it fails to resolve the full path (and *path0_p will be NULL).
 | 
				
			||||||
   for example if the current working directory has been removed (bpo-36236).
 | 
					   For example, return 0 if the current working directory has been removed
 | 
				
			||||||
 | 
					   (bpo-36236) or if argv is empty.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
_PyPathConfig_ComputeSysPath0(const _PyWstrList *argv, PyObject **path0_p)
 | 
					_PyPathConfig_ComputeSysPath0(const _PyWstrList *argv, PyObject **path0_p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(_PyWstrList_CheckConsistency(argv));
 | 
					    assert(_PyWstrList_CheckConsistency(argv));
 | 
				
			||||||
 | 
					    assert(*path0_p == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    wchar_t *argv0;
 | 
					    if (argv->length == 0) {
 | 
				
			||||||
    wchar_t *p = NULL;
 | 
					        /* Leave sys.path unchanged if sys.argv is empty */
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    wchar_t *argv0 = argv->items[0];
 | 
				
			||||||
 | 
					    int have_module_arg = (wcscmp(argv0, L"-m") == 0);
 | 
				
			||||||
 | 
					    int have_script_arg = (!have_module_arg && (wcscmp(argv0, L"-c") != 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    wchar_t *path0 = argv0;
 | 
				
			||||||
    Py_ssize_t n = 0;
 | 
					    Py_ssize_t n = 0;
 | 
				
			||||||
    int have_script_arg = 0;
 | 
					
 | 
				
			||||||
    int have_module_arg = 0;
 | 
					#ifdef HAVE_REALPATH
 | 
				
			||||||
#ifdef HAVE_READLINK
 | 
					 | 
				
			||||||
    wchar_t link[MAXPATHLEN + 1];
 | 
					 | 
				
			||||||
    wchar_t argv0copy[2 * MAXPATHLEN + 1];
 | 
					 | 
				
			||||||
    int nr = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#if defined(HAVE_REALPATH)
 | 
					 | 
				
			||||||
    wchar_t fullpath[MAXPATHLEN];
 | 
					    wchar_t fullpath[MAXPATHLEN];
 | 
				
			||||||
#elif defined(MS_WINDOWS)
 | 
					#elif defined(MS_WINDOWS)
 | 
				
			||||||
    wchar_t fullpath[MAX_PATH];
 | 
					    wchar_t fullpath[MAX_PATH];
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(*path0_p == NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (argv->length > 0) {
 | 
					 | 
				
			||||||
        argv0 = argv->items[0];
 | 
					 | 
				
			||||||
        have_module_arg = (wcscmp(argv0, L"-m") == 0);
 | 
					 | 
				
			||||||
        have_script_arg = !have_module_arg && (wcscmp(argv0, L"-c") != 0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (have_module_arg) {
 | 
					    if (have_module_arg) {
 | 
				
			||||||
#if defined(HAVE_REALPATH) || defined(MS_WINDOWS)
 | 
					#if defined(HAVE_REALPATH) || defined(MS_WINDOWS)
 | 
				
			||||||
        if (!_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath))) {
 | 
					        if (!_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath))) {
 | 
				
			||||||
                *path0_p = NULL;
 | 
					 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
            argv0 = fullpath;
 | 
					        path0 = fullpath;
 | 
				
			||||||
            n = wcslen(argv0);
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
            argv0 = L".";
 | 
					        path0 = L".";
 | 
				
			||||||
            n = 1;
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					        n = wcslen(path0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_READLINK
 | 
					#ifdef HAVE_READLINK
 | 
				
			||||||
    if (have_script_arg)
 | 
					    wchar_t link[MAXPATHLEN + 1];
 | 
				
			||||||
        nr = _Py_wreadlink(argv0, link, Py_ARRAY_LENGTH(link));
 | 
					    int nr = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (have_script_arg) {
 | 
				
			||||||
 | 
					        nr = _Py_wreadlink(path0, link, Py_ARRAY_LENGTH(link));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (nr > 0) {
 | 
					    if (nr > 0) {
 | 
				
			||||||
        /* It's a symlink */
 | 
					        /* It's a symlink */
 | 
				
			||||||
        link[nr] = '\0';
 | 
					        link[nr] = '\0';
 | 
				
			||||||
        if (link[0] == SEP)
 | 
					        if (link[0] == SEP) {
 | 
				
			||||||
            argv0 = link; /* Link to absolute path */
 | 
					            path0 = link; /* Link to absolute path */
 | 
				
			||||||
        else if (wcschr(link, SEP) == NULL)
 | 
					        }
 | 
				
			||||||
            ; /* Link without path */
 | 
					        else if (wcschr(link, SEP) == NULL) {
 | 
				
			||||||
 | 
					            /* Link without path */
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            /* Must join(dirname(argv0), link) */
 | 
					            /* Must join(dirname(path0), link) */
 | 
				
			||||||
            wchar_t *q = wcsrchr(argv0, SEP);
 | 
					            wchar_t *q = wcsrchr(path0, SEP);
 | 
				
			||||||
            if (q == NULL)
 | 
					            if (q == NULL) {
 | 
				
			||||||
                argv0 = link; /* argv0 without path */
 | 
					                /* path0 without path */
 | 
				
			||||||
 | 
					                path0 = link;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            else {
 | 
					            else {
 | 
				
			||||||
                /* Must make a copy, argv0copy has room for 2 * MAXPATHLEN */
 | 
					                /* Must make a copy, path0copy has room for 2 * MAXPATHLEN */
 | 
				
			||||||
                wcsncpy(argv0copy, argv0, MAXPATHLEN);
 | 
					                wchar_t path0copy[2 * MAXPATHLEN + 1];
 | 
				
			||||||
                q = wcsrchr(argv0copy, SEP);
 | 
					                wcsncpy(path0copy, path0, MAXPATHLEN);
 | 
				
			||||||
 | 
					                q = wcsrchr(path0copy, SEP);
 | 
				
			||||||
                wcsncpy(q+1, link, MAXPATHLEN);
 | 
					                wcsncpy(q+1, link, MAXPATHLEN);
 | 
				
			||||||
                q[MAXPATHLEN + 1] = L'\0';
 | 
					                q[MAXPATHLEN + 1] = L'\0';
 | 
				
			||||||
                argv0 = argv0copy;
 | 
					                path0 = path0copy;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif /* HAVE_READLINK */
 | 
					#endif /* HAVE_READLINK */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    wchar_t *p = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if SEP == '\\'
 | 
					#if SEP == '\\'
 | 
				
			||||||
    /* Special case for Microsoft filename syntax */
 | 
					    /* Special case for Microsoft filename syntax */
 | 
				
			||||||
    if (have_script_arg) {
 | 
					    if (have_script_arg) {
 | 
				
			||||||
| 
						 | 
					@ -653,43 +658,46 @@ _PyPathConfig_ComputeSysPath0(const _PyWstrList *argv, PyObject **path0_p)
 | 
				
			||||||
#if defined(MS_WINDOWS)
 | 
					#if defined(MS_WINDOWS)
 | 
				
			||||||
        /* Replace the first element in argv with the full path. */
 | 
					        /* Replace the first element in argv with the full path. */
 | 
				
			||||||
        wchar_t *ptemp;
 | 
					        wchar_t *ptemp;
 | 
				
			||||||
        if (GetFullPathNameW(argv0,
 | 
					        if (GetFullPathNameW(path0,
 | 
				
			||||||
                           Py_ARRAY_LENGTH(fullpath),
 | 
					                           Py_ARRAY_LENGTH(fullpath),
 | 
				
			||||||
                           fullpath,
 | 
					                           fullpath,
 | 
				
			||||||
                           &ptemp)) {
 | 
					                           &ptemp)) {
 | 
				
			||||||
            argv0 = fullpath;
 | 
					            path0 = fullpath;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        p = wcsrchr(argv0, SEP);
 | 
					        p = wcsrchr(path0, SEP);
 | 
				
			||||||
        /* Test for alternate separator */
 | 
					        /* Test for alternate separator */
 | 
				
			||||||
        q = wcsrchr(p ? p : argv0, '/');
 | 
					        q = wcsrchr(p ? p : path0, '/');
 | 
				
			||||||
        if (q != NULL)
 | 
					        if (q != NULL)
 | 
				
			||||||
            p = q;
 | 
					            p = q;
 | 
				
			||||||
        if (p != NULL) {
 | 
					        if (p != NULL) {
 | 
				
			||||||
            n = p + 1 - argv0;
 | 
					            n = p + 1 - path0;
 | 
				
			||||||
            if (n > 1 && p[-1] != ':')
 | 
					            if (n > 1 && p[-1] != ':')
 | 
				
			||||||
                n--; /* Drop trailing separator */
 | 
					                n--; /* Drop trailing separator */
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#else /* All other filename syntaxes */
 | 
					#else
 | 
				
			||||||
 | 
					    /* All other filename syntaxes */
 | 
				
			||||||
    if (have_script_arg) {
 | 
					    if (have_script_arg) {
 | 
				
			||||||
#if defined(HAVE_REALPATH)
 | 
					#if defined(HAVE_REALPATH)
 | 
				
			||||||
        if (_Py_wrealpath(argv0, fullpath, Py_ARRAY_LENGTH(fullpath))) {
 | 
					        if (_Py_wrealpath(path0, fullpath, Py_ARRAY_LENGTH(fullpath))) {
 | 
				
			||||||
            argv0 = fullpath;
 | 
					            path0 = fullpath;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        p = wcsrchr(argv0, SEP);
 | 
					        p = wcsrchr(path0, SEP);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (p != NULL) {
 | 
					    if (p != NULL) {
 | 
				
			||||||
        n = p + 1 - argv0;
 | 
					        n = p + 1 - path0;
 | 
				
			||||||
#if SEP == '/' /* Special case for Unix filename syntax */
 | 
					#if SEP == '/' /* Special case for Unix filename syntax */
 | 
				
			||||||
        if (n > 1)
 | 
					        if (n > 1) {
 | 
				
			||||||
            n--; /* Drop trailing separator */
 | 
					            /* Drop trailing separator */
 | 
				
			||||||
 | 
					            n--;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
#endif /* Unix */
 | 
					#endif /* Unix */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif /* All others */
 | 
					#endif /* All others */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    *path0_p = PyUnicode_FromWideChar(argv0, n);
 | 
					    *path0_p = PyUnicode_FromWideChar(path0, n);
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue