From 9ebeee1409d6ad5222a9cc22ae26c869de8b0208 Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Fri, 23 Oct 2026 22:04:28 -0700 Subject: [PATCH] fix: correct bundled tar allocation limits on 32-bit Android Derive the widths, limits, and integer literal suffixes from the compiler's target type sizes. Add a compile-only C11 target with static assertions that check the widths, limits, and literal types against the ABI without linking the checks into tar. Fixes #443 --- .../src/main/jni/external/tar/CMakeLists.txt | 10 +++++++ .../main/jni/external/tar/tar-config/config.h | 16 ++++++++--- .../external/tar/tar-gnu-embedded/stdint.h | 27 ++++++------------- .../main/jni/external/tar/tests/abi-limits.c | 25 +++++++++++++++++ 4 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 source/native/src/main/jni/external/tar/tests/abi-limits.c diff --git a/source/native/src/main/jni/external/tar/CMakeLists.txt b/source/native/src/main/jni/external/tar/CMakeLists.txt index 7d9cdf943b..e2364f11ee 100644 --- a/source/native/src/main/jni/external/tar/CMakeLists.txt +++ b/source/native/src/main/jni/external/tar/CMakeLists.txt @@ -19,6 +19,16 @@ add_link_options( -Wl,-allow-multiple-definition ) +# Compile ABI checks without linking them into tar. +add_library(tar-abi-limits OBJECT tests/abi-limits.c) +target_compile_features(tar-abi-limits PRIVATE c_std_11) +target_include_directories(tar-abi-limits + PRIVATE + tar-config + tar-gnu-embedded + tar/gnu +) + # libgnu.a add_library(libgnu STATIC tar/gnu/acl-errno-valid.c diff --git a/source/native/src/main/jni/external/tar/tar-config/config.h b/source/native/src/main/jni/external/tar/tar-config/config.h index 529079cc6d..3766fdfdc1 100644 --- a/source/native/src/main/jni/external/tar/tar-config/config.h +++ b/source/native/src/main/jni/external/tar/tar-config/config.h @@ -9,13 +9,13 @@ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* Define to the number of bits in type 'ptrdiff_t'. */ -#define BITSIZEOF_PTRDIFF_T 64 +#define BITSIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__ * 8) /* Define to the number of bits in type 'sig_atomic_t'. */ #define BITSIZEOF_SIG_ATOMIC_T 32 /* Define to the number of bits in type 'size_t'. */ -#define BITSIZEOF_SIZE_T 64 +#define BITSIZEOF_SIZE_T (__SIZEOF_SIZE_T__ * 8) /* Define to the number of bits in type 'wchar_t'. */ #define BITSIZEOF_WCHAR_T 32 @@ -2213,7 +2213,11 @@ /* Define to l, ll, u, ul, ull, etc., as suitable for constants of type 'ptrdiff_t'. */ -#define PTRDIFF_T_SUFFIX l +#if __SIZEOF_PTRDIFF_T__ == 8 +# define PTRDIFF_T_SUFFIX l +#else +# define PTRDIFF_T_SUFFIX +#endif /* Define to 1 if readlink fails to recognize a trailing slash. */ /* #undef READLINK_TRAILING_SLASH_BUG */ @@ -2283,7 +2287,11 @@ /* Define to l, ll, u, ul, ull, etc., as suitable for constants of type 'size_t'. */ -#define SIZE_T_SUFFIX ul +#if __SIZEOF_SIZE_T__ == 8 +# define SIZE_T_SUFFIX ul +#else +# define SIZE_T_SUFFIX u +#endif /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be diff --git a/source/native/src/main/jni/external/tar/tar-gnu-embedded/stdint.h b/source/native/src/main/jni/external/tar/tar-gnu-embedded/stdint.h index 5e70c2d77c..8d9dcab188 100644 --- a/source/native/src/main/jni/external/tar/tar-gnu-embedded/stdint.h +++ b/source/native/src/main/jni/external/tar/tar-gnu-embedded/stdint.h @@ -531,19 +531,12 @@ typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) /* ptrdiff_t limits */ # undef PTRDIFF_MIN # undef PTRDIFF_MAX -# if 0 -# ifdef _LP64 -# define PTRDIFF_MIN _STDINT_SIGNED_MIN (64, 0l) -# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l) -# else -# define PTRDIFF_MIN _STDINT_SIGNED_MIN (32, 0) -# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) -# endif +# if __SIZEOF_PTRDIFF_T__ == 8 +# define PTRDIFF_MIN _STDINT_SIGNED_MIN (64, 0l) +# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l) # else -# define PTRDIFF_MIN \ - _STDINT_SIGNED_MIN (64, 0l) -# define PTRDIFF_MAX \ - _STDINT_MAX (1, 64, 0l) +# define PTRDIFF_MIN _STDINT_SIGNED_MIN (32, 0) +# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) # endif /* sig_atomic_t limits */ @@ -563,14 +556,10 @@ typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) /* size_t limit */ # undef SIZE_MAX -# if 0 -# ifdef _LP64 -# define SIZE_MAX _STDINT_MAX (0, 64, 0ul) -# else -# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) -# endif -# else +# if __SIZEOF_SIZE_T__ == 8 # define SIZE_MAX _STDINT_MAX (0, 64, 0ul) +# else +# define SIZE_MAX _STDINT_MAX (0, 32, 0u) # endif /* wchar_t limits */ diff --git a/source/native/src/main/jni/external/tar/tests/abi-limits.c b/source/native/src/main/jni/external/tar/tests/abi-limits.c new file mode 100644 index 0000000000..91c9a56b4c --- /dev/null +++ b/source/native/src/main/jni/external/tar/tests/abi-limits.c @@ -0,0 +1,25 @@ +#include + +#include +#include +#include + +#define LITERAL_SUFFIX_(value, suffix) value ## suffix +#define LITERAL_SUFFIX(value, suffix) LITERAL_SUFFIX_ (value, suffix) + +_Static_assert (BITSIZEOF_SIZE_T == sizeof (size_t) * CHAR_BIT, + "size_t width must match the target ABI"); +_Static_assert (BITSIZEOF_PTRDIFF_T == sizeof (ptrdiff_t) * CHAR_BIT, + "ptrdiff_t width must match the target ABI"); +_Static_assert (SIZE_MAX == (size_t) -1, + "SIZE_MAX must match the target ABI"); +_Static_assert (PTRDIFF_MAX == __PTRDIFF_MAX__, + "PTRDIFF_MAX must match the target ABI"); +_Static_assert (PTRDIFF_MIN == -__PTRDIFF_MAX__ - 1, + "PTRDIFF_MIN must match the target ABI"); +_Static_assert (_Generic (LITERAL_SUFFIX (0, SIZE_T_SUFFIX), + size_t: 1, default: 0), + "SIZE_T_SUFFIX must produce a size_t literal"); +_Static_assert (_Generic (LITERAL_SUFFIX (0, PTRDIFF_T_SUFFIX), + ptrdiff_t: 1, default: 0), + "PTRDIFF_T_SUFFIX must produce a ptrdiff_t literal");