On Sun, 15 May 2022, Iain Buclaw wrote:
> Excerpts from Marc Aurèle La France's message of Mai 12, 2022 10:29 pm:

>> No compiler has any business rejecting files for the sole crime of
>> being symlinked to.  The following applies, modulo patch fuzz, to the
>> 9, 10 and 11 series of compilers.

>> Given my use of shadow trees, this bug attempted to prevent me from
>> building 12.1.0.  The D-based gdc in 12.1.0 and up does not exhibit
>> this quirky behaviour.

> Thanks, I've checked upstream and see the following change:

> https://github.com/dlang/dmd/pull/11836/commits/ebda81e44fd0ca4b247a1860d9bef411c41c16cb

> It should be fine to just backport that.

Thanks for the pointer.

I ended up with the three slightly different diffs below, one each for
the 9, 10 and 11 branches.  Each was rebuilt using 8.5.0, then used to
rebuild 12.1.0.  All of this ran smoothly without complaint, although I
wouldn't want to do this on a 486...

Thanks again and have a great day.

Marc.

Signed-off-by: Marc Aurèle La France <t...@tuyoix.net>

For GCC 9   ----------  8< ----------

diff -aNpRruz -X /etc/diff.excludes gcc-9.4.0/gcc/d/dmd/root/filename.c 
devel-9.4.0/gcc/d/dmd/root/filename.c
--- gcc-9.4.0/gcc/d/dmd/root/filename.c 2021-06-01 01:53:04.716474774 -0600
+++ devel-9.4.0/gcc/d/dmd/root/filename.c       2022-05-15 15:02:49.995441507 
-0600
@@ -475,53 +475,7 @@ const char *FileName::safeSearchPath(Strings *path, const 
char *name)

     return FileName::searchPath(path, name, false);
 #elif POSIX
-    /* Even with realpath(), we must check for // and disallow it
-     */
-    for (const char *p = name; *p; p++)
-    {
-        char c = *p;
-        if (c == '/' && p[1] == '/')
-        {
-            return NULL;
-        }
-    }
-
-    if (path)
-    {
-        /* Each path is converted to a cannonical name and then a check is 
done to see
-         * that the searched name is really a child one of the the paths 
searched.
-         */
-        for (size_t i = 0; i < path->dim; i++)
-        {
-            const char *cname = NULL;
-            const char *cpath = canonicalName((*path)[i]);
-            //printf("FileName::safeSearchPath(): name=%s; path=%s; 
cpath=%s\n",
-            //      name, (char *)path->data[i], cpath);
-            if (cpath == NULL)
-                goto cont;
-            cname = canonicalName(combine(cpath, name));
-            //printf("FileName::safeSearchPath(): cname=%s\n", cname);
-            if (cname == NULL)
-                goto cont;
-            //printf("FileName::safeSearchPath(): exists=%i "
-            //      "strncmp(cpath, cname, %i)=%i\n", exists(cname),
-            //      strlen(cpath), strncmp(cpath, cname, strlen(cpath)));
-            // exists and name is *really* a "child" of path
-            if (exists(cname) && strncmp(cpath, cname, strlen(cpath)) == 0)
-            {
-                ::free(const_cast<char *>(cpath));
-                const char *p = mem.xstrdup(cname);
-                ::free(const_cast<char *>(cname));
-                return p;
-            }
-cont:
-            if (cpath)
-                ::free(const_cast<char *>(cpath));
-            if (cname)
-                ::free(const_cast<char *>(cname));
-        }
-    }
-    return NULL;
+    return searchPath(path, name, false);
 #else
     assert(0);
 #endif

For GCC 10  ---------- 8< ----------

diff -aNpRruz -X /etc/diff.excludes gcc-10.3.0/gcc/d/dmd/root/filename.c 
devel-10.3.0/gcc/d/dmd/root/filename.c
--- gcc-10.3.0/gcc/d/dmd/root/filename.c        2021-04-08 05:56:28.277743190 
-0600
+++ devel-10.3.0/gcc/d/dmd/root/filename.c      2022-05-15 14:13:15.028032823 
-0600
@@ -476,53 +476,7 @@ const char *FileName::safeSearchPath(Strings *path, const 
char *name)

     return FileName::searchPath(path, name, false);
 #elif POSIX
-    /* Even with realpath(), we must check for // and disallow it
-     */
-    for (const char *p = name; *p; p++)
-    {
-        char c = *p;
-        if (c == '/' && p[1] == '/')
-        {
-            return NULL;
-        }
-    }
-
-    if (path)
-    {
-        /* Each path is converted to a cannonical name and then a check is 
done to see
-         * that the searched name is really a child one of the the paths 
searched.
-         */
-        for (size_t i = 0; i < path->dim; i++)
-        {
-            const char *cname = NULL;
-            const char *cpath = canonicalName((*path)[i]);
-            //printf("FileName::safeSearchPath(): name=%s; path=%s; 
cpath=%s\n",
-            //      name, (char *)path->data[i], cpath);
-            if (cpath == NULL)
-                goto cont;
-            cname = canonicalName(combine(cpath, name));
-            //printf("FileName::safeSearchPath(): cname=%s\n", cname);
-            if (cname == NULL)
-                goto cont;
-            //printf("FileName::safeSearchPath(): exists=%i "
-            //      "strncmp(cpath, cname, %i)=%i\n", exists(cname),
-            //      strlen(cpath), strncmp(cpath, cname, strlen(cpath)));
-            // exists and name is *really* a "child" of path
-            if (exists(cname) && strncmp(cpath, cname, strlen(cpath)) == 0)
-            {
-                ::free(const_cast<char *>(cpath));
-                const char *p = mem.xstrdup(cname);
-                ::free(const_cast<char *>(cname));
-                return p;
-            }
-cont:
-            if (cpath)
-                ::free(const_cast<char *>(cpath));
-            if (cname)
-                ::free(const_cast<char *>(cname));
-        }
-    }
-    return NULL;
+    return searchPath(path, name, false);
 #else
     assert(0);
 #endif

For GCC 11  ---------- 8< ----------

diff -aNpRruz -X /etc/diff.excludes gcc-11.3.0/gcc/d/dmd/root/filename.c 
devel-11.3.0/gcc/d/dmd/root/filename.c
--- gcc-11.3.0/gcc/d/dmd/root/filename.c        2022-04-21 01:58:53.000000000 
-0600
+++ devel-11.3.0/gcc/d/dmd/root/filename.c      2022-05-15 14:10:16.512781192 
-0600
@@ -490,53 +490,7 @@ const char *FileName::safeSearchPath(Strings *path, const 
char *name)

     return FileName::searchPath(path, name, false);
 #elif POSIX
-    /* Even with realpath(), we must check for // and disallow it
-     */
-    for (const char *p = name; *p; p++)
-    {
-        char c = *p;
-        if (c == '/' && p[1] == '/')
-        {
-            return NULL;
-        }
-    }
-
-    if (path)
-    {
-        /* Each path is converted to a cannonical name and then a check is 
done to see
-         * that the searched name is really a child one of the the paths 
searched.
-         */
-        for (size_t i = 0; i < path->length; i++)
-        {
-            const char *cname = NULL;
-            const char *cpath = canonicalName((*path)[i]);
-            //printf("FileName::safeSearchPath(): name=%s; path=%s; 
cpath=%s\n",
-            //      name, (char *)path->data[i], cpath);
-            if (cpath == NULL)
-                goto cont;
-            cname = canonicalName(combine(cpath, name));
-            //printf("FileName::safeSearchPath(): cname=%s\n", cname);
-            if (cname == NULL)
-                goto cont;
-            //printf("FileName::safeSearchPath(): exists=%i "
-            //      "strncmp(cpath, cname, %i)=%i\n", exists(cname),
-            //      strlen(cpath), strncmp(cpath, cname, strlen(cpath)));
-            // exists and name is *really* a "child" of path
-            if (exists(cname) && strncmp(cpath, cname, strlen(cpath)) == 0)
-            {
-                ::free(const_cast<char *>(cpath));
-                const char *p = mem.xstrdup(cname);
-                ::free(const_cast<char *>(cname));
-                return p;
-            }
-cont:
-            if (cpath)
-                ::free(const_cast<char *>(cpath));
-            if (cname)
-                ::free(const_cast<char *>(cname));
-        }
-    }
-    return NULL;
+    return searchPath(path, name, false);
 #else
     assert(0);
 #endif

Reply via email to