diff options
Diffstat (limited to 'src/lib/libc/stdlib/realpath.c')
-rw-r--r-- | src/lib/libc/stdlib/realpath.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c index e349b7e068..d01b19e0f2 100644 --- a/src/lib/libc/stdlib/realpath.c +++ b/src/lib/libc/stdlib/realpath.c | |||
@@ -35,8 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #if defined(LIBC_SCCS) && !defined(lint) | 37 | #if defined(LIBC_SCCS) && !defined(lint) |
38 | /*static char sccsid[] = "from: @(#)realpath.c 8.1 (Berkeley) 2/16/94";*/ | 38 | static char *rcsid = "$OpenBSD: realpath.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $"; |
39 | static char *rcsid = "$Id: realpath.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; | ||
40 | #endif /* LIBC_SCCS and not lint */ | 39 | #endif /* LIBC_SCCS and not lint */ |
41 | 40 | ||
42 | #include <sys/param.h> | 41 | #include <sys/param.h> |
@@ -63,13 +62,18 @@ realpath(path, resolved) | |||
63 | struct stat sb; | 62 | struct stat sb; |
64 | int fd, n, rootd, serrno; | 63 | int fd, n, rootd, serrno; |
65 | char *p, *q, wbuf[MAXPATHLEN]; | 64 | char *p, *q, wbuf[MAXPATHLEN]; |
65 | int symlinks = 0; | ||
66 | 66 | ||
67 | /* Save the starting point. */ | 67 | /* Save the starting point. */ |
68 | if ((fd = open(".", O_RDONLY)) < 0) { | 68 | if ((fd = open(".", O_RDONLY)) < 0) { |
69 | (void)strcpy(resolved, "."); | 69 | (void)strlcpy(resolved, ".", MAXPATHLEN); |
70 | return (NULL); | 70 | return (NULL); |
71 | } | 71 | } |
72 | 72 | ||
73 | /* Convert "." -> "" to optimize away a needless lstat() and chdir() */ | ||
74 | if (path[0] == '.' && path[1] == '\0') | ||
75 | path = ""; | ||
76 | |||
73 | /* | 77 | /* |
74 | * Find the dirname and basename from the path to be resolved. | 78 | * Find the dirname and basename from the path to be resolved. |
75 | * Change directory to the dirname component. | 79 | * Change directory to the dirname component. |
@@ -78,8 +82,7 @@ realpath(path, resolved) | |||
78 | * if it is a directory, then change to that directory. | 82 | * if it is a directory, then change to that directory. |
79 | * get the current directory name and append the basename. | 83 | * get the current directory name and append the basename. |
80 | */ | 84 | */ |
81 | (void)strncpy(resolved, path, MAXPATHLEN - 1); | 85 | strlcpy(resolved, path, MAXPATHLEN); |
82 | resolved[MAXPATHLEN - 1] = '\0'; | ||
83 | loop: | 86 | loop: |
84 | q = strrchr(resolved, '/'); | 87 | q = strrchr(resolved, '/'); |
85 | if (q != NULL) { | 88 | if (q != NULL) { |
@@ -99,9 +102,13 @@ loop: | |||
99 | p = resolved; | 102 | p = resolved; |
100 | 103 | ||
101 | /* Deal with the last component. */ | 104 | /* Deal with the last component. */ |
102 | if (lstat(p, &sb) == 0) { | 105 | if (*p != '\0' && lstat(p, &sb) == 0) { |
103 | if (S_ISLNK(sb.st_mode)) { | 106 | if (S_ISLNK(sb.st_mode)) { |
104 | n = readlink(p, resolved, MAXPATHLEN); | 107 | if (++symlinks > MAXSYMLINKS) { |
108 | errno = ELOOP; | ||
109 | goto err1; | ||
110 | } | ||
111 | n = readlink(p, resolved, MAXPATHLEN-1); | ||
105 | if (n < 0) | 112 | if (n < 0) |
106 | goto err1; | 113 | goto err1; |
107 | resolved[n] = '\0'; | 114 | resolved[n] = '\0'; |
@@ -118,7 +125,7 @@ loop: | |||
118 | * Save the last component name and get the full pathname of | 125 | * Save the last component name and get the full pathname of |
119 | * the current directory. | 126 | * the current directory. |
120 | */ | 127 | */ |
121 | (void)strcpy(wbuf, p); | 128 | (void)strlcpy(wbuf, p, sizeof wbuf); |
122 | if (getcwd(resolved, MAXPATHLEN) == 0) | 129 | if (getcwd(resolved, MAXPATHLEN) == 0) |
123 | goto err1; | 130 | goto err1; |
124 | 131 | ||