diff options
Diffstat (limited to 'pseudo_util.c')
-rw-r--r-- | pseudo_util.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/pseudo_util.c b/pseudo_util.c index b6980c2..64636b7 100644 --- a/pseudo_util.c +++ b/pseudo_util.c @@ -679,7 +679,7 @@ pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurre if (!leave_this && is_dir) { int is_link = S_ISLNK(buf->st_mode); if (link_recursion >= PSEUDO_MAX_LINK_RECURSION && is_link) { - pseudo_diag("link recursion too deep, not expanding path '%s'.\n", newpath); + pseudo_debug(PDBGF_PATH, "link recursion too deep, not expanding path '%s'.\n", newpath); is_link = 0; } if (is_link) { @@ -689,14 +689,15 @@ pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurre linklen = readlink(newpath, linkbuf, pseudo_path_max()); if (linklen == -1) { - pseudo_diag("uh-oh! '%s' seems to be a symlink, but I can't read it. Ignoring.", newpath); + pseudo_debug(PDBGF_PATH, "uh-oh! '%s' seems to be a symlink, but I can't read it. Ignoring.\n", newpath); + *pcurrent = current; return 0; } /* null-terminate buffer */ linkbuf[linklen] = '\0'; - /* absolute symlink means start over! */ + /* absolute symlink means go back to root */ if (*linkbuf == '/') { - current = newpath; + current = root; } else { /* point back at the end of the previous path... */ current -= (elen + 1); @@ -791,11 +792,9 @@ static char *pathbufs[PATHBUFS] = { 0 }; static int pathbuf = 0; /* Canonicalize path. "base", if present, is an already-canonicalized - * path of baselen characters, presumed not to end in a /. path is - * the new path to be canonicalized. The tricky part is that path may - * contain symlinks, which must be resolved. - * if "path" starts with a /, then it is an absolute path, and - * we ignore base. + * path of baselen characters, presumed not to end in a / unless it is + * just "/". path is the new path to be canonicalized. The tricky part + * is that path may contain symlinks, which must be resolved. */ char * pseudo_fix_path(const char *base, const char *path, size_t rootlen, size_t baselen, size_t *lenp, int leave_last) { @@ -809,13 +808,28 @@ pseudo_fix_path(const char *base, const char *path, size_t rootlen, size_t basel pseudo_diag("can't fix empty path.\n"); return 0; } + if (baselen == 1) { + baselen = 0; + } + if (rootlen == 1) { + rootlen = 0; + } newpathlen = pseudo_path_max(); + pathlen = strlen(path); + /* Crazy shell code (e.g. libtool) can pass in a command pipeline as a path which exceeds the max path + * length the system can support (6000+ chars). This will fail in libc or the syscall but if we don't + * do something here, we'd segfault before it can do that. Leave path unchanged and let libc deal + * with it. + */ + if ((pathlen + baselen) >= newpathlen) { + return path; + } if (!pathbufs[pathbuf]) { pathbufs[pathbuf] = malloc(newpathlen); } newpath = pathbufs[pathbuf]; pathbuf = (pathbuf + 1) % PATHBUFS; - pathlen = strlen(path); + /* a trailing slash has special meaning, but processing * trailing slashes is expensive. */ |