From: Paul Eggert Date: Tue, 16 Jul 2024 15:25:36 +0000 (-0700) Subject: Detect Android 5.0 strnlen bug X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2fb09fae28c0ea1f924534c86b52a441db6ab7a2;p=thirdparty%2Fautoconf.git Detect Android 5.0 strnlen bug This is useful for GNU Emacs, which still ports to that old Android version. The change here is imported from Gnulib. * lib/autoconf/functions.m4 (AC_FUNC_STRNLEN): Also detect Android 5.0 bug. Use AC_COMPILE_IFELSE rather than AC_CANONICAL_HOST for cross-compile test. --- diff --git a/NEWS b/NEWS index bca113911..615f493f9 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,10 @@ GNU Autoconf NEWS - User visible changes. The autom4te, autoscan and ifnames programs now recognize the two preprocessor directives, which were introduced in C23 and C++23. +** Notable bug fixes + +*** AC_FUNC_STRNLEN now detects Android 5.0's broken strnlen. + * Noteworthy changes in release 2.72 (2023-12-22) [release] ** Backward incompatibilities diff --git a/doc/autoconf.texi b/doc/autoconf.texi index ee3f2f7a4..dc07da5de 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -4966,6 +4966,11 @@ can detect which is in use (@pxref{Particular Functions}). @item @code{strnlen} @c @fuindex strnlen @prindex @code{strnlen} +Android 5.0's strnlen was broken, because it assumed the addressed array +always had at least the specified number of bytes. For example, +@code{strnlen ("", SIZE_MAX)} should return 0 but on Android 5.0 it +crashed. + AIX 4.3 provided a broken version which produces the following results: @@ -5734,7 +5739,7 @@ problems of this function. @prindex @code{strnlen} @caindex func_strnlen_working If the @code{strnlen} function is not available, or is buggy (like the one -from AIX 4.3), require an @code{AC_LIBOBJ} replacement for it. +from Android 5.0 or AIX 4.3), require an @code{AC_LIBOBJ} replacement for it. This macro caches its result in the @code{ac_cv_func_strnlen_working} variable. diff --git a/lib/autoconf/functions.m4 b/lib/autoconf/functions.m4 index 7b03ad6a0..ad11576d6 100644 --- a/lib/autoconf/functions.m4 +++ b/lib/autoconf/functions.m4 @@ -1751,31 +1751,45 @@ LIBS="-lintl $LIBS"])])dnl AN_FUNCTION([strnlen], [AC_FUNC_STRNLEN]) AC_DEFUN([AC_FUNC_STRNLEN], [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])dnl -AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles -AC_CACHE_CHECK([for working strnlen], ac_cv_func_strnlen_working, -[AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], [[ -#define S "foobar" -#define S_LEN (sizeof S - 1) - - /* At least one implementation is buggy: that of AIX 4.3 would - give strnlen (S, 1) == 3. */ - - int i; - for (i = 0; i < S_LEN + 1; ++i) - { - int expected = i <= S_LEN ? i : S_LEN; - if (strnlen (S, i) != expected) - return 1; - } - return 0; -]])], - [ac_cv_func_strnlen_working=yes], - [ac_cv_func_strnlen_working=no], - [# Guess no on AIX systems, yes otherwise. - case "$host_os" in - aix*) ac_cv_func_strnlen_working=no;; - *) ac_cv_func_strnlen_working=yes;; - esac])]) +AC_CACHE_CHECK([for working strnlen], [ac_cv_func_strnlen_working], +[AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [AC_INCLUDES_DEFAULT + [/* Use pstrnlen to test; 'volatile' prevents the compiler + from optimizing the strnlen calls away. */ + size_t (*volatile pstrnlen) (char const *, size_t) = strnlen; + char const s[] = "foobar"; + int s_len = sizeof s - 1; + ]], + [[ + /* AIX 4.3 is buggy: strnlen (S, 1) == 3. */ + int i; + for (i = 0; i < s_len + 1; ++i) + { + int expected = i <= s_len ? i : s_len; + if (pstrnlen (s, i) != expected) + return 1; + } + + /* Android 5.0 (API 21) strnlen ("", SIZE_MAX) incorrectly crashes. */ + if (pstrnlen ("", -1) != 0) + return 1;]])], + [ac_cv_func_strnlen_working=yes], + [ac_cv_func_strnlen_working=no], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], + [[#if defined _AIX && !defined _AIX51 + #error "AIX pre 5.1 is buggy" + #endif + #ifdef __ANDROID__ + #include + #if __ANDROID_API__ < 22 + #error "Android API < 22 is buggy" + #endif + #endif + ]])], + [ac_cv_func_strnlen_working=yes], + [ac_cv_func_strnlen_working=no])])]) test $ac_cv_func_strnlen_working = no && AC_LIBOBJ([strnlen]) ])# AC_FUNC_STRNLEN