diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2020-12-25 02:33:29 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2020-12-25 02:36:03 -0800 |
commit | 42d58264db165d265cba68d6dbebc53a50738355 (patch) | |
tree | 87543f2f0992a6b57a34dbd6ee04f48c3f6e7486 /lib | |
parent | 5880c7caab394eac55c44d4be42b2f45dbd9bc53 (diff) | |
download | emacs-42d58264db165d265cba68d6dbebc53a50738355.tar.gz |
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 @@ #include <stdlib.h> #include <errno.h> +#include <fcntl.h> #include <limits.h> #include <stdbool.h> #include <stddef.h> @@ -36,23 +37,26 @@ #include <sys/stat.h> #include <unistd.h> +#include <eloop-threshold.h> +#include <filename.h> +#include <idx.h> #include <scratch_buffer.h> #ifdef _LIBC -# include <eloop-threshold.h> # include <shlib-compat.h> -typedef ptrdiff_t idx_t; -# define IDX_MAX PTRDIFF_MAX -# define FILE_SYSTEM_PREFIX_LEN(name) 0 -# define IS_ABSOLUTE_FILE_NAME(name) ISSLASH(*(name)) -# define ISSLASH(c) ((c) == '/') -# define freea(p) ((void) (p)) +# include <sysdep.h> +# ifdef __ASSUME_FACCESSAT2 +# define FACCESSAT_NEVER_EOVERFLOWS __ASSUME_FACCESSAT2 +# else +# define FACCESSAT_NEVER_EOVERFLOWS true +# endif +# define GCC_LINT 1 +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) #else # define __canonicalize_file_name canonicalize_file_name # define __realpath realpath -# include "idx.h" # include "pathmax.h" -# include "filename.h" +# define __faccessat faccessat # if defined _WIN32 && !defined __CYGWIN__ # define __getcwd _getcwd # elif HAVE_GETCWD @@ -77,22 +81,95 @@ typedef ptrdiff_t idx_t; # define __pathconf pathconf # define __rawmemchr rawmemchr # define __readlink readlink -# ifndef MAXSYMLINKS -# ifdef SYMLOOP_MAX -# define MAXSYMLINKS SYMLOOP_MAX -# else -# define MAXSYMLINKS 20 -# endif -# endif -# define __eloop_threshold() MAXSYMLINKS +# define __stat stat +#endif + +/* Suppress bogus GCC -Wmaybe-uninitialized warnings. */ +#if defined GCC_LINT || defined lint +# define IF_LINT(Code) Code +#else +# define IF_LINT(Code) /* empty */ #endif #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT -# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 +# define DOUBLE_SLASH_IS_DISTINCT_ROOT false +#endif +#ifndef FACCESSAT_NEVER_EOVERFLOWS +# define FACCESSAT_NEVER_EOVERFLOWS false #endif #if !FUNC_REALPATH_WORKS || defined _LIBC +/* Return true if FILE's existence can be shown, false (setting errno) + otherwise. Follow symbolic links. */ +static bool +file_accessible (char const *file) +{ +# if defined _LIBC || HAVE_FACCESSAT + int r = __faccessat (AT_FDCWD, file, F_OK, AT_EACCESS); +# else + struct stat st; + int r = __stat (file, &st); +# endif + + return ((!FACCESSAT_NEVER_EOVERFLOWS && r < 0 && errno == EOVERFLOW) + || r == 0); +} + +/* True if concatenating END as a suffix to a file name means that the + code needs to check that the file name is that of a searchable + directory, since the canonicalize_filename_mode_stk code won't + check this later anyway when it checks an ordinary file name + component within END. END must either be empty, or start with a + slash. */ + +static bool _GL_ATTRIBUTE_PURE +suffix_requires_dir_check (char const *end) +{ + /* If END does not start with a slash, the suffix is OK. */ + while (ISSLASH (*end)) + { + /* Two or more slashes act like a single slash. */ + do + end++; + while (ISSLASH (*end)); + + switch (*end++) + { + default: return false; /* An ordinary file name component is OK. */ + case '\0': return true; /* Trailing "/" is trouble. */ + case '.': break; /* Possibly "." or "..". */ + } + /* Trailing "/.", or "/.." even if not trailing, is trouble. */ + if (!*end || (*end == '.' && (!end[1] || ISSLASH (end[1])))) + return true; + } + + return false; +} + +/* Append this to a file name to test whether it is a searchable directory. + On POSIX platforms "/" suffices, but "/./" is sometimes needed on + macOS 10.13 <https://bugs.gnu.org/30350>, and should also work on + platforms like AIX 7.2 that need at least "/.". */ + +#if defined _LIBC || defined LSTAT_FOLLOWS_SLASHED_SYMLINK +static char const dir_suffix[] = "/"; +#else +static char const dir_suffix[] = "/./"; +#endif + +/* Return true if DIR is a searchable dir, false (setting errno) otherwise. + DIREND points to the NUL byte at the end of the DIR string. + Store garbage into DIREND[0 .. strlen (dir_suffix)]. */ + +static bool +dir_check (char *dir, char *dirend) +{ + strcpy (dirend, dir_suffix); + return file_accessible (dir); +} + static idx_t get_path_max (void) { @@ -111,19 +188,27 @@ get_path_max (void) return path_max < 0 ? 1024 : path_max <= IDX_MAX ? path_max : IDX_MAX; } -/* Return the canonical absolute name of file NAME. A canonical name - does not contain any ".", ".." components nor any repeated file name - separators ('/') or symlinks. All file name components must exist. If - RESOLVED is null, the result is malloc'd; otherwise, if the - canonical name is PATH_MAX chars or more, returns null with 'errno' - set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, - returns the name in RESOLVED. If the name cannot be resolved and - RESOLVED is non-NULL, it contains the name of the first component - that cannot be resolved. If the name can be resolved, RESOLVED - holds the same value as the value returned. */ - -char * -__realpath (const char *name, char *resolved) +/* Act like __realpath (see below), with an additional argument + rname_buf that can be used as temporary storage. + + If GCC_LINT is defined, do not inline this function with GCC 10.1 + and later, to avoid creating a pointer to the stack that GCC + -Wreturn-local-addr incorrectly complains about. See: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644 + Although the noinline attribute can hurt performance a bit, no better way + to pacify GCC is known; even an explicit #pragma does not pacify GCC. + When the GCC bug is fixed this workaround should be limited to the + broken GCC versions. */ +#if __GNUC_PREREQ (10, 1) +# if defined GCC_LINT || defined lint +__attribute__ ((__noinline__)) +# elif __OPTIMIZE__ && !__NO_INLINE__ +# define GCC_BOGUS_WRETURN_LOCAL_ADDR +# endif +#endif +static char * +realpath_stk (const char *name, char *resolved, + struct scratch_buffer *rname_buf) { char *dest; char const *start; @@ -149,8 +234,6 @@ __realpath (const char *name, char *resolved) } struct scratch_buffer extra_buffer, link_buffer; - struct scratch_buffer rname_buffer; - struct scratch_buffer *rname_buf = &rname_buffer; scratch_buffer_init (&extra_buffer); scratch_buffer_init (&link_buffer); scratch_buffer_init (rname_buf); @@ -208,7 +291,9 @@ __realpath (const char *name, char *resolved) name ends in '/'. */ idx_t startlen = end - start; - if (startlen == 1 && start[0] == '.') + if (startlen == 0) + break; + else if (startlen == 1 && start[0] == '.') /* nothing */; else if (startlen == 2 && start[0] == '.' && start[1] == '.') { @@ -226,7 +311,8 @@ __realpath (const char *name, char *resolved) if (!ISSLASH (dest[-1])) *dest++ = '/'; - while (rname + rname_buf->length - dest <= startlen) + while (rname + rname_buf->length - dest + < startlen + sizeof dir_suffix) { idx_t dest_offset = dest - rname; if (!scratch_buffer_grow_preserve (rname_buf)) @@ -238,28 +324,19 @@ __realpath (const char *name, char *resolved) dest = __mempcpy (dest, start, startlen); *dest = '\0'; - /* If STARTLEN == 0, RNAME ends in '/'; use stat rather than - readlink, because readlink might fail with EINVAL without - checking whether RNAME sans '/' is valid. */ - struct stat st; - char *buf = NULL; + char *buf; ssize_t n; - if (startlen != 0) + while (true) { - while (true) - { - buf = link_buffer.data; - idx_t bufsize = link_buffer.length; - n = __readlink (rname, buf, bufsize - 1); - if (n < bufsize - 1) - break; - if (!scratch_buffer_grow (&link_buffer)) - goto error_nomem; - } - if (n < 0) - buf = NULL; + buf = link_buffer.data; + idx_t bufsize = link_buffer.length; + n = __readlink (rname, buf, bufsize - 1); + if (n < bufsize - 1) + break; + if (!scratch_buffer_grow (&link_buffer)) + goto error_nomem; } - if (buf) + if (0 <= n) { if (++num_links > __eloop_threshold ()) { @@ -270,7 +347,7 @@ __realpath (const char *name, char *resolved) buf[n] = '\0'; char *extra_buf = extra_buffer.data; - idx_t end_idx; + idx_t end_idx IF_LINT (= 0); if (end_in_extra_buffer) end_idx = end - extra_buf; idx_t len = strlen (end); @@ -315,8 +392,8 @@ __realpath (const char *name, char *resolved) dest++; } } - else if (! (startlen == 0 - ? stat (rname, &st) == 0 || errno == EOVERFLOW + else if (! (suffix_requires_dir_check (end) + ? dir_check (rname, dest) : errno == EINVAL)) goto error; } @@ -355,6 +432,28 @@ error_nomem: char *result = realloc (rname, rname_size); return result != NULL ? result : rname; } + +/* Return the canonical absolute name of file NAME. A canonical name + does not contain any ".", ".." components nor any repeated file name + separators ('/') or symlinks. All file name components must exist. If + RESOLVED is null, the result is malloc'd; otherwise, if the + canonical name is PATH_MAX chars or more, returns null with 'errno' + set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, + returns the name in RESOLVED. If the name cannot be resolved and + RESOLVED is non-NULL, it contains the name of the first component + that cannot be resolved. If the name can be resolved, RESOLVED + holds the same value as the value returned. */ + +char * +__realpath (const char *name, char *resolved) +{ + #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR + #warning "GCC might issue a bogus -Wreturn-local-addr warning here." + #warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>." + #endif + struct scratch_buffer rname_buffer; + return realpath_stk (name, resolved, &rname_buffer); +} libc_hidden_def (__realpath) versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); #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 }; # if defined GCC_LINT || defined lint __attribute__ ((__noinline__)) # elif __OPTIMIZE__ && !__NO_INLINE__ -# warning "GCC might issue a bogus -Wreturn-local-addr warning here." -# warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>." +# define GCC_BOGUS_WRETURN_LOCAL_ADDR # endif #endif static char * @@ -180,10 +179,11 @@ careadlinkat (int fd, char const *filename, /* Allocate the initial buffer on the stack. This way, in the common case of a symlink of small size, we get away with a single small malloc instead of a big malloc followed by a - shrinking realloc. - - If GCC -Wreturn-local-addr warns about this buffer, the warning - is bogus; see readlink_stk. */ + shrinking realloc. */ + #ifdef GCC_BOGUS_WRETURN_LOCAL_ADDR + #warning "GCC might issue a bogus -Wreturn-local-addr warning here." + #warning "See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93644>." + #endif char stack_buf[STACK_BUF_SIZE]; return readlink_stk (fd, filename, buffer, buffer_size, alloc, 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 @@ +/* Threshold at which to diagnose ELOOP. Generic version. + Copyright (C) 2012-2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _ELOOP_THRESHOLD_H +#define _ELOOP_THRESHOLD_H 1 + +#include <limits.h> +#ifdef _LIBC +# include <sys/param.h> +# define _GL_ATTRIBUTE_CONST __attribute__ ((const)) +#else +# include <unistd.h> +# include "minmax.h" +# define __sysconf sysconf +# if (!defined SYMLOOP_MAX \ + && ! (defined _SC_SYMLOOP_MAX && defined _POSIX_SYMLOOP_MAX)) +# define SYMLOOP_MAX 8 +# endif +#endif + +/* POSIX specifies SYMLOOP_MAX as the "Maximum number of symbolic + links that can be reliably traversed in the resolution of a + pathname in the absence of a loop." This makes it a minimum that + we should certainly accept. But it leaves open the possibility + that more might sometimes work--just not "reliably". + + For example, Linux implements a complex policy whereby there is a + small limit on the number of direct symlink traversals (a symlink + to a symlink to a symlink), but larger limit on the total number of + symlink traversals overall. Hence the SYMLOOP_MAX number should be + the small one, but the limit library functions enforce on users + should be the larger one. + + So, we use the larger of the reported SYMLOOP_MAX (if any) and our + own constant MIN_ELOOP_THRESHOLD, below. This constant should be + large enough that it never rules out a file name and directory tree + that the underlying system (i.e. calls to 'open' et al) would + resolve successfully. It should be small enough that actual loops + are detected without a huge number of iterations. */ + +#ifndef MIN_ELOOP_THRESHOLD +# define MIN_ELOOP_THRESHOLD 40 +#endif + +/* Return the maximum number of symlink traversals to permit + before diagnosing ELOOP. */ +static inline unsigned int _GL_ATTRIBUTE_CONST +__eloop_threshold (void) +{ +#ifdef SYMLOOP_MAX + const int symloop_max = SYMLOOP_MAX; +#else + /* The function is marked 'const' even though we use memory and + call a function, because sysconf is required to return the + same value in every call and so it must always be safe to + call __eloop_threshold exactly once and reuse the value. */ + static long int sysconf_symloop_max; + if (sysconf_symloop_max == 0) + sysconf_symloop_max = __sysconf (_SC_SYMLOOP_MAX); + const unsigned int symloop_max = (sysconf_symloop_max <= 0 + ? _POSIX_SYMLOOP_MAX + : sysconf_symloop_max); +#endif + + return MAX (symloop_max, MIN_ELOOP_THRESHOLD); +} + +#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) safe. */ if (mode == F_OK) - return stat (file, &stats); + { + int result = stat (file, &stats); + return result != 0 && errno == EOVERFLOW ? 0 : result; + } else { int result; @@ -142,8 +145,8 @@ euidaccess (const char *file, int mode) /* If we are not set-uid or set-gid, access does the same. */ return access (file, mode); - if (stat (file, &stats) != 0) - return -1; + if (stat (file, &stats) == -1) + return mode == F_OK && errno == EOVERFLOW ? 0 : -1; /* The super-user can read and write any file, and execute any file 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 @@ #include <sys/stat.h> #undef _GL_INCLUDING_UNISTD_H +#ifndef FACCESSAT_NEVER_EOVERFLOWS +# define FACCESSAT_NEVER_EOVERFLOWS 0 +#endif +#ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK +# define LSTAT_FOLLOWS_SLASHED_SYMLINK 0 +#endif + #if HAVE_FACCESSAT static int 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) { int result = orig_faccessat (fd, file, mode, flag); - if (result == 0 && file[strlen (file) - 1] == '/') + if (result != 0) + { + if (!FACCESSAT_NEVER_EOVERFLOWS && mode == F_OK && errno == EOVERFLOW) + return 0; + } + else if (!LSTAT_FOLLOWS_SLASHED_SYMLINK && file[strlen (file) - 1] == '/') { struct stat st; 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 @@ # filevercmp \ # flexmember \ # fpieee \ +# free-posix \ # fstatat \ # fsusage \ # fsync \ @@ -1528,6 +1529,17 @@ EXTRA_libgnu_a_SOURCES += dup2.c endif ## end gnulib module dup2 +## begin gnulib module eloop-threshold +ifeq (,$(OMIT_GNULIB_MODULE_eloop-threshold)) + +ifneq (,$(gl_GNULIB_ENABLED_925677f0343de64b89a9f0c790b4104c)) + +endif +EXTRA_DIST += eloop-threshold.h + +endif +## end gnulib module eloop-threshold + ## begin gnulib module errno ifeq (,$(OMIT_GNULIB_MODULE_errno)) @@ -1750,9 +1762,7 @@ endif ## begin gnulib module free-posix ifeq (,$(OMIT_GNULIB_MODULE_free-posix)) -ifneq (,$(gl_GNULIB_ENABLED_ef07dc4b3077c11ea9cef586db4e5955)) -endif EXTRA_DIST += free.c 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/. */ /* NOTE: All functions in this file which are not declared in mini-gmp.h are internal, and are not intended to be compatible - neither with GMP nor with future versions of mini-gmp. */ + with GMP or with future versions of mini-gmp. */ /* Much of the material copied from GMP files, including: gmp-impl.h, 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, unsigned bits) { mp_size_t rn; - size_t j; + mp_limb_t limb; unsigned shift; - for (j = sn, rn = 0, shift = 0; j-- > 0; ) + for (limb = 0, rn = 0, shift = 0; sn-- > 0; ) { - if (shift == 0) - { - rp[rn++] = sp[j]; - shift += bits; - } - else + limb |= (mp_limb_t) sp[sn] << shift; + shift += bits; + if (shift >= GMP_LIMB_BITS) { - rp[rn-1] |= (mp_limb_t) sp[j] << shift; - shift += bits; - if (shift >= GMP_LIMB_BITS) - { - shift -= GMP_LIMB_BITS; - if (shift > 0) - rp[rn++] = (mp_limb_t) sp[j] >> (bits - shift); - } + shift -= GMP_LIMB_BITS; + rp[rn++] = limb; + /* Next line is correct also if shift == 0, + bits == 8, and mp_limb_t == unsigned char. */ + limb = (unsigned int) sp[sn] >> (bits - shift); } } - rn = mpn_normalized_size (rp, rn); + if (limb != 0) + rp[rn++] = limb; + else + rn = mpn_normalized_size (rp, rn); return rn; } @@ -2723,7 +2720,7 @@ mpz_make_odd (mpz_t r) assert (r->_mp_size > 0); /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */ - shift = mpn_common_scan (r->_mp_d[0], 0, r->_mp_d, 0, 0); + shift = mpn_scan1 (r->_mp_d, 0); mpz_tdiv_q_2exp (r, r, shift); return shift; @@ -2780,9 +2777,13 @@ mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v) if (tv->_mp_size == 1) { - mp_limb_t vl = tv->_mp_d[0]; - mp_limb_t ul = mpz_tdiv_ui (tu, vl); - mpz_set_ui (g, mpn_gcd_11 (ul, vl)); + mp_limb_t *gp; + + mpz_tdiv_r (tu, tu, tv); + gp = MPZ_REALLOC (g, 1); /* gp = mpz_limbs_modify (g, 1); */ + *gp = mpn_gcd_11 (tu->_mp_d[0], tv->_mp_d[0]); + + g->_mp_size = *gp != 0; /* mpz_limbs_finish (g, 1); */ break; } 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) * s0 = 0, s1 = 2^vz */ - mpz_setbit (t0, uz); mpz_tdiv_qr (t1, tu, tu, tv); mpz_mul_2exp (t1, t1, uz); @@ -2882,8 +2882,7 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) { mp_bitcnt_t shift; shift = mpz_make_odd (tu); - mpz_mul_2exp (t0, t0, shift); - mpz_mul_2exp (s0, s0, shift); + mpz_setbit (t0, uz + shift); power += shift; for (;;) @@ -2921,6 +2920,8 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) power += shift; } } + else + mpz_setbit (t0, uz); /* Now tv = odd part of gcd, and -s0 and t0 are corresponding cofactors. */ @@ -3604,7 +3605,8 @@ mpz_probab_prime_p (const mpz_t n, int reps) /* Find q and k, where q is odd and n = 1 + 2**k * q. */ mpz_abs (nm1, n); nm1->_mp_d[0] -= 1; - k = mpz_scan1 (nm1, 0); + /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */ + k = mpn_scan1 (nm1->_mp_d, 0); mpz_tdiv_q_2exp (q, nm1, k); /* BPSW test */ @@ -4301,7 +4303,7 @@ mpz_get_str (char *sp, int base, const mpz_t u) ret: sp[sn] = '\0'; if (osn && osn != sn + 1) - sp = gmp_realloc(sp, osn, sn + 1); + sp = (char*) gmp_realloc (sp, osn, sn + 1); return sp; } @@ -4425,6 +4427,8 @@ mpz_out_str (FILE *stream, int base, const mpz_t x) size_t len, n; str = mpz_get_str (NULL, base, x); + if (!str) + return 0; len = strlen (str); n = fwrite (str, 1, len, stream); 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 @@ /* mini-gmp, a minimalistic implementation of a GNU GMP subset. -Copyright 2011-2015, 2017, 2019 Free Software Foundation, Inc. +Copyright 2011-2015, 2017, 2019-2020 Free Software Foundation, Inc. This file is part of the GNU MP Library. @@ -295,7 +295,8 @@ int mpz_init_set_str (mpz_t, const char *, int); || defined (_MSL_STDIO_H) /* Metrowerks */ \ || defined (_STDIO_H_INCLUDED) /* QNX4 */ \ || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \ - || defined (__STDIO_LOADED) /* VMS */ + || defined (__STDIO_LOADED) /* VMS */ \ + || defined (__DEFINED_FILE) /* musl */ size_t mpz_out_str (FILE *, int, const mpz_t); #endif 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) if (len && name[len - 1] == '/') { struct stat st; - if (lstat (name, &st) == 0) + if (lstat (name, &st) == 0 || errno == EOVERFLOW) errno = EEXIST; return -1; } |