]> git.ipfire.org Git - thirdparty/git.git/commitdiff
meson: detect broken iconv that requires ICONV_RESTART_RESET
authorPatrick Steinhardt <ps@pks.im>
Thu, 5 Mar 2026 11:20:22 +0000 (12:20 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 5 Mar 2026 19:19:56 +0000 (11:19 -0800)
In d0cec08d70 (utf8.c: prepare workaround for iconv under macOS 14/15,
2026-01-12) we have introduced a new workaround for a broken version of
libiconv on macOS. This workaround has for now only been wired up for
our Makefile, so using Meson with such a broken version will fail.

We can rather easily detect the broken behaviour. Some encodings have
different modes that can be switched to via an escape sequence. In the
case of ISO-2022-JP this can be done via "<Esc>$B" and "<Esc>(J" to
switch between ASCII and JIS modes. The bug now triggers when one does
multiple calls to iconv(3p) to convert a string piece by piece, where
the first call enters JIS mode. The second call forgets about the fact
that it is still in JIS mode, and consequently it will incorrectly treat
the input as ASCII, and thus the produced output is of course garbage.

Wire up a test that exercises this in Meson and, if it fails, set the
`ICONV_RESTART_RESET` define.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
meson.build

index 1f9694e42b13928f2be310e9abf97c79d17934bb..1f82a131d9a6f9a0cd7eeb398f626bd1f0aee707 100644 (file)
@@ -1053,6 +1053,32 @@ if iconv.found()
     ).returncode() != 0
       libgit_c_args += '-DICONV_OMITS_BOM'
     endif
+
+    if compiler.run('''
+      #include <iconv.h>
+      #include <string.h>
+
+      int main(int argc, const char *argv[])
+      {
+          char in[] = "\x1b\x24\x42\x24\x22\x24\x22\x1b\x28\x42", *inpos = in;
+          char out[7] = { 0 }, *outpos = out;
+          size_t insz = sizeof(in) - 1, outsz = 4;
+          iconv_t conv = iconv_open("UTF-8", "ISO-2022-JP");
+          if (!conv)
+              return 1;
+          if (iconv(conv, (void *) &inpos, &insz, &outpos, &outsz) != (size_t) -1)
+              return 2;
+          outsz = sizeof(out) - (outpos - out);
+          if (iconv(conv, (void *) &inpos, &insz, &outpos, &outsz) == (size_t) -1)
+              return 3;
+          return strcmp("\343\201\202\343\201\202", out) ? 4 : 0;
+      }
+    ''',
+      dependencies: iconv,
+      name: 'iconv handles restarts properly',
+    ).returncode() != 0
+      libgit_c_args += '-DICONV_RESTART_RESET'
+    endif
   endif
 else
   libgit_c_args += '-DNO_ICONV'