Mercurial > hg > toybox
view toys/posix/pwd.c @ 1613:96aa7ec74936 draft
Fix yet another sed bug.
The s/// command would copy the \ of substitutions before deciding what to
do with them (generally overwriting the \ with the new data). When the
substitution was A) at the very end of the new string, B) resolved to nothing,
it could leave a trailing \ that didn't belong there and didn't get overwritten
because the "copy trailing data" part that copies the original string's null
terminator already happened before the \ overwrote it.
The ghostwheel() function restarts regexes after embedded NUL bytes, but
if the string it's passed is _longer_ than the length it's told then it
gets confused (and it means we're off the end of our allocation so segfaults
are likely).
Fix: test for \ first and move the "copy byte" logic into an else case.
author | Rob Landley <rob@landley.net> |
---|---|
date | Mon, 15 Dec 2014 03:34:55 -0600 |
parents | cf101d432225 |
children |
line wrap: on
line source
/* pwd.c - Print working directory. * * Copyright 2006 Rob Landley <rob@landley.net> * * See http://opengroup.org/onlinepubs/9699919799/utilities/pwd.html USE_PWD(NEWTOY(pwd, ">0LP[-LP]", TOYFLAG_BIN)) config PWD bool "pwd" default y help usage: pwd [-L|-P] Print working (current) directory. -L Use shell's path from $PWD (when applicable) -P Print cannonical absolute path */ #define FOR_pwd #include "toys.h" void pwd_main(void) { char *s, *pwd = getcwd(0, 0), *PWD; // Only use $PWD if it's an absolute path alias for cwd with no "." or ".." if (!(toys.optflags & FLAG_P) && (s = PWD = getenv("PWD"))) { struct stat st1, st2; while (*s == '/') { if (*(++s) == '.') { if (s[1] == '/' || !s[1]) break; if (s[1] == '.' && (s[2] == '/' || !s[2])) break; } while (*s && *s != '/') s++; } if (!*s && s != PWD) s = PWD; else s = NULL; // If current directory exists, make sure it matches. if (s && pwd) if (stat(pwd, &st1) || stat(PWD, &st2) || st1.st_ino != st2.st_ino || st1.st_dev != st2.st_dev) s = NULL; } else s = NULL; // If -L didn't give us a valid path, use cwd. if (!s && !(s = pwd)) perror_exit("xgetcwd"); xprintf("%s\n", s); if (CFG_TOYBOX_FREE) free(pwd); }