From aa36276ca64594de58ae1fb8a6c1af4317e927c6 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 10 Nov 2023 12:50:03 +0100 Subject: [PATCH] gettext: fix the regression where `%I64d` support was broken The `%I64` printf format family is a Windows-specific extension that has been handled for, like, eternity in `mingw-w64-gettext`. But the recent update to v0.22.3 broke that. The reason for that is a story of two episodes: - gnulib slipped in a major refactoring of the `printf()` format parsing into a commit whose purpose was to support new size specifiers: https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=480a59ba60fa0b43a1cebe218bbcea6a947f1e86 Unfortunately, the code handling `%I64` was converted incorrectly, where it previously skipped the `64` part before looking for the conversion specifier (correct) but now no longer does so (incorrect): https://git.savannah.gnu.org/cgit/gnulib.git/diff/lib/printf-parse.c?id=480a59ba60fa0b43a1cebe218bbcea6a947f1e86 - gettext saw a major refactoring with the intention to avoid duplicating gnulib's `printf()` logic, dropping its own code in favor of the latter: https://git.savannah.gnu.org/gitweb/?p=gettext.git;a=commitdiff;h=a80b9021019fe311b81771d67138496f512ef35a The result is that as of `mingw-w64-gettext` v0.22.3, `%I64d` is _started_ to be parsed but then fails because it mistakes `6` for the conversion character (instead of recognizing `d` as such). Work around this regression by skipping the `64` part again. This patch needs to be upstreamed to the gnulib project, yet we need to fix the `mingw-w64-gettext` regression at a more timely pace and need to integrate the patch early. Signed-off-by: Johannes Schindelin --- .../0001-printf_parse-fix-off-by-two.patch | 36 +++++++++++++++++++ mingw-w64-gettext/PKGBUILD | 32 +++++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 mingw-w64-gettext/0001-printf_parse-fix-off-by-two.patch diff --git a/mingw-w64-gettext/0001-printf_parse-fix-off-by-two.patch b/mingw-w64-gettext/0001-printf_parse-fix-off-by-two.patch new file mode 100644 index 0000000000000..c7899766836e8 --- /dev/null +++ b/mingw-w64-gettext/0001-printf_parse-fix-off-by-two.patch @@ -0,0 +1,36 @@ +From 45cd4b6d5f3db4ac26219ddde951fc09589e74a0 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Fri, 10 Nov 2023 12:16:02 +0100 +Subject: [PATCH] printf_parse: fix off-by-two + +In gnulib's 480a59ba60 (*printf-posix: ISO C 23: Support size specifiers +'wN' and 'wfN'., 2023-03-24), a major refactoring hides a bug in the +conversion of the code handling Windows' `%I64*` family of `printf()` +formats: before the refactoring, the `64` part was skipped (as desired), +but afterwards that part is not skipped and therefore the `6` is +mistaken for a conversion character. Which is invalid, of course, +causing the code to error out. + +Fix this by skipping the `64` part again. + +Signed-off-by: Johannes Schindelin +--- + gettext-runtime/intl/gnulib-lib/printf-parse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gettext-runtime/intl/gnulib-lib/printf-parse.c b/gettext-runtime/intl/gnulib-lib/printf-parse.c +index d3f2c3cb5d..6741ee5ff4 100644 +--- a/gettext-runtime/intl/gnulib-lib/printf-parse.c ++++ b/gettext-runtime/intl/gnulib-lib/printf-parse.c +@@ -555,7 +555,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) + unsigned_type = TYPE_ULONGINT; + pointer_type = TYPE_COUNT_LONGINT_POINTER; + } +- cp++; ++ cp += 3; + } + #endif + +-- +2.43.0.rc1.windows.1 + diff --git a/mingw-w64-gettext/PKGBUILD b/mingw-w64-gettext/PKGBUILD index b6161949c6e49..bfd7be80a77c6 100644 --- a/mingw-w64-gettext/PKGBUILD +++ b/mingw-w64-gettext/PKGBUILD @@ -27,7 +27,8 @@ source=(https://ftp.gnu.org/pub/gnu/${_realname}/${_realname}-${pkgver}.tar.gz{, gettext-0.22-disable-libtextstyle.patch 0021-replace-fsync.patch 0022-libasprintf.patch - 0023-gnulib.patch) + 0023-gnulib.patch + 0001-printf_parse-fix-off-by-two.patch) sha256sums=('839a260b2314ba66274dae7d245ec19fce190a3aa67869bf31354cb558df42c7' 'SKIP' 'cbc2f533012d646521afa20f8b256917fce040741ff42cf53fb6dd7123a6670a' @@ -35,7 +36,8 @@ sha256sums=('839a260b2314ba66274dae7d245ec19fce190a3aa67869bf31354cb558df42c7' 'a28a27192f336f0b0908bdbf840d3b19d7b587c4ac52cad635cb43e95eb3c78d' '380dbddee2f9e2feee4c1435e8a942b5d11d0125e60c3350ebb10c19b19011aa' 'c354f6a7021069c99b90f1c6d6f6a4ccf40a01e9f6742b866df2b5a7286cb868' - '4f34906eeb535c74fa3f2936729b59c36d05d503a274e2b850fc770263c60b46') + '4f34906eeb535c74fa3f2936729b59c36d05d503a274e2b850fc770263c60b46' + 'e6187cc1f1190fcb2267e4b811ade0049126e78dd8fd37d3a86a716dfdbf713e') validpgpkeys=('462225C3B46F34879FC8496CD605848ED7E69871' # Daiki Ueno '9001B85AF9E1B83DF1BDA942F5BE8B267C6A406D') # Bruno Haible @@ -62,7 +64,8 @@ prepare() { apply_patch_with_msg \ 0021-replace-fsync.patch \ 0022-libasprintf.patch \ - 0023-gnulib.patch + 0023-gnulib.patch \ + 0001-printf_parse-fix-off-by-two.patch autoreconf -fiv } @@ -105,6 +108,29 @@ build() { make } +verify () { + cd ${srcdir}/build-${MSYSTEM} + + # ensure that the Windows-specific `%I64*` format family is recognized correctly + cat >test-I64d.c < +#include +#include + +int main(int argc, char **argv) +{ + char buf[1024] = "(failure)"; + int len = libintl_snprintf(buf, 1024, "hello %llu %I64u 0:%d\n", (uint64_t)123, (uint64_t)123, 0); + + printf("%d, '%s'\n", len, buf); + + return len < 0 ? 1 : 0; +} +EOF + gcc -Wall -g -o test-I64d.exe test-I64d.c ./gettext-runtime/intl/.libs/libintl.a || return 1 + ./test-I64d.exe || return 1 +} + package() { cd ${srcdir}/build-${MSYSTEM} make DESTDIR="${pkgdir}" install