[pcre-dev] [Bug 2794] pcre2grep "-r" option needs to detect …

Top Page
Delete this message
Author: admin
Date:  
To: pcre-dev
Old-Topics: [pcre-dev] [Bug 2794] New: pcre2grep directory recursion has trouble with certain symlinks on macOS
Subject: [pcre-dev] [Bug 2794] pcre2grep "-r" option needs to detect endless symlink recursion
https://bugs.exim.org/show_bug.cgi?id=2794

--- Comment #9 from Thomas Tempelmann <tempelmann@???> ---
Done.

Assuming this is line 3330:

    char buffer[FNBUFSIZ];


Then please rename "buffer" into "childpath" for better readability.

Then insert right after 3352 ("sprintf(..."):

      #if 1 // <-- replace with test for Linux and BSD (macOS/Darwin)
        // prevent endless recursion due to a symlink pointing to a parent dir
(Bug 2794)
        char resolvedpath[PATH_MAX];
        if (realpath(childpath, resolvedpath) == NULL)
          continue;     // this path is invalid - we can skip processing this
        BOOL isSame = strcmp(pathname, resolvedpath) == 0;
        if (isSame)
          continue;    // we have a recursion
        strlcat(resolvedpath, "/", sizeof(resolvedpath));
        size_t rlen = strlen(resolvedpath);
        BOOL contained = strncmp(pathname, resolvedpath, rlen) == 0;
        if (contained)
          continue;    // we have a recursion
        resolvedpath[rlen-1] = 0;   // removes the added "/"
        strlcpy(childpath, resolvedpath, sizeof(childpath));
      #endif


I've tested this to work successfully on macOS with my screwed-up symlink.

The tricky part is to tell whether the resolved path is pointing back to where
we already were.

With the first strcmp() I check whether it equals the parent current directory
path. This assumes, though, that "pathname" is also already resolved - but if
the user passed an unresolved path that points to itself, this recursion
detection will fail the first time, but then, in the recursion, the paths will
be the same (because I replace childpath with the resolved path further down)
and thus the recursion will be stopped. You could just as well also resolve the
path at the top of the function, but that's wasteful, IMO.

The second strcmp then checks of the resolved path exists as a the current
path's parent or their parent. I do this by adding a "/" to the resolved path
so that I do not mismatch the case where the resolved is "/a/b" and the parent
is "/a/b2".

Hope that helps.

--
You are receiving this mail because:
You are on the CC list for the bug.