This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients hfuru, vstinner
Date 2019-02-25.10:10:23
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1551089423.86.0.432533309006.issue10308@roundup.psfhosted.org>
In-reply-to
Content
I reviewed getpath.diff:

diff -pru Python-2.7/Modules/getpath.c Python-2.7/Modules/getpath.c
--- Python-2.7/Modules/getpath.c
+++ Python-2.7/Modules/getpath.c
@@ -218,7 +218,7 @@ joinpath(char *buffer, char *stuff)
     if (n > MAXPATHLEN)
         Py_FatalError("buffer overflow in getpath.c's joinpath()");
     k = strlen(stuff);
-    if (n + k > MAXPATHLEN)
+    if (k > MAXPATHLEN - n)
         k = MAXPATHLEN - n;
     strncpy(buffer+n, stuff, k);
     buffer[n+k] = '\0';

As I explained in a previous comment, this change is useless: "n+k" cannot overflow.


@@ -229,10 +229,9 @@ joinpath(char *buffer, char *stuff)
 static void
 copy_absolute(char *path, char *p)
 {
-    if (p[0] == SEP)
+    if (p[0] == SEP || getcwd(path, MAXPATHLEN) == NULL)
         strcpy(path, p);
     else {
-        getcwd(path, MAXPATHLEN);
         if (p[0] == '.' && p[1] == SEP)
             p += 2;
         joinpath(path, p);

The code changed in the meanwhile (in the master branch, in 3.7 maybe, I don't recall), getcwd() error is now checked in copy_absolute():

        if (!_Py_wgetcwd(path, pathlen)) {
            /* unable to get the current directory */
            wcscpy(path, p);
            return;
        }

diff -pru Python-3.2a3/Modules/getpath.c Python-3.2a3/Modules/getpath.c
--- Python-3.2a3/Modules/getpath.c
+++ Python-3.2a3/Modules/getpath.c
@@ -351,18 +351,18 @@ search_for_exec_prefix(wchar_t *argv0_pa
         else {
             char buf[MAXPATHLEN+1];
             PyObject *decoded;
-            wchar_t rel_builddir_path[MAXPATHLEN+1];
-            size_t n;
             n = fread(buf, 1, MAXPATHLEN, f);
             buf[n] = '\0';
             fclose(f);
             decoded = PyUnicode_DecodeUTF8(buf, n, "surrogateescape");
             if (decoded != NULL) {
-                n = PyUnicode_AsWideChar((PyUnicodeObject*)decoded,
+                wchar_t rel_builddir_path[MAXPATHLEN+1];
+                Py_ssize_t k;
+                k = PyUnicode_AsWideChar((PyUnicodeObject*)decoded,
                                          rel_builddir_path, MAXPATHLEN);
                 Py_DECREF(decoded);
-                if (n >= 0) {
-                    rel_builddir_path[n] = L'\0';
+                if (k >= 0) {
+                    rel_builddir_path[k] = L'\0';
                     wcscpy(exec_prefix, argv0_path);
                     joinpath(exec_prefix, rel_builddir_path);
                     return -1;

Again, the code changed in the meanwhile:

            wchar_t *rel_builddir_path;
            ...
            rel_builddir_path = _Py_DecodeUTF8_surrogateescape(buf, n);
            if (rel_builddir_path) {

There is a new _Py_DecodeUTF8_surrogateescape() function which returns directly wchar_t* strings.

I close the issue.

--

Modules/getpath.c should be rewritten without global MAXPATHLEN limit. I rewrote the code to avoid global variables and pass buffer lengths in some functions. It's better but not perfect yet :-))
History
Date User Action Args
2019-02-25 10:10:23vstinnersetrecipients: + vstinner, hfuru
2019-02-25 10:10:23vstinnersetmessageid: <1551089423.86.0.432533309006.issue10308@roundup.psfhosted.org>
2019-02-25 10:10:23vstinnerlinkissue10308 messages
2019-02-25 10:10:23vstinnercreate