diff options
| author | Paul Eggert | 2020-12-25 02:33:29 -0800 |
|---|---|---|
| committer | Paul Eggert | 2020-12-25 02:36:03 -0800 |
| commit | 42d58264db165d265cba68d6dbebc53a50738355 (patch) | |
| tree | 87543f2f0992a6b57a34dbd6ee04f48c3f6e7486 /lib | |
| parent | 5880c7caab394eac55c44d4be42b2f45dbd9bc53 (diff) | |
| download | emacs-42d58264db165d265cba68d6dbebc53a50738355.tar.gz emacs-42d58264db165d265cba68d6dbebc53a50738355.zip | |
Update Gnulib.
All changes in this commit are autogenerated by running
admin/merge-gnulib.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/canonicalize-lgpl.c | 213 | ||||
| -rw-r--r-- | lib/careadlinkat.c | 12 | ||||
| -rw-r--r-- | lib/eloop-threshold.h | 83 | ||||
| -rw-r--r-- | lib/euidaccess.c | 9 | ||||
| -rw-r--r-- | lib/faccessat.c | 14 | ||||
| -rw-r--r-- | lib/gnulib.mk.in | 14 | ||||
| -rw-r--r-- | lib/mini-gmp.c | 58 | ||||
| -rw-r--r-- | lib/mini-gmp.h | 5 | ||||
| -rw-r--r-- | lib/symlink.c | 2 |
9 files changed, 311 insertions, 99 deletions
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c index 584fce1cfa4..650d510f2d0 100644 --- a/lib/canonicalize-lgpl.c +++ b/lib/canonicalize-lgpl.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <stdlib.h> | 29 | #include <stdlib.h> |
| 30 | 30 | ||
| 31 | #include <errno.h> | 31 | #include <errno.h> |
| 32 | #include <fcntl.h> | ||
| 32 | #include <limits.h> | 33 | #include <limits.h> |
| 33 | #include <stdbool.h> | 34 | #include <stdbool.h> |
| 34 | #include <stddef.h> | 35 | #include <stddef.h> |
| @@ -36,23 +37,26 @@ | |||
| 36 | #include <sys/stat.h> | 37 | #include <sys/stat.h> |
| 37 | #include <unistd.h> | 38 | #include <unistd.h> |
| 38 | 39 | ||
| 40 | #include <eloop-threshold.h> | ||
| 41 | #include <filename.h> | ||
| 42 | #include <idx.h> | ||
| 39 | #include <scratch_buffer.h> | 43 | #include <scratch_buffer.h> |
| 40 | 44 | ||
| 41 | #ifdef _LIBC | 45 | #ifdef _LIBC |
| 42 | # include <eloop-threshold.h> | ||
| 43 | # include <shlib-compat.h> | 46 | # include <shlib-compat.h> |
| 44 | typedef ptrdiff_t idx_t; | 47 | # include <sysdep.h> |
| 45 | # define IDX_MAX PTRDIFF_MAX | 48 | # ifdef __ASSUME_FACCESSAT2 |
| 46 | # define FILE_SYSTEM_PREFIX_LEN(name) 0 | 49 | # define FACCESSAT_NEVER_EOVERFLOWS __ASSUME_FACCESSAT2 |
| 47 | # define IS_ABSOLUTE_FILE_NAME(name) ISSLASH(*(name)) | 50 | # else |
| 48 | # define ISSLASH(c) ((c) == '/') | 51 | # define FACCESSAT_NEVER_EOVERFLOWS true |
| 49 | # define freea(p) ((void) (p)) | 52 | # endif |
| 53 | # define GCC_LINT 1 | ||
| 54 | # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) | ||
| 50 | #else | 55 | #else |
| 51 | # define __canonicalize_file_name canonicalize_file_name | 56 | # define __canonicalize_file_name canonicalize_file_name |
| 52 | # define __realpath realpath | 57 | # define __realpath realpath |
| 53 | # include "idx.h" | ||
| 54 | # include "pathmax.h" | 58 | # include "pathmax.h" |
| 55 | # include "filename.h" | 59 | # define __faccessat faccessat |
| 56 | # if defined _WIN32 && !defined __CYGWIN__ | 60 | # if defined _WIN32 && !defined __CYGWIN__ |
| 57 | # define __getcwd _getcwd | 61 | # define __getcwd _getcwd |
| 58 | # elif HAVE_GETCWD | 62 | # elif HAVE_GETCWD |
| @@ -77,22 +81,95 @@ typedef ptrdiff_t idx_t; | |||
| 77 | # define __pathconf pathconf | 81 | # define __pathconf pathconf |
| 78 | # define __rawmemchr rawmemchr | 82 | # define __rawmemchr rawmemchr |
| 79 | # define __readlink readlink | 83 | # define __readlink readlink |
| 80 | # ifndef MAXSYMLINKS | 84 | # define __stat stat |
| 81 | # ifdef SYMLOOP_MAX | 85 | #endif |
| 82 | # define MAXSYMLINKS SYMLOOP_MAX | 86 | |
| 83 | # else | 87 | /* Suppress bogus GCC -Wmaybe-uninitialized warnings. */ |
| 84 | # define MAXSYMLINKS 20 | 88 | #if defined GCC_LINT || defined lint |
| 85 | # endif | 89 | # define IF_LINT(Code) Code |
| 86 | # endif | 90 | #else |
| 87 | # define __eloop_threshold() MAXSYMLINKS | 91 | # define IF_LINT(Code) /* empty */ |
| 88 | #endif | 92 | #endif |
| 89 | 93 | ||
| 90 | #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT | 94 | #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT |
| 91 | # define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 | 95 | # define DOUBLE_SLASH_IS_DISTINCT_ROOT false |
| 96 | #endif | ||
| 97 | #ifndef FACCESSAT_NEVER_EOVERFLOWS | ||
| 98 | # define FACCESSAT_NEVER_EOVERFLOWS false | ||
| 92 | #endif | 99 | #endif |
| 93 | 100 | ||
| 94 | #if !FUNC_REALPATH_WORKS || defined _LIBC | 101 | #if !FUNC_REALPATH_WORKS || defined _LIBC |
| 95 | 102 | ||
| 103 | /* Return true if FILE's existence can be shown, false (setting errno) | ||
| 104 | otherwise. Follow symbolic links. */ | ||
| 105 | static bool | ||
| 106 | file_accessible (char const *file) | ||
| 107 | { | ||
| 108 | # if defined _LIBC || HAVE_FACCESSAT | ||
| 109 | int r = __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS); | ||
| 110 | # else | ||
| 111 | struct stat st; | ||
| 112 | int r = __stat (file, &st); | ||
| 113 | # endif | ||
| 114 | |||
| 115 | return ((!FACCESSAT_NEVER_EOVERFLOWS && r < 0 && errno == EOVERFLOW) | ||
| 116 | || r == 0); | ||
| 117 | } | ||
| 118 | |||
| 119 | /* True if concatenating END as a suffix to a file name means that the | ||
| 120 | code needs to check that the file name is that of a searchable | ||
| 121 | directory, since the canonicalize_filename_mode_stk code won't | ||
| 122 | check this later anyway when it checks an ordinary file name | ||
| 123 | component within END. END must either be empty, or start with a | ||
| 124 | slash. */ | ||
| 125 | |||
| 126 | static bool _GL_ATTRIBUTE_PURE | ||
| 127 | suffix_requires_dir_check (char const *end) | ||
| 128 | { | ||
| 129 | /* If END does not start with a slash, the suffix is OK. */ | ||
| 130 | while (ISSLASH (*end)) | ||
| 131 | { | ||
| 132 | /* Two or more slashes act like a single slash. */ | ||
| 133 | do | ||
| 134 | end++; | ||
| 135 | while (ISSLASH (*end)); | ||
| 136 | |||
| 137 | switch (*end++) | ||
| 138 | { | ||
| 139 | default: return false; /* An ordinary file name component is OK. */ | ||
| 140 | case '\0': return true; /* Trailing "/" is trouble. */ | ||
| 141 | case '.': break; /* Possibly "." or "..". */ | ||
| 142 | } | ||
| 143 | /* Trailing "/.", or "/.." even if not trailing, is trouble. */ | ||
| 144 | if (!*end || (*end == '.' && (!end[1] || ISSLASH (end[1])))) | ||
| 145 | return true; | ||
| 146 | } | ||
| 147 | |||
| 148 | return false; | ||
| 149 | } | ||
| 150 | |||
| 151 | /* Append this to a file name to test whether it is a searchable directory. | ||
| 152 | On POSIX platforms "/" suffices, but "/./" is sometimes needed on | ||
| 153 | macOS 10.13 <https://bugs.gnu.org/30350>, and should also work on | ||
| 154 | platforms like AIX 7.2 that need at least "/.". */ | ||
| 155 | |||
| 156 | #if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK | ||
| 157 | static char const dir_suffix[] = "/"; | ||
| 158 | #else | ||
| 159 | static char const dir_suffix[] = "/./"; | ||
| 160 | #endif | ||
| 161 | |||
| 162 | /* Return true if DIR is a searchable dir, false (setting errno) otherwise. | ||
| 163 | DIREND points to the NUL byte at the end of the DIR string. | ||
| 164 | Store garbage into DIREND[0 .. strlen (dir_suffix)]. */ | ||
| 165 | |||
| 166 | static bool | ||
| 167 | dir_check (char *dir, char *dirend) | ||
| 168 | { | ||
| 169 | strcpy (dirend, dir_suffix); | ||
| 170 | return file_accessible (dir); | ||
| 171 | } | ||
| 172 | |||
| 96 | static idx_t | 173 | static idx_t |
| 97 | get_path_max (void) | 174 | get_path_max (void) |
| 98 | { | 175 | { |
| @@ -111,19 +188,27 @@ get_path_max (void) | |||
| 111 | return path_max < 0 ? 1024 : path_max <= IDX_MAX ? path_max : IDX_MAX; | 188 | return path_max < 0 ? 1024 : path_max <= IDX_MAX ? path_max : IDX_MAX; |
| 112 | } | 189 | } |
| 113 | 190 | ||
| 114 | /* Return the canonical absolute name of file NAME. A canonical name | 191 | /* Act like __realpath (see below), with an additional argument |
| 115 | does not contain any ".", ".." components nor any repeated file name | 192 | rname_buf that can be used as temporary storage. |
| 116 | separators ('/') or symlinks. All file name components must exist. If | 193 | |
| 117 | RESOLVED is null, the result is malloc'd; otherwise, if the | 194 | If GCC_LINT is defined, do not inline this function with GCC 10.1 |
| 118 | canonical name is PATH_MAX chars or more, returns null with 'errno' | 195 | and later, to avoid creating a pointer to the stack that GCC |
| 119 | set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, | 196 | -Wreturn-local-addr incorrectly complains about. See: |
| 120 | returns the name in RESOLVED. If the name cannot be resolved and | 197 | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644 |
| 121 | RESOLVED is non-NULL, it contains the name of the first component | 198 | Although the noinline attribute can hurt performance a bit, no better way |
| 122 | that cannot be resolved. If the name can be resolved, RESOLVED | 199 | to pacify GCC is known; even an explicit #pragma does not pacify GCC. |
| 123 | holds the same value as the value returned. */ | 200 | When the GCC bug is fixed this workaround should be limited to the |
| 124 | 201 | broken GCC versions. */ | |
| 125 | char * | 202 | #if __GNUC_PREREQ (10, 1) |
| 126 | __realpath (const char *name, char *resolved) | 203 | # if defined GCC_LINT || defined lint |
| 204 | __attribute__ ((__noinline__)) | ||
| 205 | # elif __OPTIMIZE__ && !__NO_INLINE__ | ||
| 206 | # define GCC_BOGUS_WRETURN_LOCAL_ADDR | ||
| 207 | # endif | ||
| 208 | #endif | ||
| 209 | static char * | ||
| 210 | realpath_stk (const char *name, char *resolved, | ||
| 211 | struct scratch_buffer *rname_buf) | ||
| 127 | { | 212 | { |
| 128 | char *dest; | 213 | char *dest; |
| 129 | char const *start; | 214 | char const *start; |
| @@ -149,8 +234,6 @@ __realpath (const char *name, char *resolved) | |||
| 149 | } | 234 | } |
| 150 | 235 | ||
| 151 | struct scratch_buffer extra_buffer, link_buffer; | 236 | struct scratch_buffer extra_buffer, link_buffer; |
| 152 | struct scratch_buffer rname_buffer; | ||
| 153 | struct scratch_buffer *rname_buf = &rname_buffer; | ||
| 154 | scratch_buffer_init (&extra_buffer); | 237 | scratch_buffer_init (&extra_buffer); |
| 155 | scratch_buffer_init (&link_buffer); | 238 | scratch_buffer_init (&link_buffer); |
| 156 | scratch_buffer_init (rname_buf); | 239 | scratch_buffer_init (rname_buf); |
| @@ -208,7 +291,9 @@ __realpath (const char *name, char *resolved) | |||
| 208 | name ends in '/'. */ | 291 | name ends in '/'. */ |
| 209 | idx_t startlen = end - start; | 292 | idx_t startlen = end - start; |
| 210 | 293 | ||
| 211 | if (startlen == 1 && start[0] == '.') | 294 | if (startlen == 0) |
| 295 | break; | ||
| 296 | else if (startlen == 1 && start[0] == '.') | ||
| 212 | /* nothing */; | 297 | /* nothing */; |
| 213 | else if (startlen == 2 && start[0] == '.' && start[1] == '.') | 298 | else if (startlen == 2 && start[0] == '.' && start[1] == '.') |
| 214 | { | 299 | { |
| @@ -226,7 +311,8 @@ __realpath (const char *name, char *resolved) | |||
| 226 | if (!ISSLASH (dest[-1])) | 311 | if (!ISSLASH (dest[-1])) |
| 227 | *dest++ = '/'; | 312 | *dest++ = '/'; |
| 228 | 313 | ||
| 229 | while (rname + rname_buf->length - dest <= startlen) | 314 | while (rname + rname_buf->length - dest |
| 315 | < startlen + sizeof dir_suffix) | ||
| 230 | { | 316 | { |
| 231 | idx_t dest_offset = dest - rname; | 317 | idx_t dest_offset = dest - rname; |
| 232 | if (!scratch_buffer_grow_preserve (rname_buf)) | 318 | if (!scratch_buffer_grow_preserve (rname_buf)) |
| @@ -238,28 +324,19 @@ __realpath (const char *name, char *resolved) | |||
| 238 | dest = __mempcpy (dest, start, startlen); | 324 | dest = __mempcpy (dest, start, startlen); |
| 239 | *dest = '\0'; | 325 | *dest = '\0'; |
| 240 | 326 | ||
| 241 | /* If STARTLEN == 0, RNAME ends in '/'; use stat rather than | 327 | char *buf; |
| 242 | readlink, because readlink might fail with EINVAL without | ||
| 243 | checking whether RNAME sans '/' is valid. */ | ||
| 244 | struct stat st; | ||
| 245 | char *buf = NULL; | ||
| 246 | ssize_t n; | 328 | ssize_t n; |
| 247 | if (startlen != 0) | 329 | while (true) |
| 248 | { | 330 | { |
| 249 | while (true) | 331 | buf = link_buffer.data; |
| 250 | { | 332 | idx_t bufsize = link_buffer.length; |
| 251 | buf = link_buffer.data; | 333 | n = __readlink (rname, buf, bufsize - 1); |
| 252 | idx_t bufsize = link_buffer.length; | 334 | if (n < bufsize - 1) |
| 253 | n = __readlink (rname, buf, bufsize - 1); | 335 | break; |
| 254 | if (n < bufsize - 1) | 336 | if (!scratch_buffer_grow (&link_buffer)) |
| 255 | break; | 337 | goto error_nomem; |
| 256 | if (!scratch_buffer_grow (&link_buffer)) | ||
| 257 | goto error_nomem; | ||
| 258 | } | ||
| 259 | if (n < 0) | ||
| 260 | buf = NULL; | ||
| 261 | } | 338 | } |
| 262 | if (buf) | 339 | if (0 <= n) |
| 263 | { | 340 | { |
| 264 | if (++num_links > __eloop_threshold ()) | 341 | if (++num_links > __eloop_threshold ()) |
| 265 | { | 342 | { |
| @@ -270,7 +347,7 @@ __realpath (const char *name, char *resolved) | |||
| 270 | buf[n] = '\0'; | 347 | buf[n] = '\0'; |
| 271 | 348 | ||
| 272 | char *extra_buf = extra_buffer.data; | 349 | char *extra_buf = extra_buffer.data; |
| 273 | idx_t end_idx; | 350 | idx_t end_idx IF_LINT (= 0); |
| 274 | if (end_in_extra_buffer) | 351 | if (end_in_extra_buffer) |
| 275 | end_idx = end - extra_buf; | 352 | end_idx = end - extra_buf; |
| 276 | idx_t len = strlen (end); | 353 | idx_t len = strlen (end); |
| @@ -315,8 +392,8 @@ __realpath (const char *name, char *resolved) | |||
| 315 | dest++; | 392 | dest++; |
| 316 | } | 393 | } |
| 317 | } | 394 | } |
| 318 | else if (! (startlen == 0 | 395 | else if (! (suffix_requires_dir_check (end) |
| 319 | ? stat (rname, &st) == 0 || errno == EOVERFLOW | 396 | ? dir_check (rname, dest) |
| 320 | : errno == EINVAL)) | 397 | : errno == EINVAL)) |
| 321 | goto error; | 398 | goto error; |
| 322 | } | 399 | } |
| @@ -355,6 +432,28 @@ error_nomem: | |||
| 355 | char *result = realloc (rname, rname_size); | 432 | char *result = realloc (rname, rname_size); |
| 356 | return result != NULL ? result : rname; | 433 | return result != NULL ? result : rname; |
| 357 | } | 434 | } |
| 435 | |||
| 436 | /* Return the canonical absolute name of file NAME. A canonical name | ||
| 437 | does not contain any ".", ".." components nor any repeated file name | ||
| 438 | separators ('/') or symlinks. All file name components must exist. If | ||
| 439 | RESOLVED is null, the result is malloc'd; otherwise, if the | ||
| 440 | canonical name is PATH_MAX chars or more, returns null with 'errno' | ||
| 441 | set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, | ||
| 442 | returns the name in RESOLVED. If the name cannot be resolved and | ||
| 443 | RESOLVED is non-NULL, it contains the name of the first component | ||
| 444 | that cannot be resolved. If the name can be resolved, RESOLVED | ||
| 445 | holds the same value as the value returned. */ | ||
| 446 | |||
| 447 | char * | ||
| 448 | __realpath (const char *name, char *resolved) | ||
| 449 | { | ||
| 450 | #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR | ||
| 451 | #warning "GCC might issue a bogus -Wreturn-local-addr warning here." | ||
| 452 | #warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>." | ||
| 453 | #endif | ||
| 454 | struct scratch_buffer rname_buffer; | ||
| 455 | return realpath_stk (name, resolved, &rname_buffer); | ||
| 456 | } | ||
| 358 | libc_hidden_def (__realpath) | 457 | libc_hidden_def (__realpath) |
| 359 | versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); | 458 | versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); |
| 360 | #endif /* !FUNC_REALPATH_WORKS || defined _LIBC */ | 459 | #endif /* !FUNC_REALPATH_WORKS || defined _LIBC */ |
diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c index 26fe84df55e..6aaa712b9be 100644 --- a/lib/careadlinkat.c +++ b/lib/careadlinkat.c | |||
| @@ -55,8 +55,7 @@ enum { STACK_BUF_SIZE = 1024 }; | |||
| 55 | # if defined GCC_LINT || defined lint | 55 | # if defined GCC_LINT || defined lint |
| 56 | __attribute__ ((__noinline__)) | 56 | __attribute__ ((__noinline__)) |
| 57 | # elif __OPTIMIZE__ && !__NO_INLINE__ | 57 | # elif __OPTIMIZE__ && !__NO_INLINE__ |
| 58 | # warning "GCC might issue a bogus -Wreturn-local-addr warning here." | 58 | # define GCC_BOGUS_WRETURN_LOCAL_ADDR |
| 59 | # warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>." | ||
| 60 | # endif | 59 | # endif |
| 61 | #endif | 60 | #endif |
| 62 | static char * | 61 | static char * |
| @@ -180,10 +179,11 @@ careadlinkat (int fd, char const *filename, | |||
| 180 | /* Allocate the initial buffer on the stack. This way, in the | 179 | /* Allocate the initial buffer on the stack. This way, in the |
| 181 | common case of a symlink of small size, we get away with a | 180 | common case of a symlink of small size, we get away with a |
| 182 | single small malloc instead of a big malloc followed by a | 181 | single small malloc instead of a big malloc followed by a |
| 183 | shrinking realloc. | 182 | shrinking realloc. */ |
| 184 | 183 | #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR | |
| 185 | If GCC -Wreturn-local-addr warns about this buffer, the warning | 184 | #warning "GCC might issue a bogus -Wreturn-local-addr warning here." |
| 186 | is bogus; see readlink_stk. */ | 185 | #warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>." |
| 186 | #endif | ||
| 187 | char stack_buf[STACK_BUF_SIZE]; | 187 | char stack_buf[STACK_BUF_SIZE]; |
| 188 | return readlink_stk (fd, filename, buffer, buffer_size, alloc, | 188 | return readlink_stk (fd, filename, buffer, buffer_size, alloc, |
| 189 | preadlinkat, stack_buf); | 189 | preadlinkat, stack_buf); |
diff --git a/lib/eloop-threshold.h b/lib/eloop-threshold.h new file mode 100644 index 00000000000..5953a4cc065 --- /dev/null +++ b/lib/eloop-threshold.h | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | /* Threshold at which to diagnose ELOOP. Generic version. | ||
| 2 | Copyright (C) 2012-2020 Free Software Foundation, Inc. | ||
| 3 | This file is part of the GNU C Library. | ||
| 4 | |||
| 5 | The GNU C Library is free software; you can redistribute it and/or | ||
| 6 | modify it under the terms of the GNU General Public | ||
| 7 | License as published by the Free Software Foundation; either | ||
| 8 | version 3 of the License, or (at your option) any later version. | ||
| 9 | |||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public | ||
| 16 | License along with the GNU C Library; if not, see | ||
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _ELOOP_THRESHOLD_H | ||
| 20 | #define _ELOOP_THRESHOLD_H 1 | ||
| 21 | |||
| 22 | #include <limits.h> | ||
| 23 | #ifdef _LIBC | ||
| 24 | # include <sys/param.h> | ||
| 25 | # define _GL_ATTRIBUTE_CONST __attribute__ ((const)) | ||
| 26 | #else | ||
| 27 | # include <unistd.h> | ||
| 28 | # include "minmax.h" | ||
| 29 | # define __sysconf sysconf | ||
| 30 | # if (!defined SYMLOOP_MAX \ | ||
| 31 | && ! (defined _SC_SYMLOOP_MAX && defined _POSIX_SYMLOOP_MAX)) | ||
| 32 | # define SYMLOOP_MAX 8 | ||
| 33 | # endif | ||
| 34 | #endif | ||
| 35 | |||
| 36 | /* POSIX specifies SYMLOOP_MAX as the "Maximum number of symbolic | ||
| 37 | links that can be reliably traversed in the resolution of a | ||
| 38 | pathname in the absence of a loop." This makes it a minimum that | ||
| 39 | we should certainly accept. But it leaves open the possibility | ||
| 40 | that more might sometimes work--just not "reliably". | ||
| 41 | |||
| 42 | For example, Linux implements a complex policy whereby there is a | ||
| 43 | small limit on the number of direct symlink traversals (a symlink | ||
| 44 | to a symlink to a symlink), but larger limit on the total number of | ||
| 45 | symlink traversals overall. Hence the SYMLOOP_MAX number should be | ||
| 46 | the small one, but the limit library functions enforce on users | ||
| 47 | should be the larger one. | ||
| 48 | |||
| 49 | So, we use the larger of the reported SYMLOOP_MAX (if any) and our | ||
| 50 | own constant MIN_ELOOP_THRESHOLD, below. This constant should be | ||
| 51 | large enough that it never rules out a file name and directory tree | ||
| 52 | that the underlying system (i.e. calls to 'open' et al) would | ||
| 53 | resolve successfully. It should be small enough that actual loops | ||
| 54 | are detected without a huge number of iterations. */ | ||
| 55 | |||
| 56 | #ifndef MIN_ELOOP_THRESHOLD | ||
| 57 | # define MIN_ELOOP_THRESHOLD 40 | ||
| 58 | #endif | ||
| 59 | |||
| 60 | /* Return the maximum number of symlink traversals to permit | ||
| 61 | before diagnosing ELOOP. */ | ||
| 62 | static inline unsigned int _GL_ATTRIBUTE_CONST | ||
| 63 | __eloop_threshold (void) | ||
| 64 | { | ||
| 65 | #ifdef SYMLOOP_MAX | ||
| 66 | const int symloop_max = SYMLOOP_MAX; | ||
| 67 | #else | ||
| 68 | /* The function is marked 'const' even though we use memory and | ||
| 69 | call a function, because sysconf is required to return the | ||
| 70 | same value in every call and so it must always be safe to | ||
| 71 | call __eloop_threshold exactly once and reuse the value. */ | ||
| 72 | static long int sysconf_symloop_max; | ||
| 73 | if (sysconf_symloop_max == 0) | ||
| 74 | sysconf_symloop_max = __sysconf (_SC_SYMLOOP_MAX); | ||
| 75 | const unsigned int symloop_max = (sysconf_symloop_max <= 0 | ||
| 76 | ? _POSIX_SYMLOOP_MAX | ||
| 77 | : sysconf_symloop_max); | ||
| 78 | #endif | ||
| 79 | |||
| 80 | return MAX (symloop_max, MIN_ELOOP_THRESHOLD); | ||
| 81 | } | ||
| 82 | |||
| 83 | #endif /* eloop-threshold.h */ | ||
diff --git a/lib/euidaccess.c b/lib/euidaccess.c index b352123ae18..a32e3366eb8 100644 --- a/lib/euidaccess.c +++ b/lib/euidaccess.c | |||
| @@ -107,7 +107,10 @@ euidaccess (const char *file, int mode) | |||
| 107 | safe. */ | 107 | safe. */ |
| 108 | 108 | ||
| 109 | if (mode == F_OK) | 109 | if (mode == F_OK) |
| 110 | return stat (file, &stats); | 110 | { |
| 111 | int result = stat (file, &stats); | ||
| 112 | return result != 0 && errno == EOVERFLOW ? 0 : result; | ||
| 113 | } | ||
| 111 | else | 114 | else |
| 112 | { | 115 | { |
| 113 | int result; | 116 | int result; |
| @@ -142,8 +145,8 @@ euidaccess (const char *file, int mode) | |||
| 142 | /* If we are not set-uid or set-gid, access does the same. */ | 145 | /* If we are not set-uid or set-gid, access does the same. */ |
| 143 | return access (file, mode); | 146 | return access (file, mode); |
| 144 | 147 | ||
| 145 | if (stat (file, &stats) != 0) | 148 | if (stat (file, &stats) == -1) |
| 146 | return -1; | 149 | return mode == F_OK && errno == EOVERFLOW ? 0 : -1; |
| 147 | 150 | ||
| 148 | /* The super-user can read and write any file, and execute any file | 151 | /* The super-user can read and write any file, and execute any file |
| 149 | that anyone can execute. */ | 152 | that anyone can execute. */ |
diff --git a/lib/faccessat.c b/lib/faccessat.c index 9f6a11bf6e3..330c54a0be2 100644 --- a/lib/faccessat.c +++ b/lib/faccessat.c | |||
| @@ -32,6 +32,13 @@ | |||
| 32 | #include <sys/stat.h> | 32 | #include <sys/stat.h> |
| 33 | #undef _GL_INCLUDING_UNISTD_H | 33 | #undef _GL_INCLUDING_UNISTD_H |
| 34 | 34 | ||
| 35 | #ifndef FACCESSAT_NEVER_EOVERFLOWS | ||
| 36 | # define FACCESSAT_NEVER_EOVERFLOWS 0 | ||
| 37 | #endif | ||
| 38 | #ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK | ||
| 39 | # define LSTAT_FOLLOWS_SLASHED_SYMLINK 0 | ||
| 40 | #endif | ||
| 41 | |||
| 35 | #if HAVE_FACCESSAT | 42 | #if HAVE_FACCESSAT |
| 36 | static int | 43 | static int |
| 37 | orig_faccessat (int fd, char const *name, int mode, int flag) | 44 | orig_faccessat (int fd, char const *name, int mode, int flag) |
| @@ -59,7 +66,12 @@ rpl_faccessat (int fd, char const *file, int mode, int flag) | |||
| 59 | { | 66 | { |
| 60 | int result = orig_faccessat (fd, file, mode, flag); | 67 | int result = orig_faccessat (fd, file, mode, flag); |
| 61 | 68 | ||
| 62 | if (result == 0 && file[strlen (file) - 1] == '/') | 69 | if (result != 0) |
| 70 | { | ||
| 71 | if (!FACCESSAT_NEVER_EOVERFLOWS && mode == F_OK && errno == EOVERFLOW) | ||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | else if (!LSTAT_FOLLOWS_SLASHED_SYMLINK && file[strlen (file) - 1] == '/') | ||
| 63 | { | 75 | { |
| 64 | struct stat st; | 76 | struct stat st; |
| 65 | result = fstatat (fd, file, &st, 0); | 77 | result = fstatat (fd, file, &st, 0); |
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index df533fa6740..a37f9278a31 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in | |||
| @@ -103,6 +103,7 @@ | |||
| 103 | # filevercmp \ | 103 | # filevercmp \ |
| 104 | # flexmember \ | 104 | # flexmember \ |
| 105 | # fpieee \ | 105 | # fpieee \ |
| 106 | # free-posix \ | ||
| 106 | # fstatat \ | 107 | # fstatat \ |
| 107 | # fsusage \ | 108 | # fsusage \ |
| 108 | # fsync \ | 109 | # fsync \ |
| @@ -1528,6 +1529,17 @@ EXTRA_libgnu_a_SOURCES += dup2.c | |||
| 1528 | endif | 1529 | endif |
| 1529 | ## end gnulib module dup2 | 1530 | ## end gnulib module dup2 |
| 1530 | 1531 | ||
| 1532 | ## begin gnulib module eloop-threshold | ||
| 1533 | ifeq (,$(OMIT_GNULIB_MODULE_eloop-threshold)) | ||
| 1534 | |||
| 1535 | ifneq (,$(gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c)) | ||
| 1536 | |||
| 1537 | endif | ||
| 1538 | EXTRA_DIST += eloop-threshold.h | ||
| 1539 | |||
| 1540 | endif | ||
| 1541 | ## end gnulib module eloop-threshold | ||
| 1542 | |||
| 1531 | ## begin gnulib module errno | 1543 | ## begin gnulib module errno |
| 1532 | ifeq (,$(OMIT_GNULIB_MODULE_errno)) | 1544 | ifeq (,$(OMIT_GNULIB_MODULE_errno)) |
| 1533 | 1545 | ||
| @@ -1750,9 +1762,7 @@ endif | |||
| 1750 | ## begin gnulib module free-posix | 1762 | ## begin gnulib module free-posix |
| 1751 | ifeq (,$(OMIT_GNULIB_MODULE_free-posix)) | 1763 | ifeq (,$(OMIT_GNULIB_MODULE_free-posix)) |
| 1752 | 1764 | ||
| 1753 | ifneq (,$(gl_GNULIB_ENABLED_ef07dc4b3077c11ea9cef586db4e5955)) | ||
| 1754 | 1765 | ||
| 1755 | endif | ||
| 1756 | EXTRA_DIST += free.c | 1766 | EXTRA_DIST += free.c |
| 1757 | 1767 | ||
| 1758 | EXTRA_libgnu_a_SOURCES += free.c | 1768 | EXTRA_libgnu_a_SOURCES += free.c |
diff --git a/lib/mini-gmp.c b/lib/mini-gmp.c index 2e0301b0081..d34fe525e4c 100644 --- a/lib/mini-gmp.c +++ b/lib/mini-gmp.c | |||
| @@ -32,7 +32,7 @@ see https://www.gnu.org/licenses/. */ | |||
| 32 | 32 | ||
| 33 | /* NOTE: All functions in this file which are not declared in | 33 | /* NOTE: All functions in this file which are not declared in |
| 34 | mini-gmp.h are internal, and are not intended to be compatible | 34 | mini-gmp.h are internal, and are not intended to be compatible |
| 35 | neither with GMP nor with future versions of mini-gmp. */ | 35 | with GMP or with future versions of mini-gmp. */ |
| 36 | 36 | ||
| 37 | /* Much of the material copied from GMP files, including: gmp-impl.h, | 37 | /* Much of the material copied from GMP files, including: gmp-impl.h, |
| 38 | longlong.h, mpn/generic/add_n.c, mpn/generic/addmul_1.c, | 38 | longlong.h, mpn/generic/add_n.c, mpn/generic/addmul_1.c, |
| @@ -1331,29 +1331,26 @@ mpn_set_str_bits (mp_ptr rp, const unsigned char *sp, size_t sn, | |||
| 1331 | unsigned bits) | 1331 | unsigned bits) |
| 1332 | { | 1332 | { |
| 1333 | mp_size_t rn; | 1333 | mp_size_t rn; |
| 1334 | size_t j; | 1334 | mp_limb_t limb; |
| 1335 | unsigned shift; | 1335 | unsigned shift; |
| 1336 | 1336 | ||
| 1337 | for (j = sn, rn = 0, shift = 0; j-- > 0; ) | 1337 | for (limb = 0, rn = 0, shift = 0; sn-- > 0; ) |
| 1338 | { | 1338 | { |
| 1339 | if (shift == 0) | 1339 | limb |= (mp_limb_t) sp[sn] << shift; |
| 1340 | { | 1340 | shift += bits; |
| 1341 | rp[rn++] = sp[j]; | 1341 | if (shift >= GMP_LIMB_BITS) |
| 1342 | shift += bits; | ||
| 1343 | } | ||
| 1344 | else | ||
| 1345 | { | 1342 | { |
| 1346 | rp[rn-1] |= (mp_limb_t) sp[j] << shift; | 1343 | shift -= GMP_LIMB_BITS; |
| 1347 | shift += bits; | 1344 | rp[rn++] = limb; |
| 1348 | if (shift >= GMP_LIMB_BITS) | 1345 | /* Next line is correct also if shift == 0, |
| 1349 | { | 1346 | bits == 8, and mp_limb_t == unsigned char. */ |
| 1350 | shift -= GMP_LIMB_BITS; | 1347 | limb = (unsigned int) sp[sn] >> (bits - shift); |
| 1351 | if (shift > 0) | ||
| 1352 | rp[rn++] = (mp_limb_t) sp[j] >> (bits - shift); | ||
| 1353 | } | ||
| 1354 | } | 1348 | } |
| 1355 | } | 1349 | } |
| 1356 | rn = mpn_normalized_size (rp, rn); | 1350 | if (limb != 0) |
| 1351 | rp[rn++] = limb; | ||
| 1352 | else | ||
| 1353 | rn = mpn_normalized_size (rp, rn); | ||
| 1357 | return rn; | 1354 | return rn; |
| 1358 | } | 1355 | } |
| 1359 | 1356 | ||
| @@ -2723,7 +2720,7 @@ mpz_make_odd (mpz_t r) | |||
| 2723 | 2720 | ||
| 2724 | assert (r->_mp_size > 0); | 2721 | assert (r->_mp_size > 0); |
| 2725 | /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */ | 2722 | /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */ |
| 2726 | shift = mpn_common_scan (r->_mp_d[0], 0, r->_mp_d, 0, 0); | 2723 | shift = mpn_scan1 (r->_mp_d, 0); |
| 2727 | mpz_tdiv_q_2exp (r, r, shift); | 2724 | mpz_tdiv_q_2exp (r, r, shift); |
| 2728 | 2725 | ||
| 2729 | return shift; | 2726 | return shift; |
| @@ -2780,9 +2777,13 @@ mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v) | |||
| 2780 | 2777 | ||
| 2781 | if (tv->_mp_size == 1) | 2778 | if (tv->_mp_size == 1) |
| 2782 | { | 2779 | { |
| 2783 | mp_limb_t vl = tv->_mp_d[0]; | 2780 | mp_limb_t *gp; |
| 2784 | mp_limb_t ul = mpz_tdiv_ui (tu, vl); | 2781 | |
| 2785 | mpz_set_ui (g, mpn_gcd_11 (ul, vl)); | 2782 | mpz_tdiv_r (tu, tu, tv); |
| 2783 | gp = MPZ_REALLOC (g, 1); /* gp = mpz_limbs_modify (g, 1); */ | ||
| 2784 | *gp = mpn_gcd_11 (tu->_mp_d[0], tv->_mp_d[0]); | ||
| 2785 | |||
| 2786 | g->_mp_size = *gp != 0; /* mpz_limbs_finish (g, 1); */ | ||
| 2786 | break; | 2787 | break; |
| 2787 | } | 2788 | } |
| 2788 | mpz_sub (tu, tu, tv); | 2789 | mpz_sub (tu, tu, tv); |
| @@ -2871,7 +2872,6 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) | |||
| 2871 | * s0 = 0, s1 = 2^vz | 2872 | * s0 = 0, s1 = 2^vz |
| 2872 | */ | 2873 | */ |
| 2873 | 2874 | ||
| 2874 | mpz_setbit (t0, uz); | ||
| 2875 | mpz_tdiv_qr (t1, tu, tu, tv); | 2875 | mpz_tdiv_qr (t1, tu, tu, tv); |
| 2876 | mpz_mul_2exp (t1, t1, uz); | 2876 | mpz_mul_2exp (t1, t1, uz); |
| 2877 | 2877 | ||
| @@ -2882,8 +2882,7 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) | |||
| 2882 | { | 2882 | { |
| 2883 | mp_bitcnt_t shift; | 2883 | mp_bitcnt_t shift; |
| 2884 | shift = mpz_make_odd (tu); | 2884 | shift = mpz_make_odd (tu); |
| 2885 | mpz_mul_2exp (t0, t0, shift); | 2885 | mpz_setbit (t0, uz + shift); |
| 2886 | mpz_mul_2exp (s0, s0, shift); | ||
| 2887 | power += shift; | 2886 | power += shift; |
| 2888 | 2887 | ||
| 2889 | for (;;) | 2888 | for (;;) |
| @@ -2921,6 +2920,8 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) | |||
| 2921 | power += shift; | 2920 | power += shift; |
| 2922 | } | 2921 | } |
| 2923 | } | 2922 | } |
| 2923 | else | ||
| 2924 | mpz_setbit (t0, uz); | ||
| 2924 | 2925 | ||
| 2925 | /* Now tv = odd part of gcd, and -s0 and t0 are corresponding | 2926 | /* Now tv = odd part of gcd, and -s0 and t0 are corresponding |
| 2926 | cofactors. */ | 2927 | cofactors. */ |
| @@ -3604,7 +3605,8 @@ mpz_probab_prime_p (const mpz_t n, int reps) | |||
| 3604 | /* Find q and k, where q is odd and n = 1 + 2**k * q. */ | 3605 | /* Find q and k, where q is odd and n = 1 + 2**k * q. */ |
| 3605 | mpz_abs (nm1, n); | 3606 | mpz_abs (nm1, n); |
| 3606 | nm1->_mp_d[0] -= 1; | 3607 | nm1->_mp_d[0] -= 1; |
| 3607 | k = mpz_scan1 (nm1, 0); | 3608 | /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */ |
| 3609 | k = mpn_scan1 (nm1->_mp_d, 0); | ||
| 3608 | mpz_tdiv_q_2exp (q, nm1, k); | 3610 | mpz_tdiv_q_2exp (q, nm1, k); |
| 3609 | 3611 | ||
| 3610 | /* BPSW test */ | 3612 | /* BPSW test */ |
| @@ -4301,7 +4303,7 @@ mpz_get_str (char *sp, int base, const mpz_t u) | |||
| 4301 | ret: | 4303 | ret: |
| 4302 | sp[sn] = '\0'; | 4304 | sp[sn] = '\0'; |
| 4303 | if (osn && osn != sn + 1) | 4305 | if (osn && osn != sn + 1) |
| 4304 | sp = gmp_realloc(sp, osn, sn + 1); | 4306 | sp = (char*) gmp_realloc (sp, osn, sn + 1); |
| 4305 | return sp; | 4307 | return sp; |
| 4306 | } | 4308 | } |
| 4307 | 4309 | ||
| @@ -4425,6 +4427,8 @@ mpz_out_str (FILE *stream, int base, const mpz_t x) | |||
| 4425 | size_t len, n; | 4427 | size_t len, n; |
| 4426 | 4428 | ||
| 4427 | str = mpz_get_str (NULL, base, x); | 4429 | str = mpz_get_str (NULL, base, x); |
| 4430 | if (!str) | ||
| 4431 | return 0; | ||
| 4428 | len = strlen (str); | 4432 | len = strlen (str); |
| 4429 | n = fwrite (str, 1, len, stream); | 4433 | n = fwrite (str, 1, len, stream); |
| 4430 | gmp_free (str, len + 1); | 4434 | gmp_free (str, len + 1); |
diff --git a/lib/mini-gmp.h b/lib/mini-gmp.h index c00568c2568..59a37e64947 100644 --- a/lib/mini-gmp.h +++ b/lib/mini-gmp.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* mini-gmp, a minimalistic implementation of a GNU GMP subset. | 1 | /* mini-gmp, a minimalistic implementation of a GNU GMP subset. |
| 2 | 2 | ||
| 3 | Copyright 2011-2015, 2017, 2019 Free Software Foundation, Inc. | 3 | Copyright 2011-2015, 2017, 2019-2020 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of the GNU MP Library. | 5 | This file is part of the GNU MP Library. |
| 6 | 6 | ||
| @@ -295,7 +295,8 @@ int mpz_init_set_str (mpz_t, const char *, int); | |||
| 295 | || defined (_MSL_STDIO_H) /* Metrowerks */ \ | 295 | || defined (_MSL_STDIO_H) /* Metrowerks */ \ |
| 296 | || defined (_STDIO_H_INCLUDED) /* QNX4 */ \ | 296 | || defined (_STDIO_H_INCLUDED) /* QNX4 */ \ |
| 297 | || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \ | 297 | || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \ |
| 298 | || defined (__STDIO_LOADED) /* VMS */ | 298 | || defined (__STDIO_LOADED) /* VMS */ \ |
| 299 | || defined (__DEFINED_FILE) /* musl */ | ||
| 299 | size_t mpz_out_str (FILE *, int, const mpz_t); | 300 | size_t mpz_out_str (FILE *, int, const mpz_t); |
| 300 | #endif | 301 | #endif |
| 301 | 302 | ||
diff --git a/lib/symlink.c b/lib/symlink.c index e7dbd184a99..b1196b9ee85 100644 --- a/lib/symlink.c +++ b/lib/symlink.c | |||
| @@ -36,7 +36,7 @@ rpl_symlink (char const *contents, char const *name) | |||
| 36 | if (len && name[len - 1] == '/') | 36 | if (len && name[len - 1] == '/') |
| 37 | { | 37 | { |
| 38 | struct stat st; | 38 | struct stat st; |
| 39 | if (lstat (name, &st) == 0) | 39 | if (lstat (name, &st) == 0 || errno == EOVERFLOW) |
| 40 | errno = EEXIST; | 40 | errno = EEXIST; |
| 41 | return -1; | 41 | return -1; |
| 42 | } | 42 | } |