canonicalize-lgpl.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. /* Return the canonical absolute name of a given file.
  2. Copyright (C) 1996-2017 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. #ifndef _LIBC
  15. /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc
  16. optimizes away the name == NULL test below. */
  17. # define _GL_ARG_NONNULL(params)
  18. # define _GL_USE_STDLIB_ALLOC 1
  19. # include <config.h>
  20. #endif
  21. #if !HAVE_CANONICALIZE_FILE_NAME || !FUNC_REALPATH_WORKS || defined _LIBC
  22. /* Specification. */
  23. #include <stdlib.h>
  24. #include <alloca.h>
  25. #include <string.h>
  26. #include <unistd.h>
  27. #include <limits.h>
  28. #if HAVE_SYS_PARAM_H || defined _LIBC
  29. # include <sys/param.h>
  30. #endif
  31. #include <sys/stat.h>
  32. #include <errno.h>
  33. #include <stddef.h>
  34. #ifdef _LIBC
  35. # include <shlib-compat.h>
  36. #else
  37. # define SHLIB_COMPAT(lib, introduced, obsoleted) 0
  38. # define versioned_symbol(lib, local, symbol, version) extern int dummy
  39. # define compat_symbol(lib, local, symbol, version)
  40. # define weak_alias(local, symbol)
  41. # define __canonicalize_file_name canonicalize_file_name
  42. # define __realpath realpath
  43. # include "pathmax.h"
  44. # include "malloca.h"
  45. # include "dosname.h"
  46. # if HAVE_GETCWD
  47. # if IN_RELOCWRAPPER
  48. /* When building the relocatable program wrapper, use the system's getcwd
  49. function, not the gnulib override, otherwise we would get a link error.
  50. */
  51. # undef getcwd
  52. # endif
  53. # ifdef VMS
  54. /* We want the directory in Unix syntax, not in VMS syntax. */
  55. # define __getcwd(buf, max) getcwd (buf, max, 0)
  56. # else
  57. # define __getcwd getcwd
  58. # endif
  59. # else
  60. # define __getcwd(buf, max) getwd (buf)
  61. # endif
  62. # define __readlink readlink
  63. # define __set_errno(e) errno = (e)
  64. # ifndef MAXSYMLINKS
  65. # ifdef SYMLOOP_MAX
  66. # define MAXSYMLINKS SYMLOOP_MAX
  67. # else
  68. # define MAXSYMLINKS 20
  69. # endif
  70. # endif
  71. #endif
  72. #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
  73. # define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
  74. #endif
  75. /* Define this independently so that stdint.h is not a prerequisite. */
  76. #ifndef SIZE_MAX
  77. # define SIZE_MAX ((size_t) -1)
  78. #endif
  79. #if !FUNC_REALPATH_WORKS || defined _LIBC
  80. static void
  81. alloc_failed (void)
  82. {
  83. #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  84. /* Avoid errno problem without using the malloc or realloc modules; see:
  85. http://lists.gnu.org/archive/html/bug-gnulib/2016-08/msg00025.html */
  86. errno = ENOMEM;
  87. #endif
  88. }
  89. /* Return the canonical absolute name of file NAME. A canonical name
  90. does not contain any ".", ".." components nor any repeated path
  91. separators ('/') or symlinks. All path components must exist. If
  92. RESOLVED is null, the result is malloc'd; otherwise, if the
  93. canonical name is PATH_MAX chars or more, returns null with 'errno'
  94. set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars,
  95. returns the name in RESOLVED. If the name cannot be resolved and
  96. RESOLVED is non-NULL, it contains the path of the first component
  97. that cannot be resolved. If the path can be resolved, RESOLVED
  98. holds the same value as the value returned. */
  99. char *
  100. __realpath (const char *name, char *resolved)
  101. {
  102. char *rpath, *dest, *extra_buf = NULL;
  103. const char *start, *end, *rpath_limit;
  104. long int path_max;
  105. int num_links = 0;
  106. size_t prefix_len;
  107. if (name == NULL)
  108. {
  109. /* As per Single Unix Specification V2 we must return an error if
  110. either parameter is a null pointer. We extend this to allow
  111. the RESOLVED parameter to be NULL in case the we are expected to
  112. allocate the room for the return value. */
  113. __set_errno (EINVAL);
  114. return NULL;
  115. }
  116. if (name[0] == '\0')
  117. {
  118. /* As per Single Unix Specification V2 we must return an error if
  119. the name argument points to an empty string. */
  120. __set_errno (ENOENT);
  121. return NULL;
  122. }
  123. #ifdef PATH_MAX
  124. path_max = PATH_MAX;
  125. #else
  126. path_max = pathconf (name, _PC_PATH_MAX);
  127. if (path_max <= 0)
  128. path_max = 8192;
  129. #endif
  130. if (resolved == NULL)
  131. {
  132. rpath = malloc (path_max);
  133. if (rpath == NULL)
  134. {
  135. alloc_failed ();
  136. return NULL;
  137. }
  138. }
  139. else
  140. rpath = resolved;
  141. rpath_limit = rpath + path_max;
  142. /* This is always zero for Posix hosts, but can be 2 for MS-Windows
  143. and MS-DOS X:/foo/bar file names. */
  144. prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
  145. if (!IS_ABSOLUTE_FILE_NAME (name))
  146. {
  147. if (!__getcwd (rpath, path_max))
  148. {
  149. rpath[0] = '\0';
  150. goto error;
  151. }
  152. dest = strchr (rpath, '\0');
  153. start = name;
  154. prefix_len = FILE_SYSTEM_PREFIX_LEN (rpath);
  155. }
  156. else
  157. {
  158. dest = rpath;
  159. if (prefix_len)
  160. {
  161. memcpy (rpath, name, prefix_len);
  162. dest += prefix_len;
  163. }
  164. *dest++ = '/';
  165. if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
  166. {
  167. if (ISSLASH (name[1]) && !ISSLASH (name[2]) && !prefix_len)
  168. *dest++ = '/';
  169. *dest = '\0';
  170. }
  171. start = name + prefix_len;
  172. }
  173. for (end = start; *start; start = end)
  174. {
  175. #ifdef _LIBC
  176. struct stat64 st;
  177. #else
  178. struct stat st;
  179. #endif
  180. /* Skip sequence of multiple path-separators. */
  181. while (ISSLASH (*start))
  182. ++start;
  183. /* Find end of path component. */
  184. for (end = start; *end && !ISSLASH (*end); ++end)
  185. /* Nothing. */;
  186. if (end - start == 0)
  187. break;
  188. else if (end - start == 1 && start[0] == '.')
  189. /* nothing */;
  190. else if (end - start == 2 && start[0] == '.' && start[1] == '.')
  191. {
  192. /* Back up to previous component, ignore if at root already. */
  193. if (dest > rpath + prefix_len + 1)
  194. for (--dest; dest > rpath && !ISSLASH (dest[-1]); --dest)
  195. continue;
  196. if (DOUBLE_SLASH_IS_DISTINCT_ROOT
  197. && dest == rpath + 1 && !prefix_len
  198. && ISSLASH (*dest) && !ISSLASH (dest[1]))
  199. dest++;
  200. }
  201. else
  202. {
  203. size_t new_size;
  204. if (!ISSLASH (dest[-1]))
  205. *dest++ = '/';
  206. if (dest + (end - start) >= rpath_limit)
  207. {
  208. ptrdiff_t dest_offset = dest - rpath;
  209. char *new_rpath;
  210. if (resolved)
  211. {
  212. __set_errno (ENAMETOOLONG);
  213. if (dest > rpath + prefix_len + 1)
  214. dest--;
  215. *dest = '\0';
  216. goto error;
  217. }
  218. new_size = rpath_limit - rpath;
  219. if (end - start + 1 > path_max)
  220. new_size += end - start + 1;
  221. else
  222. new_size += path_max;
  223. new_rpath = (char *) realloc (rpath, new_size);
  224. if (new_rpath == NULL)
  225. {
  226. alloc_failed ();
  227. goto error;
  228. }
  229. rpath = new_rpath;
  230. rpath_limit = rpath + new_size;
  231. dest = rpath + dest_offset;
  232. }
  233. #ifdef _LIBC
  234. dest = __mempcpy (dest, start, end - start);
  235. #else
  236. memcpy (dest, start, end - start);
  237. dest += end - start;
  238. #endif
  239. *dest = '\0';
  240. #ifdef _LIBC
  241. if (__lxstat64 (_STAT_VER, rpath, &st) < 0)
  242. #else
  243. if (lstat (rpath, &st) < 0)
  244. #endif
  245. goto error;
  246. if (S_ISLNK (st.st_mode))
  247. {
  248. char *buf;
  249. size_t len;
  250. ssize_t n;
  251. if (++num_links > MAXSYMLINKS)
  252. {
  253. __set_errno (ELOOP);
  254. goto error;
  255. }
  256. buf = malloca (path_max);
  257. if (!buf)
  258. {
  259. __set_errno (ENOMEM);
  260. goto error;
  261. }
  262. n = __readlink (rpath, buf, path_max - 1);
  263. if (n < 0)
  264. {
  265. int saved_errno = errno;
  266. freea (buf);
  267. __set_errno (saved_errno);
  268. goto error;
  269. }
  270. buf[n] = '\0';
  271. if (!extra_buf)
  272. {
  273. extra_buf = malloca (path_max);
  274. if (!extra_buf)
  275. {
  276. freea (buf);
  277. __set_errno (ENOMEM);
  278. goto error;
  279. }
  280. }
  281. len = strlen (end);
  282. /* Check that n + len + 1 doesn't overflow and is <= path_max. */
  283. if (n >= SIZE_MAX - len || n + len >= path_max)
  284. {
  285. freea (buf);
  286. __set_errno (ENAMETOOLONG);
  287. goto error;
  288. }
  289. /* Careful here, end may be a pointer into extra_buf... */
  290. memmove (&extra_buf[n], end, len + 1);
  291. name = end = memcpy (extra_buf, buf, n);
  292. if (IS_ABSOLUTE_FILE_NAME (buf))
  293. {
  294. size_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf);
  295. if (pfxlen)
  296. memcpy (rpath, buf, pfxlen);
  297. dest = rpath + pfxlen;
  298. *dest++ = '/'; /* It's an absolute symlink */
  299. if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
  300. {
  301. if (ISSLASH (buf[1]) && !ISSLASH (buf[2]) && !pfxlen)
  302. *dest++ = '/';
  303. *dest = '\0';
  304. }
  305. /* Install the new prefix to be in effect hereafter. */
  306. prefix_len = pfxlen;
  307. }
  308. else
  309. {
  310. /* Back up to previous component, ignore if at root
  311. already: */
  312. if (dest > rpath + prefix_len + 1)
  313. for (--dest; dest > rpath && !ISSLASH (dest[-1]); --dest)
  314. continue;
  315. if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1
  316. && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)
  317. dest++;
  318. }
  319. }
  320. else if (!S_ISDIR (st.st_mode) && *end != '\0')
  321. {
  322. __set_errno (ENOTDIR);
  323. goto error;
  324. }
  325. }
  326. }
  327. if (dest > rpath + prefix_len + 1 && ISSLASH (dest[-1]))
  328. --dest;
  329. if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 && !prefix_len
  330. && ISSLASH (*dest) && !ISSLASH (dest[1]))
  331. dest++;
  332. *dest = '\0';
  333. if (extra_buf)
  334. freea (extra_buf);
  335. return rpath;
  336. error:
  337. {
  338. int saved_errno = errno;
  339. if (extra_buf)
  340. freea (extra_buf);
  341. if (resolved == NULL)
  342. free (rpath);
  343. __set_errno (saved_errno);
  344. }
  345. return NULL;
  346. }
  347. versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
  348. #endif /* !FUNC_REALPATH_WORKS || defined _LIBC */
  349. #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3)
  350. char *
  351. attribute_compat_text_section
  352. __old_realpath (const char *name, char *resolved)
  353. {
  354. if (resolved == NULL)
  355. {
  356. __set_errno (EINVAL);
  357. return NULL;
  358. }
  359. return __realpath (name, resolved);
  360. }
  361. compat_symbol (libc, __old_realpath, realpath, GLIBC_2_0);
  362. #endif
  363. char *
  364. __canonicalize_file_name (const char *name)
  365. {
  366. return __realpath (name, NULL);
  367. }
  368. weak_alias (__canonicalize_file_name, canonicalize_file_name)
  369. #else
  370. /* This declaration is solely to ensure that after preprocessing
  371. this file is never empty. */
  372. typedef int dummy;
  373. #endif