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.
This commit is contained in:
Paul Eggert 2024-07-16 08:25:36 -07:00
parent 3a7aa01e2a
commit 2fb09fae28
3 changed files with 48 additions and 25 deletions

4
NEWS
View File

@ -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

View 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.

View 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)
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;
}
/* 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])])
/* 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