Skip to content

Commit

Permalink
gettext: fix the regression where %I64d support was broken
Browse files Browse the repository at this point in the history
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 <johannes.schindelin@gmx.de>
  • Loading branch information
dscho committed Nov 10, 2023
1 parent 151ed5e commit aa36276
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
36 changes: 36 additions & 0 deletions mingw-w64-gettext/0001-printf_parse-fix-off-by-two.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
From 45cd4b6d5f3db4ac26219ddde951fc09589e74a0 Mon Sep 17 00:00:00 2001
From: Johannes Schindelin <johannes.schindelin@gmx.de>
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 <johannes.schindelin@gmx.de>
---
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

32 changes: 29 additions & 3 deletions mingw-w64-gettext/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@ 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'
'ef9f11a1cd10539d4323c6fcba3013cc503d47366004fe8a99c642dc3ddf2fd0'
'a28a27192f336f0b0908bdbf840d3b19d7b587c4ac52cad635cb43e95eb3c78d'
'380dbddee2f9e2feee4c1435e8a942b5d11d0125e60c3350ebb10c19b19011aa'
'c354f6a7021069c99b90f1c6d6f6a4ccf40a01e9f6742b866df2b5a7286cb868'
'4f34906eeb535c74fa3f2936729b59c36d05d503a274e2b850fc770263c60b46')
'4f34906eeb535c74fa3f2936729b59c36d05d503a274e2b850fc770263c60b46'
'e6187cc1f1190fcb2267e4b811ade0049126e78dd8fd37d3a86a716dfdbf713e')
validpgpkeys=('462225C3B46F34879FC8496CD605848ED7E69871' # Daiki Ueno
'9001B85AF9E1B83DF1BDA942F5BE8B267C6A406D') # Bruno Haible

Expand All @@ -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
}
Expand Down Expand Up @@ -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 <<EOF
#include <stdio.h>
#include <stdint.h>
#include <libintl.h>
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
Expand Down

0 comments on commit aa36276

Please sign in to comment.