diff options
| author | Po Lu | 2024-07-05 12:09:52 +0800 |
|---|---|---|
| committer | Po Lu | 2024-07-05 12:09:52 +0800 |
| commit | 04d7318efa20cce3aa369fdfd563d8364feb6e78 (patch) | |
| tree | 12bec2e418e7572dc9fba3f927d6ca9ce7c8ce06 | |
| parent | 507a13f5a1615d39f31d75547835416b29677c03 (diff) | |
| download | emacs-04d7318efa20cce3aa369fdfd563d8364feb6e78.tar.gz emacs-04d7318efa20cce3aa369fdfd563d8364feb6e78.zip | |
Enable Gnulib substitute on Android systems with defective strnlen
* configure.ac (AC_FUNC_STRNLEN): Detect a bug where strnlen is
liable to integer overflows if addition of the search limit to
the string would also overflow.
* src/xdisp.c (store_mode_line_string): Remove stopgap measure.
| -rw-r--r-- | configure.ac | 24 | ||||
| -rw-r--r-- | src/xdisp.c | 13 |
2 files changed, 25 insertions, 12 deletions
diff --git a/configure.ac b/configure.ac index f0437d6f8cb..909f5786c9a 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -1611,6 +1611,30 @@ AC_DEFUN([gl_TYPE_OFF64_T], | |||
| 1611 | [HAVE_OFF64_T=1 | 1611 | [HAVE_OFF64_T=1 |
| 1612 | AC_SUBST([HAVE_OFF64_T])]) | 1612 | AC_SUBST([HAVE_OFF64_T])]) |
| 1613 | 1613 | ||
| 1614 | # `strnlen' cannot accept nlen greater than the size of the object S | ||
| 1615 | # on Android 2.2 and earlier. | ||
| 1616 | m4_define([ORIGINAL_AC_FUNC_STRNLEN], m4_defn([AC_FUNC_STRNLEN])) | ||
| 1617 | AC_DEFUN([AC_FUNC_STRNLEN], [ | ||
| 1618 | AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])dnl | ||
| 1619 | AC_REQUIRE([AC_CANONICAL_HOST])dnl | ||
| 1620 | AC_CACHE_CHECK([for strnlen capable of accepting large limits], | ||
| 1621 | [emacs_cv_func_strnlen_working], | ||
| 1622 | [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], [[ | ||
| 1623 | volatile size_t (*strnlen_pointer) (const char *s, size_t) = &strnlen; | ||
| 1624 | if ((*strnlen_pointer) ("", -1) != 0) | ||
| 1625 | return 1; | ||
| 1626 | return 0; | ||
| 1627 | ]])],[emacs_cv_func_strnlen_working=yes], | ||
| 1628 | [emacs_cv_func_strnlen_working=no], | ||
| 1629 | [# Guess no on Android 21 and earlier, yes elsewhere. | ||
| 1630 | AS_IF([test -n "$ANDROID_SDK" && test "$ANDROID_SDK" -lt 22], | ||
| 1631 | [emacs_cv_func_strnlen_working=no], | ||
| 1632 | [emacs_cv_func_strnlen_working='guessing yes'])])]) | ||
| 1633 | AS_IF([test "$emacs_cv_func_strnlen_working" != "no"], | ||
| 1634 | [ORIGINAL_AC_FUNC_STRNLEN], | ||
| 1635 | [ac_cv_func_strnlen_working=no | ||
| 1636 | AC_LIBOBJ([strnlen])])]) | ||
| 1637 | |||
| 1614 | # Initialize gnulib right after choosing the compiler. | 1638 | # Initialize gnulib right after choosing the compiler. |
| 1615 | dnl Amongst other things, this sets AR and ARFLAGS. | 1639 | dnl Amongst other things, this sets AR and ARFLAGS. |
| 1616 | gl_EARLY | 1640 | gl_EARLY |
diff --git a/src/xdisp.c b/src/xdisp.c index 566c4b211d6..8c7e8e5cb43 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -28065,18 +28065,7 @@ store_mode_line_string (const char *string, Lisp_Object lisp_string, | |||
| 28065 | 28065 | ||
| 28066 | if (string != NULL) | 28066 | if (string != NULL) |
| 28067 | { | 28067 | { |
| 28068 | #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY \ | 28068 | len = strnlen (string, precision <= 0 ? SIZE_MAX : precision); |
| 28069 | && __ANDROID_API__ < 22 | ||
| 28070 | /* Circumvent a bug in memchr preventing strnlen from returning | ||
| 28071 | valid values when a large limit is specified. | ||
| 28072 | |||
| 28073 | https://issuetracker.google.com/issues/37020957 */ | ||
| 28074 | if (precision <= 0 || ((uintptr_t) string | ||
| 28075 | > (UINTPTR_MAX - precision))) | ||
| 28076 | len = strlen (string); | ||
| 28077 | else | ||
| 28078 | #endif /* HAVE_ANDROID && !ANDROID_STUBIFY && __ANDROID_API__ < 22 */ | ||
| 28079 | len = strnlen (string, precision <= 0 ? SIZE_MAX : precision); | ||
| 28080 | lisp_string = make_string (string, len); | 28069 | lisp_string = make_string (string, len); |
| 28081 | if (NILP (props)) | 28070 | if (NILP (props)) |
| 28082 | props = mode_line_string_face_prop; | 28071 | props = mode_line_string_face_prop; |