diff options
Diffstat (limited to 'stdlib')
-rw-r--r-- | stdlib/canonicalize.c | 39 | ||||
-rw-r--r-- | stdlib/msort.c | 5 | ||||
-rw-r--r-- | stdlib/test-canon.c | 24 |
3 files changed, 54 insertions, 14 deletions
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c index ea7883dba5..3617226f0a 100644 --- a/stdlib/canonicalize.c +++ b/stdlib/canonicalize.c @@ -45,6 +45,22 @@ canonicalize (const char *name, char *resolved) long int path_max; int num_links = 0; + if (name == NULL || resolved == NULL) + { + /* As per Single Unix Specification V2 we must return an error if + either parameter is a null pointer. */ + __set_errno (EINVAL); + return NULL; + } + + if (name[0] == '\0') + { + /* As per Single Unix Specification V2 we must return an error if + the name argument points to an empty string. */ + __set_errno (ENOENT); + return NULL; + } + #ifdef PATH_MAX path_max = PATH_MAX; #else @@ -73,21 +89,23 @@ canonicalize (const char *name, char *resolved) struct stat st; int n; - /* skip sequence of multiple path-separators: */ + /* Skip sequence of multiple path-separators. */ while (*start == '/') ++start; - /* find end of path component: */ + /* Find end of path component. */ for (end = start; *end && *end != '/'; ++end); if (end - start == 0) break; else if (strncmp (start, ".", end - start) == 0) /* nothing */; - else if (strncmp (start, "..", end - start) == 0) { - /* back up to previous component, ignore if at root already: */ - if (dest > rpath + 1) - while ((--dest)[-1] != '/'); - } else + else if (strncmp (start, "..", end - start) == 0) + { + /* Back up to previous component, ignore if at root already. */ + if (dest > rpath + 1) + while ((--dest)[-1] != '/'); + } + else { size_t new_size; @@ -112,8 +130,7 @@ canonicalize (const char *name, char *resolved) return NULL; } - memcpy (dest, start, end - start); - dest += end - start; + dest = __mempcpy (dest, start, end - start); *dest = '\0'; if (__lstat (rpath, &st) < 0) @@ -146,8 +163,8 @@ canonicalize (const char *name, char *resolved) } /* Careful here, end may be a pointer into extra_buf... */ - memcpy (&buf[n], end, len + 1); - strcpy (extra_buf, buf); + memmove (&extra_buf[n], end, len + 1); + memcpy (extra_buf, buf, n); name = end = extra_buf; if (buf[0] == '/') diff --git a/stdlib/msort.c b/stdlib/msort.c index 4cd3e3f167..1c36a4cb9c 100644 --- a/stdlib/msort.c +++ b/stdlib/msort.c @@ -71,17 +71,16 @@ msort_with_tmp (b, n, s, cmp, t) { if ((*cmp) (b1, b2) <= 0) { - memcpy (tmp, b1, s); + tmp = (char *) __mempcpy (tmp, b1, s); b1 += s; --n1; } else { - memcpy (tmp, b2, s); + tmp = (char *) __mempcpy (tmp, b2, s); b2 += s; --n2; } - tmp += s; } if (n1 > 0) memcpy (tmp, b1, n1 * s); diff --git a/stdlib/test-canon.c b/stdlib/test-canon.c index ffd6fa99d4..c239d50ae8 100644 --- a/stdlib/test-canon.c +++ b/stdlib/test-canon.c @@ -117,6 +117,30 @@ main (int argc, char ** argv) getcwd (cwd, sizeof(buf)); cwd_len = strlen (cwd); + errno = 0; + if (realpath (NULL, buf) != NULL || errno != EINVAL) + { + printf ("%s: expected return value NULL and errno set to EINVAL" + " for realpath(NULL,...)\n", argv[0]); + ++errors; + } + + errno = 0; + if (realpath ("/", NULL) != NULL || errno != EINVAL) + { + printf ("%s: expected return value NULL and errno set to EINVAL" + " for realpath(...,NULL)\n", argv[0]); + ++errors; + } + + errno = 0; + if (realpath ("", buf) != NULL || errno != ENOENT) + { + printf ("%s: expected return value NULL and set errno to ENOENT", + " for realpath(\"\",...)\n", argv[0]); + ++errors; + } + for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i) symlink (symlinks[i].value, symlinks[i].name); |