From ccaa4a07f093428241cbcc81379c3ea3d84b38ee Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 23 Feb 2026 00:20:46 -0800 Subject: [PATCH] Update from Gnulib by running admin/merge-gnulib --- lib/af_alg.h | 16 +-- lib/cdefs.h | 250 ++++++++++++++++++++++++++++++++++++++++------- lib/gnulib.mk.in | 2 + lib/md5-stream.c | 2 +- lib/md5.h | 19 ++-- lib/sha1.c | 12 ++- lib/sha1.h | 18 ++-- lib/sha256.c | 18 ++-- lib/sha256.h | 26 ++--- lib/sha512.c | 18 ++-- lib/sha512.h | 26 ++--- lib/string.c | 2 +- lib/string.in.h | 52 ++++++++++ m4/string_h.m4 | 3 +- 14 files changed, 359 insertions(+), 105 deletions(-) diff --git a/lib/af_alg.h b/lib/af_alg.h index 1321970f8ee..6272d1ecbbb 100644 --- a/lib/af_alg.h +++ b/lib/af_alg.h @@ -58,8 +58,8 @@ extern "C" { If successful, fill RESBLOCK and return 0. Upon failure, return a negated error number. */ int -afalg_buffer (const char *buffer, size_t len, const char *alg, - void *resblock, ssize_t hashlen); +afalg_buffer (char const *restrict buffer, size_t len, char const *restrict alg, + void *restrict resblock, ssize_t hashlen); /* Compute a message digest of data read from STREAM. @@ -87,21 +87,21 @@ afalg_buffer (const char *buffer, size_t len, const char *alg, Unless returning 0 or -EIO, restore STREAM's file position so that the caller can fall back on some other method. */ int -afalg_stream (FILE *stream, const char *alg, - void *resblock, ssize_t hashlen); +afalg_stream (FILE *restrict stream, char const *restrict alg, + void *restrict resblock, ssize_t hashlen); # else static inline int -afalg_buffer (const char *buffer, size_t len, const char *alg, - void *resblock, ssize_t hashlen) +afalg_buffer (char const *restrict buffer, size_t len, char const *restrict alg, + void *restrict resblock, ssize_t hashlen) { return -EAFNOSUPPORT; } static inline int -afalg_stream (FILE *stream, const char *alg, - void *resblock, ssize_t hashlen) +afalg_stream (FILE *restrict stream, char const *restrict alg, + void *restrict resblock, ssize_t hashlen) { return -EAFNOSUPPORT; } diff --git a/lib/cdefs.h b/lib/cdefs.h index 696e65424b7..42024b20e11 100644 --- a/lib/cdefs.h +++ b/lib/cdefs.h @@ -24,13 +24,6 @@ # include #endif -/* The GNU libc does not support any K&R compilers or the traditional mode - of ISO C compilers anymore. Check for some of the combinations not - supported anymore. */ -#if defined __GNUC__ && !defined __STDC__ -# error "You need a ISO C conforming compiler to use the glibc headers" -#endif - /* Some user header file might have defined this before. */ #undef __P #undef __PMT @@ -100,6 +93,12 @@ # endif # endif +# if __GNUC_PREREQ (4, 3) || __glibc_has_attribute (__cold__) +# define __COLD __attribute__ ((__cold__)) +# else +# define __COLD +# endif + #else /* Not GCC or clang. */ # if (defined __cplusplus \ @@ -112,6 +111,7 @@ # define __THROW # define __THROWNL # define __NTH(fct) fct +# define __COLD #endif /* GCC || clang. */ @@ -140,38 +140,47 @@ #endif +/* The overloadable attribute was added on clang 2.6. */ +#if defined __clang_major__ \ + && (__clang_major__ + (__clang_minor__ >= 6) > 2) +# define __attribute_overloadable__ __attribute__((__overloadable__)) +#else +# define __attribute_overloadable__ +#endif + /* Gnulib avoids these definitions, as they don't work on non-glibc platforms. In particular, __bos and __bos0 are defined differently in the Android libc. */ #ifndef __GNULIB_CDEFS /* Fortify support. */ -# define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) -# define __bos0(ptr) __builtin_object_size (ptr, 0) +#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) +#define __bos0(ptr) __builtin_object_size (ptr, 0) /* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */ -# if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0) \ - || __GNUC_PREREQ (12, 0)) -# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0) -# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1) -# else -# define __glibc_objsize0(__o) __bos0 (__o) -# define __glibc_objsize(__o) __bos (__o) -# endif +#if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0) \ + || __GNUC_PREREQ (12, 0)) +# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0) +# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1) +#else +# define __glibc_objsize0(__o) __bos0 (__o) +# define __glibc_objsize(__o) __bos (__o) +#endif +#if __USE_FORTIFY_LEVEL > 0 /* Compile time conditions to choose between the regular, _chk and _chk_warn variants. These conditions should get evaluated to constant and optimized away. */ -# define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s)) -# define __glibc_unsigned_or_positive(__l) \ +#define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s)) +#define __glibc_unsigned_or_positive(__l) \ ((__typeof (__l)) 0 < (__typeof (__l)) -1 \ || (__builtin_constant_p (__l) && (__l) > 0)) /* Length is known to be safe at compile time if the __L * __S <= __OBJSZ condition can be folded to a constant and if it is true, or unknown (-1) */ -# define __glibc_safe_or_unknown_len(__l, __s, __osz) \ - ((__osz) == (__SIZE_TYPE__) -1 \ +#define __glibc_safe_or_unknown_len(__l, __s, __osz) \ + ((__builtin_constant_p (__osz) && (__osz) == (__SIZE_TYPE__) -1) \ || (__glibc_unsigned_or_positive (__l) \ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ (__s), (__osz))) \ @@ -180,34 +189,179 @@ /* Conversely, we know at compile time that the length is unsafe if the __L * __S <= __OBJSZ condition can be folded to a constant and if it is false. */ -# define __glibc_unsafe_len(__l, __s, __osz) \ +#define __glibc_unsafe_len(__l, __s, __osz) \ (__glibc_unsigned_or_positive (__l) \ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ __s, __osz)) \ && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) +/* To correctly instrument the fortify wrapper clang requires the + pass_object_size attribute, and the attribute has the restriction that the + argument needs to be 'const'. Furthermore, to make it usable with C + interfaces, clang provides the overload attribute, which provides a C++ + like function overload support. The overloaded fortify wrapper with the + pass_object_size attribute has precedence over the default symbol. + + Also, clang does not support __va_arg_pack, so variadic functions are + expanded to issue va_arg implementations. The error function must not have + bodies (address takes are expanded to nonfortified calls), and with + __fortify_function compiler might still create a body with the C++ + mangling name (due to the overload attribute). In this case, the function + is defined with __fortify_function_error_function macro instead. + + The argument size check is also done with a clang-only attribute, + __attribute__ ((__diagnose_if__ (...))), different than gcc which calls + symbol_chk_warn alias with uses __warnattr attribute. + + The pass_object_size was added on clang 4.0, __diagnose_if__ on 5.0, + and pass_dynamic_object_size on 9.0. */ +#if defined __clang_major__ && __clang_major__ >= 5 +# define __fortify_use_clang 1 + +# define __fortify_function_error_function static __attribute__((__unused__)) + +# define __fortify_clang_pass_object_size_n(n) \ + __attribute__ ((__pass_object_size__ (n))) +# define __fortify_clang_pass_object_size0 \ + __fortify_clang_pass_object_size_n (0) +# define __fortify_clang_pass_object_size \ + __fortify_clang_pass_object_size_n (__USE_FORTIFY_LEVEL > 1) + +# if __clang_major__ >= 9 +# define __fortify_clang_pass_dynamic_object_size_n(n) \ + __attribute__ ((__pass_dynamic_object_size__ (n))) +# define __fortify_clang_pass_dynamic_object_size0 \ + __fortify_clang_pass_dynamic_object_size_n (0) +# define __fortify_clang_pass_dynamic_object_size \ + __fortify_clang_pass_dynamic_object_size_n (1) +# else +# define __fortify_clang_pass_dynamic_object_size_n(n) +# define __fortify_clang_pass_dynamic_object_size0 +# define __fortify_clang_pass_dynamic_object_size +# endif + +# define __fortify_clang_bos_static_lt_impl(bos_val, n, s) \ + ((bos_val) != -1ULL && (n) > (bos_val) / (s)) +# define __fortify_clang_bos_static_lt2(__n, __e, __s) \ + __fortify_clang_bos_static_lt_impl (__bos (__e), __n, __s) +# define __fortify_clang_bos_static_lt(__n, __e) \ + __fortify_clang_bos_static_lt2 (__n, __e, 1) +# define __fortify_clang_bos0_static_lt2(__n, __e, __s) \ + __fortify_clang_bos_static_lt_impl (__bos0 (__e), __n, __s) +# define __fortify_clang_bos0_static_lt(__n, __e) \ + __fortify_clang_bos0_static_lt2 (__n, __e, 1) + +# define __fortify_clang_bosn_args(bos_fn, n, buf, div, complaint) \ + (__fortify_clang_bos_static_lt_impl (bos_fn (buf), n, div)), (complaint), \ + "warning" + +# define __fortify_clang_warning(__c, __msg) \ + __attribute__ ((__diagnose_if__ ((__c), (__msg), "warning"))) +# define __fortify_clang_error(__c, __msg) \ + __attribute__ ((__diagnose_if__ ((__c), (__msg), "error"))) +# define __fortify_clang_warning_only_if_bos0_lt(n, buf, complaint) \ + __attribute__ ((__diagnose_if__ \ + (__fortify_clang_bosn_args (__bos0, n, buf, 1, complaint)))) +# define __fortify_clang_warning_only_if_bos0_lt2(n, buf, div, complaint) \ + __attribute__ ((__diagnose_if__ \ + (__fortify_clang_bosn_args (__bos0, n, buf, div, complaint)))) +# define __fortify_clang_warning_only_if_bos_lt(n, buf, complaint) \ + __attribute__ ((__diagnose_if__ \ + (__fortify_clang_bosn_args (__bos, n, buf, 1, complaint)))) +# define __fortify_clang_warning_only_if_bos_lt2(n, buf, div, complaint) \ + __attribute__ ((__diagnose_if__ \ + (__fortify_clang_bosn_args (__bos, n, buf, div, complaint)))) + +# define __fortify_clang_prefer_this_overload \ + __attribute__ ((enable_if (1, ""))) +# define __fortify_clang_unavailable(__msg) \ + __attribute__ ((unavailable(__msg))) + +# if __USE_FORTIFY_LEVEL == 3 +# define __fortify_clang_overload_arg(__type, __attr, __name) \ + __type __attr const __fortify_clang_pass_dynamic_object_size __name +# define __fortify_clang_overload_arg0(__type, __attr, __name) \ + __type __attr const __fortify_clang_pass_dynamic_object_size0 __name +# else +# define __fortify_clang_overload_arg(__type, __attr, __name) \ + __type __attr const __fortify_clang_pass_object_size __name +# define __fortify_clang_overload_arg0(__type, __attr, __name) \ + __type __attr const __fortify_clang_pass_object_size0 __name +# endif + +# define __fortify_clang_mul_may_overflow(size, n) \ + ((size | n) >= (((size_t)1) << (8 * sizeof (size_t) / 2))) + +# define __fortify_clang_size_too_small(__bos, __dest, __len) \ + (__bos (__dest) != (size_t) -1 && __bos (__dest) < __len) +# define __fortify_clang_warn_if_src_too_large(__dest, __src) \ + __fortify_clang_warning (__fortify_clang_size_too_small (__glibc_objsize, \ + __dest, \ + __builtin_strlen (__src) + 1), \ + "destination buffer will always be overflown by source") +# define __fortify_clang_warn_if_dest_too_small(__dest, __len) \ + __fortify_clang_warning (__fortify_clang_size_too_small (__glibc_objsize, \ + __dest, \ + __len), \ + "function called with bigger length than the destination buffer") +# define __fortify_clang_warn_if_dest_too_small0(__dest, __len) \ + __fortify_clang_warning (__fortify_clang_size_too_small (__glibc_objsize0, \ + __dest, \ + __len), \ + "function called with bigger length than the destination buffer") +#else +# define __fortify_use_clang 0 +# define __fortify_clang_warning(__c, __msg) +# define __fortify_clang_warning_only_if_bos0_lt(__n, __buf, __complaint) +# define __fortify_clang_warning_only_if_bos0_lt2(__n, __buf, __div, complaint) +# define __fortify_clang_warning_only_if_bos_lt(__n, __buf, __complaint) +# define __fortify_clang_warning_only_if_bos_lt2(__n, __buf, div, __complaint) +# define __fortify_clang_overload_arg(__type, __attr, __name) \ + __type __attr __name +# define __fortify_clang_overload_arg0(__type, __attr, __name) \ + __fortify_clang_overload_arg (__type, __attr, __name) +# define __fortify_clang_warn_if_src_too_large(__dest, __src) +# define __fortify_clang_warn_if_dest_too_small(__dest, __len) +# define __fortify_clang_warn_if_dest_too_small0(__dest, __len) +#endif + + /* Fortify function f. __f_alias, __f_chk and __f_chk_warn must be declared. */ +#if !__fortify_use_clang # define __glibc_fortify(f, __l, __s, __osz, ...) \ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ ? __ ## f ## _alias (__VA_ARGS__) \ : (__glibc_unsafe_len (__l, __s, __osz) \ ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ - : __ ## f ## _chk (__VA_ARGS__, __osz))) \ + : __ ## f ## _chk (__VA_ARGS__, __osz))) +#else +# define __glibc_fortify(f, __l, __s, __osz, ...) \ + (__osz == (__SIZE_TYPE__) -1) \ + ? __ ## f ## _alias (__VA_ARGS__) \ + : __ ## f ## _chk (__VA_ARGS__, __osz) +#endif /* Fortify function f, where object size argument passed to f is the number of elements and not total size. */ +#if !__fortify_use_clang # define __glibc_fortify_n(f, __l, __s, __osz, ...) \ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ ? __ ## f ## _alias (__VA_ARGS__) \ : (__glibc_unsafe_len (__l, __s, __osz) \ ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ - : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) \ - + : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) +# else +# define __glibc_fortify_n(f, __l, __s, __osz, ...) \ + (__osz == (__SIZE_TYPE__) -1) \ + ? __ ## f ## _alias (__VA_ARGS__) \ + : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)) #endif +#endif /* __USE_FORTIFY_LEVEL > 0 */ +#endif /* !__GNULIB_CDEFS */ #if __GNUC_PREREQ (4,3) # define __warnattr(msg) __attribute__((__warning__ (msg))) @@ -269,6 +423,14 @@ # define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname) # define __ASMNAME2(prefix, cname) __STRING (prefix) cname +#ifndef __REDIRECT_FORTIFY +#define __REDIRECT_FORTIFY __REDIRECT +#endif + +#ifndef __REDIRECT_FORTIFY_NTH +#define __REDIRECT_FORTIFY_NTH __REDIRECT_NTH +#endif + /* #elif __SOME_OTHER_COMPILER__ @@ -445,14 +607,14 @@ # define __attribute_artificial__ /* Ignore */ #endif -/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 - inline semantics, unless -fgnu89-inline is used. Using __GNUC_STDC_INLINE__ - or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions +/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 inline + semantics, unless -fgnu89-inline is used. Using __GNUC_STDC_INLINE__ or + __GNUC_GNU_INLINE__ is not a good enough check for gcc because gcc versions older than 4.3 may define these macros and still not guarantee GNU inlining semantics. clang++ identifies itself as gcc-4.2, but has support for GNU inlining - semantics, that can be checked for by using the __GNUC_STDC_INLINE_ and + semantics, that can be checked for by using the __GNUC_STDC_INLINE__ and __GNUC_GNU_INLINE__ macro definitions. */ #if (!defined __cplusplus || __GNUC_PREREQ (4,3) \ || (defined __clang__ && (defined __GNUC_STDC_INLINE__ \ @@ -577,6 +739,8 @@ # define __LDBL_REDIR(name, proto) ... unused__ldbl_redir # define __LDBL_REDIR_DECL(name) \ extern __typeof (name) name __asm (__ASMNAME ("__" #name "ieee128")); +# define __REDIRECT_LDBL(name, proto, alias) \ + name proto __asm (__ASMNAME ("__" #alias "ieee128")) /* Alias name defined automatically, with leading underscores. */ # define __LDBL_REDIR2_DECL(name) \ @@ -594,7 +758,6 @@ __LDBL_REDIR1_NTH (name, proto, __##alias##ieee128) /* Unused. */ -# define __REDIRECT_LDBL(name, proto, alias) ... unused__redirect_ldbl # define __LDBL_REDIR_NTH(name, proto) ... unused__ldbl_redir_nth # else @@ -666,6 +829,18 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf # define __HAVE_GENERIC_SELECTION 0 #endif +#if __HAVE_GENERIC_SELECTION +/* If PTR is a pointer to const, return CALL cast to type CTYPE, + otherwise return CALL. Pointers to types with non-const qualifiers + are not valid. This should not be defined for C++, as macros are + not an appropriate way of implementing such qualifier-generic + operations for C++. */ +# define __glibc_const_generic(PTR, CTYPE, CALL) \ + _Generic (0 ? (PTR) : (void *) 1, \ + const void *: (CTYPE) (CALL), \ + default: CALL) +#endif + #if __GNUC_PREREQ (10, 0) /* Designates a 1-based positional argument ref-index of pointer type that can be used to access size-index elements of the pointed-to @@ -675,10 +850,10 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf # define __attr_access(x) __attribute__ ((__access__ x)) /* For _FORTIFY_SOURCE == 3 we use __builtin_dynamic_object_size, which may use the access attribute to get object sizes from function definition - arguments, so we can't use them on functions we fortify. Drop the object - size hints for such functions. */ + arguments, so we can't use them on functions we fortify. Drop the access + attribute for such functions. */ # if __USE_FORTIFY_LEVEL == 3 -# define __fortified_attr_access(a, o, s) __attribute__ ((__access__ (a, o))) +# define __fortified_attr_access(a, o, s) # else # define __fortified_attr_access(a, o, s) __attr_access ((a, o, s)) # endif @@ -712,4 +887,13 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf # define __attribute_returns_twice__ /* Ignore. */ #endif +/* Mark struct types as aliasable. Restricted to compilers that + support forward declarations of structs in the presence of the + attribute. */ +#if __GNUC_PREREQ (7, 1) || defined __clang__ +# define __attribute_struct_may_alias__ __attribute__ ((__may_alias__)) +#else +# define __attribute_struct_may_alias__ +#endif + #endif /* sys/cdefs.h */ diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 6b7889cf835..d7203c16fde 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -635,6 +635,7 @@ GL_GNULIB_STRNCAT = @GL_GNULIB_STRNCAT@ GL_GNULIB_STRNCPY = @GL_GNULIB_STRNCPY@ GL_GNULIB_STRNDUP = @GL_GNULIB_STRNDUP@ GL_GNULIB_STRNLEN = @GL_GNULIB_STRNLEN@ +GL_GNULIB_STRNUL = @GL_GNULIB_STRNUL@ GL_GNULIB_STRPBRK = @GL_GNULIB_STRPBRK@ GL_GNULIB_STRPTIME = @GL_GNULIB_STRPTIME@ GL_GNULIB_STRSEP = @GL_GNULIB_STRSEP@ @@ -3765,6 +3766,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_STRNCPY''@/$(GL_GNULIB_STRNCPY)/g' \ -e 's/@''GNULIB_STRNDUP''@/$(GL_GNULIB_STRNDUP)/g' \ -e 's/@''GNULIB_STRNLEN''@/$(GL_GNULIB_STRNLEN)/g' \ + -e 's/@''GNULIB_STRNUL''@/$(GL_GNULIB_STRNUL)/g' \ -e 's/@''GNULIB_STRPBRK''@/$(GL_GNULIB_STRPBRK)/g' \ -e 's/@''GNULIB_STRSEP''@/$(GL_GNULIB_STRSEP)/g' \ -e 's/@''GNULIB_STRSTR''@/$(GL_GNULIB_STRSTR)/g' \ diff --git a/lib/md5-stream.c b/lib/md5-stream.c index 96b92374c1d..ffe077f52ab 100644 --- a/lib/md5-stream.c +++ b/lib/md5-stream.c @@ -63,7 +63,7 @@ md5_stream (FILE *stream, void *resblock) case -EIO: return 1; } - char *buffer = malloc (BLOCKSIZE + 72); + char *buffer = malloc (BLOCKSIZE); if (!buffer) return 1; diff --git a/lib/md5.h b/lib/md5.h index 16c6684b61b..5d93b10baa6 100644 --- a/lib/md5.h +++ b/lib/md5.h @@ -121,28 +121,30 @@ extern void __md5_init_ctx (struct md5_ctx *ctx) __THROW; initialization function update the context for the next LEN bytes starting at BUFFER. It is necessary that LEN is a multiple of 64!!! */ -extern void __md5_process_block (const void *buffer, size_t len, - struct md5_ctx *ctx) __THROW; +extern void __md5_process_block (void const *restrict buffer, size_t len, + struct md5_ctx *restrict ctx) __THROW; /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is NOT required that LEN is a multiple of 64. */ -extern void __md5_process_bytes (const void *buffer, size_t len, - struct md5_ctx *ctx) __THROW; +extern void __md5_process_bytes (void const *restrict buffer, size_t len, + struct md5_ctx *restrict ctx) __THROW; /* Process the remaining bytes in the buffer and put result from CTX in first 16 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *restrict resbuf) +extern void *__md5_finish_ctx (struct md5_ctx *restrict ctx, + void *restrict resbuf) __THROW; /* Put result from CTX in first 16 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *restrict resbuf) +extern void *__md5_read_ctx (struct md5_ctx const *restrict ctx, + void *restrict resbuf) __THROW; @@ -150,7 +152,7 @@ extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *restrict resbuf) result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *__md5_buffer (const char *buffer, size_t len, +extern void *__md5_buffer (char const *restrict buffer, size_t len, void *restrict resblock) __THROW; # endif @@ -161,7 +163,8 @@ extern void *__md5_buffer (const char *buffer, size_t len, The case that the last operation on STREAM was an 'ungetc' is not supported. The resulting message digest number will be written into the 16 bytes beginning at RESBLOCK. */ -extern int __md5_stream (FILE *stream, void *resblock) __THROW; +extern int __md5_stream (FILE *restrict stream, void *restrict resblock) + __THROW; # ifdef __cplusplus diff --git a/lib/sha1.c b/lib/sha1.c index f41bda875db..bb7aa2af293 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -74,7 +74,7 @@ set_uint32 (char *cp, uint32_t v) /* Put result from CTX in first 20 bytes following RESBUF. The result must be in little endian byte order. */ void * -sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf) +sha1_read_ctx (struct sha1_ctx const *restrict ctx, void *restrict resbuf) { char *r = resbuf; set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A)); @@ -89,7 +89,7 @@ sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf) /* Process the remaining bytes in the internal buffer and the usual prolog according to the standard and write the result to RESBUF. */ void * -sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) +sha1_finish_ctx (struct sha1_ctx *restrict ctx, void *restrict resbuf) { /* Take yet unprocessed bytes into account. */ uint32_t bytes = ctx->buflen; @@ -117,7 +117,7 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) output yields to the wanted ASCII representation of the message digest. */ void * -sha1_buffer (const char *buffer, size_t len, void *resblock) +sha1_buffer (char const *restrict buffer, size_t len, void *restrict resblock) { struct sha1_ctx ctx; @@ -132,7 +132,8 @@ sha1_buffer (const char *buffer, size_t len, void *resblock) } void -sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) +sha1_process_bytes (void const *restrict buffer, size_t len, + struct sha1_ctx *restrict ctx) { /* When we already have some bits in our internal buffer concatenate both inputs first. */ @@ -219,7 +220,8 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) Most of this code comes from GnuPG's cipher/sha1.c. */ void -sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx) +sha1_process_block (void const *restrict buffer, size_t len, + struct sha1_ctx *restrict ctx) { const uint32_t *words = buffer; size_t nwords = len / sizeof (uint32_t); diff --git a/lib/sha1.h b/lib/sha1.h index a267d46ab4c..444902cb28e 100644 --- a/lib/sha1.h +++ b/lib/sha1.h @@ -79,34 +79,36 @@ extern void sha1_init_ctx (struct sha1_ctx *ctx); initialization function update the context for the next LEN bytes starting at BUFFER. It is necessary that LEN is a multiple of 64!!! */ -extern void sha1_process_block (const void *buffer, size_t len, - struct sha1_ctx *ctx); +extern void sha1_process_block (void const *restrict buffer, size_t len, + struct sha1_ctx *restrict ctx); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is NOT required that LEN is a multiple of 64. */ -extern void sha1_process_bytes (const void *buffer, size_t len, - struct sha1_ctx *ctx); +extern void sha1_process_bytes (void const *restrict buffer, size_t len, + struct sha1_ctx *restrict ctx); /* Process the remaining bytes in the buffer and put result from CTX in first 20 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *restrict resbuf); +extern void *sha1_finish_ctx (struct sha1_ctx *restrict ctx, + void *restrict resbuf); /* Put result from CTX in first 20 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *restrict resbuf); +extern void *sha1_read_ctx (struct sha1_ctx const *restrict ctx, + void *restrict resbuf); /* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha1_buffer (const char *buffer, size_t len, +extern void *sha1_buffer (char const *restrict buffer, size_t len, void *restrict resblock); # endif @@ -117,7 +119,7 @@ extern void *sha1_buffer (const char *buffer, size_t len, The case that the last operation on STREAM was an 'ungetc' is not supported. The resulting message digest number will be written into the 20 bytes beginning at RESBLOCK. */ -extern int sha1_stream (FILE *stream, void *resblock); +extern int sha1_stream (FILE *restrict stream, void *restrict resblock); # ifdef __cplusplus diff --git a/lib/sha256.c b/lib/sha256.c index bada2d07171..115b288e467 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -94,7 +94,7 @@ set_uint32 (char *cp, uint32_t v) /* Put result from CTX in first 32 bytes following RESBUF. The result must be in little endian byte order. */ void * -sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf) +sha256_read_ctx (struct sha256_ctx const *restrict ctx, void *restrict resbuf) { char *r = resbuf; @@ -105,7 +105,7 @@ sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf) } void * -sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf) +sha224_read_ctx (struct sha256_ctx const *restrict ctx, void *restrict resbuf) { char *r = resbuf; @@ -144,14 +144,14 @@ sha256_conclude_ctx (struct sha256_ctx *ctx) } void * -sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf) +sha256_finish_ctx (struct sha256_ctx *restrict ctx, void *restrict resbuf) { sha256_conclude_ctx (ctx); return sha256_read_ctx (ctx, resbuf); } void * -sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf) +sha224_finish_ctx (struct sha256_ctx *restrict ctx, void *restrict resbuf) { sha256_conclude_ctx (ctx); return sha224_read_ctx (ctx, resbuf); @@ -162,7 +162,7 @@ sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf) output yields to the wanted ASCII representation of the message digest. */ void * -sha256_buffer (const char *buffer, size_t len, void *resblock) +sha256_buffer (char const *restrict buffer, size_t len, void *restrict resblock) { struct sha256_ctx ctx; @@ -177,7 +177,7 @@ sha256_buffer (const char *buffer, size_t len, void *resblock) } void * -sha224_buffer (const char *buffer, size_t len, void *resblock) +sha224_buffer (char const *restrict buffer, size_t len, void *restrict resblock) { struct sha256_ctx ctx; @@ -192,7 +192,8 @@ sha224_buffer (const char *buffer, size_t len, void *resblock) } void -sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx) +sha256_process_bytes (void const *restrict buffer, size_t len, + struct sha256_ctx *restrict ctx) { /* When we already have some bits in our internal buffer concatenate both inputs first. */ @@ -292,7 +293,8 @@ static const uint32_t sha256_round_constants[64] = { Most of this code comes from GnuPG's cipher/sha1.c. */ void -sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx) +sha256_process_block (void const *restrict buffer, size_t len, + struct sha256_ctx *restrict ctx) { const uint32_t *words = buffer; size_t nwords = len / sizeof (uint32_t); diff --git a/lib/sha256.h b/lib/sha256.h index db80ea5e357..867befdd5d3 100644 --- a/lib/sha256.h +++ b/lib/sha256.h @@ -78,30 +78,32 @@ extern void sha224_init_ctx (struct sha256_ctx *ctx); initialization function update the context for the next LEN bytes starting at BUFFER. It is necessary that LEN is a multiple of 64!!! */ -extern void sha256_process_block (const void *buffer, size_t len, - struct sha256_ctx *ctx); +extern void sha256_process_block (void const *restrict buffer, size_t len, + struct sha256_ctx *restrict ctx); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is NOT required that LEN is a multiple of 64. */ -extern void sha256_process_bytes (const void *buffer, size_t len, - struct sha256_ctx *ctx); +extern void sha256_process_bytes (void const *restrict buffer, size_t len, + struct sha256_ctx *restrict ctx); /* Process the remaining bytes in the buffer and put result from CTX in first 32 (28) bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha256_finish_ctx (struct sha256_ctx *ctx, void *restrict resbuf); -extern void *sha224_finish_ctx (struct sha256_ctx *ctx, void *restrict resbuf); +extern void *sha256_finish_ctx (struct sha256_ctx *restrict ctx, + void *restrict resbuf); +extern void *sha224_finish_ctx (struct sha256_ctx *restrict ctx, + void *restrict resbuf); /* Put result from CTX in first 32 (28) bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha256_read_ctx (const struct sha256_ctx *ctx, +extern void *sha256_read_ctx (struct sha256_ctx const *restrict ctx, void *restrict resbuf); -extern void *sha224_read_ctx (const struct sha256_ctx *ctx, +extern void *sha224_read_ctx (struct sha256_ctx const *restrict ctx, void *restrict resbuf); @@ -109,9 +111,9 @@ extern void *sha224_read_ctx (const struct sha256_ctx *ctx, The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha256_buffer (const char *buffer, size_t len, +extern void *sha256_buffer (char const *restrict buffer, size_t len, void *restrict resblock); -extern void *sha224_buffer (const char *buffer, size_t len, +extern void *sha224_buffer (char const *restrict buffer, size_t len, void *restrict resblock); # endif @@ -122,8 +124,8 @@ extern void *sha224_buffer (const char *buffer, size_t len, The case that the last operation on STREAM was an 'ungetc' is not supported. The resulting message digest number will be written into the 32 (28) bytes beginning at RESBLOCK. */ -extern int sha256_stream (FILE *stream, void *resblock); -extern int sha224_stream (FILE *stream, void *resblock); +extern int sha256_stream (FILE *restrict stream, void *restrict resblock); +extern int sha224_stream (FILE *restrict stream, void *restrict resblock); # ifdef __cplusplus diff --git a/lib/sha512.c b/lib/sha512.c index a8c6484c2ed..4a213f8accc 100644 --- a/lib/sha512.c +++ b/lib/sha512.c @@ -94,7 +94,7 @@ set_uint64 (char *cp, u64 v) /* Put result from CTX in first 64 bytes following RESBUF. The result must be in little endian byte order. */ void * -sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf) +sha512_read_ctx (struct sha512_ctx const *restrict ctx, void *restrict resbuf) { char *r = resbuf; @@ -105,7 +105,7 @@ sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf) } void * -sha384_read_ctx (const struct sha512_ctx *ctx, void *resbuf) +sha384_read_ctx (struct sha512_ctx const *restrict ctx, void *restrict resbuf) { char *r = resbuf; @@ -145,14 +145,14 @@ sha512_conclude_ctx (struct sha512_ctx *ctx) } void * -sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf) +sha512_finish_ctx (struct sha512_ctx *restrict ctx, void *restrict resbuf) { sha512_conclude_ctx (ctx); return sha512_read_ctx (ctx, resbuf); } void * -sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf) +sha384_finish_ctx (struct sha512_ctx *restrict ctx, void *restrict resbuf) { sha512_conclude_ctx (ctx); return sha384_read_ctx (ctx, resbuf); @@ -163,7 +163,7 @@ sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf) output yields to the wanted ASCII representation of the message digest. */ void * -sha512_buffer (const char *buffer, size_t len, void *resblock) +sha512_buffer (char const *restrict buffer, size_t len, void *restrict resblock) { struct sha512_ctx ctx; @@ -178,7 +178,7 @@ sha512_buffer (const char *buffer, size_t len, void *resblock) } void * -sha384_buffer (const char *buffer, size_t len, void *resblock) +sha384_buffer (char const *restrict buffer, size_t len, void *restrict resblock) { struct sha512_ctx ctx; @@ -193,7 +193,8 @@ sha384_buffer (const char *buffer, size_t len, void *resblock) } void -sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx) +sha512_process_bytes (void const *restrict buffer, size_t len, + struct sha512_ctx *restrict ctx) { /* When we already have some bits in our internal buffer concatenate both inputs first. */ @@ -317,7 +318,8 @@ static u64 const sha512_round_constants[80] = { Most of this code comes from GnuPG's cipher/sha1.c. */ void -sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx) +sha512_process_block (void const *restrict buffer, size_t len, + struct sha512_ctx *restrict ctx) { u64 const *words = buffer; u64 const *endp = words + len / sizeof (u64); diff --git a/lib/sha512.h b/lib/sha512.h index aedd9c8e210..6b9cf58da11 100644 --- a/lib/sha512.h +++ b/lib/sha512.h @@ -78,22 +78,24 @@ extern void sha384_init_ctx (struct sha512_ctx *ctx); initialization function update the context for the next LEN bytes starting at BUFFER. It is necessary that LEN is a multiple of 128!!! */ -extern void sha512_process_block (const void *buffer, size_t len, - struct sha512_ctx *ctx); +extern void sha512_process_block (void const *restrict buffer, size_t len, + struct sha512_ctx *restrict ctx); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is NOT required that LEN is a multiple of 128. */ -extern void sha512_process_bytes (const void *buffer, size_t len, - struct sha512_ctx *ctx); +extern void sha512_process_bytes (void const *restrict buffer, size_t len, + struct sha512_ctx *restrict ctx); /* Process the remaining bytes in the buffer and put result from CTX in first 64 (48) bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha512_finish_ctx (struct sha512_ctx *ctx, void *restrict resbuf); -extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *restrict resbuf); +extern void *sha512_finish_ctx (struct sha512_ctx *restrict ctx, + void *restrict resbuf); +extern void *sha384_finish_ctx (struct sha512_ctx *restrict ctx, + void *restrict resbuf); /* Put result from CTX in first 64 (48) bytes following RESBUF. The result is @@ -102,9 +104,9 @@ extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *restrict resbuf); IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ -extern void *sha512_read_ctx (const struct sha512_ctx *ctx, +extern void *sha512_read_ctx (struct sha512_ctx const *restrict ctx, void *restrict resbuf); -extern void *sha384_read_ctx (const struct sha512_ctx *ctx, +extern void *sha384_read_ctx (struct sha512_ctx const *restrict ctx, void *restrict resbuf); @@ -112,9 +114,9 @@ extern void *sha384_read_ctx (const struct sha512_ctx *ctx, The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ -extern void *sha512_buffer (const char *buffer, size_t len, +extern void *sha512_buffer (char const *restrict buffer, size_t len, void *restrict resblock); -extern void *sha384_buffer (const char *buffer, size_t len, +extern void *sha384_buffer (char const *restrict buffer, size_t len, void *restrict resblock); # endif @@ -125,8 +127,8 @@ extern void *sha384_buffer (const char *buffer, size_t len, The case that the last operation on STREAM was an 'ungetc' is not supported. The resulting message digest number will be written into the 64 (48) bytes beginning at RESBLOCK. */ -extern int sha512_stream (FILE *stream, void *resblock); -extern int sha384_stream (FILE *stream, void *resblock); +extern int sha512_stream (FILE *restrict stream, void *restrict resblock); +extern int sha384_stream (FILE *restrict stream, void *restrict resblock); # ifdef __cplusplus diff --git a/lib/string.c b/lib/string.c index c2e1b1f4184..b8f079aa78f 100644 --- a/lib/string.c +++ b/lib/string.c @@ -1,4 +1,4 @@ -/* streq and memeq functions. +/* streq, memeq, gl_strnul functions. Copyright (C) 2025-2026 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify diff --git a/lib/string.in.h b/lib/string.in.h index 1b391507f49..599203c44db 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -1230,6 +1230,58 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - " /* The following functions are not specified by POSIX. They are gnulib extensions. */ +#if @GNULIB_STRNUL@ +/* Returns a pointer to the terminating NUL byte of STRING. + strnul (string) + This is a type-generic macro: + If STRING is a 'const char *', the result is 'const char *'. + If STRING is a 'char *', the result is 'char *'. + It is equivalent to + string + strlen (string) + or to + strchr (string, '\0'). */ +# ifdef __cplusplus +extern "C" { +# endif +_GL_STRING_INLINE const char *gl_strnul (const char *string) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1)); +_GL_STRING_INLINE const char *gl_strnul (const char *string) +{ + /* In gcc >= 7 or clang >= 4, we could use the expression + strchr (string, '\0') + because these compiler versions produce identical code for both + expressions. But this optimization in not available in older + compiler versions, and is also not available when the compiler + option '-fno-builtin' is in use. */ + return string + strlen (string); +} +# ifdef __cplusplus +} +# endif +# ifdef __cplusplus +template T strnul (T); +template <> inline const char *strnul (const char *s) +{ return gl_strnul (s); } +template <> inline char *strnul< char *> ( char *s) +{ return const_cast(gl_strnul (s)); } +# else +# if (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 9) > 4 && !defined __cplusplus) \ + || (defined __clang__ && __clang_major__ >= 3) \ + || (defined __SUNPRO_C && __SUNPRO_C >= 0x5150) \ + || (__STDC_VERSION__ >= 201112L && !defined __GNUC__) +/* The compiler supports _Generic from ISO C11. */ +# define strnul(s) \ + _Generic (s, \ + char * : (char *) gl_strnul (s), \ + const char * : gl_strnul (s)) +# else +# define strnul(s) \ + ((char *) gl_strnul (s)) +# endif +# endif +#endif + #if @GNULIB_STR_STARTSWITH@ /* Returns true if STRING starts with PREFIX. Returns false otherwise. */ diff --git a/m4/string_h.m4 b/m4/string_h.m4 index 2a6e4db46dd..93a5d354cf9 100644 --- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -1,5 +1,5 @@ # string_h.m4 -# serial 46 +# serial 47 dnl Copyright (C) 2007-2026 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,7 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNUL]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_STARTSWITH]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_ENDSWITH]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN])