]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Detect Android 5.0 strnlen bug
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 16 Jul 2024 15:25:36 +0000 (08:25 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 16 Jul 2024 15:26:28 +0000 (08:26 -0700)
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.

NEWS
doc/autoconf.texi
lib/autoconf/functions.m4

diff --git a/NEWS b/NEWS
index bca113911c6b3241df9f72e9d204375b23ce6702..615f493f93035109774007ffd47a51f209c94fa8 100644 (file)
--- 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
index ee3f2f7a4730384bef6650642363450d677052a8..dc07da5deeea5460ce09fcfc0a6f8d3ee2623a4e 100644 (file)
@@ -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.
index 7b03ad6a0f18b02df18204bcf80f232d7ed39422..ad11576d66838d190305c1c8fdcfd7f32fe5f663 100644 (file)
@@ -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 <android/api-level.h>
+           #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