bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* Don't treat Apple's new Citrus/FreeBSD-based iconv like GNU libiconv
@ 2024-02-14 22:45 Bruno Haible
  2024-02-24 13:01 ` Bruno Haible
  0 siblings, 1 reply; 2+ messages in thread
From: Bruno Haible @ 2024-02-14 22:45 UTC (permalink / raw)
  To: bug-gnulib

Apple's iconv() implementation, for many years, was based on GNU libiconv.
They stopped upgrading in 2007, when I switched the license of the iconv
program from GPLv2+ to GPLv3+. (Although the GNU libiconv library remained
under LGPLv2+.)

In 2023, they replaced the implementation with the Citrus/FreeBSD implementation
and a few Apple-specific changes [1][2].

  (1) They turned on transliteration by default, and iconv()'s return value
      is 0 regardless whether there was transliteration or not. Thus iconv()
      loses the ability to tell whether a conversion was faithful or lossy.

  (2) They continue to define the _LIBICONV_VERSION macro and the
      _libiconv_version variable. Thus they are lying about their
      implementation, and shipping a fake GNU libiconv.

(1) has been corrected meanwhile: in a newer version [2] they again follow
glibc and GNU libiconv's behaviour of reporting EILSEQ instead of inserting
a question mark or other "nice" characters.

Since a workaround for (1) would be quite complex (due to the need to verify
the roundtripping of each converted character), and since Apple tends to
force new releases onto its users quite rapidly, I won't add a workaround
for that one.

But we need a workaround for (2): We need to distinguish:
  - The bastard (*) Apple iconv:
      (_LIBICONV_VERSION == 0x10b && defined __APPLE__)
  - The authentic GNU libiconv:
      (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__))
The patch below does this throughout Gnulib.

[1] https://lists.gnu.org/archive/html/bug-gettext/2024-02/msg00003.html
[2] https://github.com/apple-oss-distributions/libiconv
(*) bastard as an adjective, not as a noun.


2024-02-14  Bruno Haible  <bruno@clisp.org>

	Don't treat Apple's new Citrus/FreeBSD-based iconv like GNU libiconv.
	* m4/iconv_open.m4 (gl_FUNC_ICONV_OPEN): Don't treat the bastard Apple
	iconv like GNU libiconv.
	* lib/striconv.c (mem_cd_iconv, str_cd_iconv): Likewise.
	* lib/striconveh.c (iconv_carefully, iconv_carefully_1,
	mem_cd_iconveh_internal): Likewise.
	* lib/propername.c (proper_name_utf8): Likewise.
	* lib/unicodeio.c (unicode_to_mb): Likewise.
	* lib/uniconv/u16-conv-from-enc.c (UTF16_NAME): Likewise.
	* lib/uniconv/u16-conv-to-enc.c (UTF16_NAME): Likewise.
	* lib/uniconv/u16-strconv-to-enc.c (UTF16_NAME): Likewise.
	* lib/uniconv/u32-conv-from-enc.c (UTF32_NAME): Likewise.
	* lib/uniconv/u32-conv-to-enc.c (UTF32_NAME): Likewise.
	* lib/uniconv/u32-strconv-to-enc.c (UTF32_NAME): Likewise.
	* tests/test-striconveh.c (main): Likewise.
	* tests/test-striconveha.c (main): Likewise.
	* tests/uniconv/test-u8-conv-from-enc.c (main): Likewise.
	* tests/uniconv/test-u8-strconv-from-enc.c (main): Likewise.
	* tests/uniconv/test-u16-conv-from-enc.c (main): Likewise.
	* tests/uniconv/test-u16-strconv-from-enc.c (main): Likewise.
	* tests/uniconv/test-u32-conv-from-enc.c (main): Likewise.
	* tests/uniconv/test-u32-strconv-from-enc.c (main): Likewise.

diff --git a/lib/propername.c b/lib/propername.c
index d5b52a2c11..7e072d35b6 100644
--- a/lib/propername.c
+++ b/lib/propername.c
@@ -245,7 +245,7 @@ proper_name_utf8 (const char *name_ascii, const char *name_utf8)
 
         if (converted_translit != NULL)
           {
-#  if !_LIBICONV_VERSION
+#  if !_LIBICONV_VERSION || (_LIBICONV_VERSION == 0x10b && defined __APPLE__)
             /* Don't use the transliteration if it added question marks.
                glibc's transliteration falls back to question marks; libiconv's
                transliteration does not.
diff --git a/lib/striconv.c b/lib/striconv.c
index 9688a9fbb1..f7d9ccf8e2 100644
--- a/lib/striconv.c
+++ b/lib/striconv.c
@@ -82,11 +82,12 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
             else
               return -1;
           }
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     && !(defined __GLIBC__ && !defined __UCLIBC__)
         /* Irix iconv() inserts a NUL byte if it cannot convert.
            NetBSD iconv() inserts a question mark if it cannot convert.
-           Only GNU libiconv and GNU libc are known to prefer to fail rather
-           than doing a lossy conversion.  */
+           Only GNU libiconv (excluding the bastard Apple iconv) and GNU libc
+           are known to prefer to fail rather than doing a lossy conversion.  */
         else if (res > 0)
           {
             errno = EILSEQ;
@@ -158,11 +159,12 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
             else
               goto fail;
           }
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     && !(defined __GLIBC__ && !defined __UCLIBC__)
         /* Irix iconv() inserts a NUL byte if it cannot convert.
            NetBSD iconv() inserts a question mark if it cannot convert.
-           Only GNU libiconv and GNU libc are known to prefer to fail rather
-           than doing a lossy conversion.  */
+           Only GNU libiconv (excluding the bastard Apple iconv) and GNU libc
+           are known to prefer to fail rather than doing a lossy conversion.  */
         else if (res > 0)
           {
             errno = EILSEQ;
@@ -206,14 +208,16 @@ str_cd_iconv (const char *src, iconv_t cd)
      to a trailing NUL byte in the output.  But not for UTF-7.  So that this
      function is usable for UTF-7, we have to exclude the NUL byte from the
      conversion and add it by hand afterwards.  */
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     && !(defined __GLIBC__ && !defined __UCLIBC__)
   /* Irix iconv() inserts a NUL byte if it cannot convert.
      NetBSD iconv() inserts a question mark if it cannot convert.
-     Only GNU libiconv and GNU libc are known to prefer to fail rather
-     than doing a lossy conversion.  For other iconv() implementations,
-     we have to look at the number of irreversible conversions returned;
-     but this information is lost when iconv() returns for an E2BIG reason.
-     Therefore we cannot use the second, faster algorithm.  */
+     Only GNU libiconv (excluding the bastard Apple iconv) and GNU libc are
+     known to prefer to fail rather than doing a lossy conversion.  For other
+     iconv() implementations, we have to look at the number of irreversible
+     conversions returned; but this information is lost when iconv() returns
+     for an E2BIG reason.  Therefore we cannot use the second, faster
+     algorithm.  */
 
   char *result = NULL;
   size_t length = 0;
diff --git a/lib/striconveh.c b/lib/striconveh.c
index 43cc3e11a4..db83a1ddca 100644
--- a/lib/striconveh.c
+++ b/lib/striconveh.c
@@ -139,11 +139,12 @@ iconveh_close (const iconveh_t *cd)
 /* iconv_carefully is like iconv, except that it stops as soon as it encounters
    a conversion error, and it returns in *INCREMENTED a boolean telling whether
    it has incremented the input pointers past the error location.  */
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     && !(defined __GLIBC__ && !defined __UCLIBC__)
 /* Irix iconv() inserts a NUL byte if it cannot convert.
    NetBSD iconv() inserts a question mark if it cannot convert.
-   Only GNU libiconv and GNU libc are known to prefer to fail rather
-   than doing a lossy conversion.  */
+   Only GNU libiconv (excluding the bastard Apple iconv) and GNU libc are
+   known to prefer to fail rather than doing a lossy conversion.  */
 static size_t
 iconv_carefully (iconv_t cd,
                  const char **inbuf, size_t *inbytesleft,
@@ -247,11 +248,12 @@ iconv_carefully_1 (iconv_t cd,
 
   *inbuf = inptr;
   *inbytesleft = inptr_end - inptr;
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     && !(defined __GLIBC__ && !defined __UCLIBC__)
   /* Irix iconv() inserts a NUL byte if it cannot convert.
      NetBSD iconv() inserts a question mark if it cannot convert.
-     Only GNU libiconv and GNU libc are known to prefer to fail rather
-     than doing a lossy conversion.  */
+     Only GNU libiconv (excluding the bastard Apple iconv) and GNU libc are
+     known to prefer to fail rather than doing a lossy conversion.  */
   if (res != (size_t)(-1) && res > 0)
     {
       /* iconv() has already incremented INPTR.  We cannot go back to a
@@ -948,13 +950,15 @@ mem_cd_iconveh_internal (const char *src, size_t srclen,
                               }
                             length = out2ptr - result;
                           }
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     && !(defined __GLIBC__ && !defined __UCLIBC__)
                         /* IRIX iconv() inserts a NUL byte if it cannot convert.
                            FreeBSD iconv(), NetBSD iconv(), and Solaris 11
                            iconv() insert a '?' if they cannot convert.
                            musl libc iconv() inserts a '*' if it cannot convert.
-                           Only GNU libiconv and GNU libc are known to prefer
-                           to fail rather than doing a lossy conversion.  */
+                           Only GNU libiconv (excluding the bastard Apple iconv)
+                           and GNU libc are known to prefer to fail rather than
+                           doing a lossy conversion.  */
                         if (res != (size_t)(-1) && res > 0)
                           {
                             errno = EILSEQ;
diff --git a/lib/unicodeio.c b/lib/unicodeio.c
index 565c98c65d..9ed3875f93 100644
--- a/lib/unicodeio.c
+++ b/lib/unicodeio.c
@@ -144,7 +144,7 @@ unicode_to_mb (unsigned int code,
 # endif
           /* FreeBSD iconv(), NetBSD iconv(), and Solaris 11 iconv() insert
              a '?' if they cannot convert.  */
-# if !defined _LIBICONV_VERSION
+# if !defined _LIBICONV_VERSION || (_LIBICONV_VERSION == 0x10b && defined __APPLE__)
           || (res > 0 && outptr - outbuf == 1 && *outbuf == '?')
 # endif
           /* musl libc iconv() inserts a '*' if it cannot convert.  */
diff --git a/lib/uniconv/u16-conv-from-enc.c b/lib/uniconv/u16-conv-from-enc.c
index aa94e915f5..272cba3f0e 100644
--- a/lib/uniconv/u16-conv-from-enc.c
+++ b/lib/uniconv/u16-conv-from-enc.c
@@ -36,7 +36,8 @@
 #include "unistr.h"
 
 /* Name of UTF-16 encoding with machine dependent endianness and alignment.  */
-#if defined _LIBICONV_VERSION || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
+#if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+    || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
 # ifdef WORDS_BIGENDIAN
 #  define UTF16_NAME "UTF-16BE"
 # else
diff --git a/lib/uniconv/u16-conv-to-enc.c b/lib/uniconv/u16-conv-to-enc.c
index 4f8aa8a443..08f4e06324 100644
--- a/lib/uniconv/u16-conv-to-enc.c
+++ b/lib/uniconv/u16-conv-to-enc.c
@@ -39,7 +39,8 @@
 #define SIZEOF(array) (sizeof (array) / sizeof (array[0]))
 
 /* Name of UTF-16 encoding with machine dependent endianness and alignment.  */
-#if defined _LIBICONV_VERSION || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
+#if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+    || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
 # ifdef WORDS_BIGENDIAN
 #  define UTF16_NAME "UTF-16BE"
 # else
diff --git a/lib/uniconv/u16-strconv-to-enc.c b/lib/uniconv/u16-strconv-to-enc.c
index 4455dd5101..7a5ab81848 100644
--- a/lib/uniconv/u16-strconv-to-enc.c
+++ b/lib/uniconv/u16-strconv-to-enc.c
@@ -39,7 +39,8 @@
 #define SIZEOF(array) (sizeof (array) / sizeof (array[0]))
 
 /* Name of UTF-16 encoding with machine dependent endianness and alignment.  */
-#if defined _LIBICONV_VERSION || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
+#if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+    || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
 # ifdef WORDS_BIGENDIAN
 #  define UTF16_NAME "UTF-16BE"
 # else
diff --git a/lib/uniconv/u32-conv-from-enc.c b/lib/uniconv/u32-conv-from-enc.c
index 9d4ac530d1..6e5f04958b 100644
--- a/lib/uniconv/u32-conv-from-enc.c
+++ b/lib/uniconv/u32-conv-from-enc.c
@@ -37,7 +37,7 @@
 
 /* Name of UTF-32 or UCS-4 encoding with machine dependent endianness and
    alignment.  */
-#if defined _LIBICONV_VERSION
+#if defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)
 # define UTF32_NAME "UCS-4-INTERNAL"
 #elif ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
 # define UTF32_NAME "WCHAR_T"
diff --git a/lib/uniconv/u32-conv-to-enc.c b/lib/uniconv/u32-conv-to-enc.c
index 6fcd132513..e446c6920c 100644
--- a/lib/uniconv/u32-conv-to-enc.c
+++ b/lib/uniconv/u32-conv-to-enc.c
@@ -40,7 +40,7 @@
 
 /* Name of UTF-32 or UCS-4 encoding with machine dependent endianness and
    alignment.  */
-#if defined _LIBICONV_VERSION
+#if defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)
 # define UTF32_NAME "UCS-4-INTERNAL"
 #elif ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
 # define UTF32_NAME "WCHAR_T"
diff --git a/lib/uniconv/u32-strconv-to-enc.c b/lib/uniconv/u32-strconv-to-enc.c
index 848318e610..c7fb3f0d24 100644
--- a/lib/uniconv/u32-strconv-to-enc.c
+++ b/lib/uniconv/u32-strconv-to-enc.c
@@ -40,7 +40,7 @@
 
 /* Name of UTF-32 or UCS-4 encoding with machine dependent endianness and
    alignment.  */
-#if defined _LIBICONV_VERSION
+#if defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)
 # define UTF32_NAME "UCS-4-INTERNAL"
 #elif ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
 # define UTF32_NAME "WCHAR_T"
diff --git a/m4/iconv_open.m4 b/m4/iconv_open.m4
index d4fd3ab7f6..c6fe346bd4 100644
--- a/m4/iconv_open.m4
+++ b/m4/iconv_open.m4
@@ -1,4 +1,4 @@
-# iconv_open.m4 serial 16
+# iconv_open.m4 serial 17
 dnl Copyright (C) 2007-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -16,7 +16,8 @@ AC_DEFUN([gl_FUNC_ICONV_OPEN]
     dnl We know that GNU libiconv and GNU libc do.
     AC_EGREP_CPP([gnu_iconv], [
       #include <iconv.h>
-      #if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+      #if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+          || (defined __GLIBC__ && !defined __UCLIBC__)
        gnu_iconv
       #endif
       ], [gl_func_iconv_gnu=yes], [gl_func_iconv_gnu=no])
diff --git a/tests/test-striconveh.c b/tests/test-striconveh.c
index eb8a3e2b74..71dfc3f73f 100644
--- a/tests/test-striconveh.c
+++ b/tests/test-striconveh.c
@@ -68,7 +68,7 @@ main ()
   iconv_t cd_88592_to_utf8 = iconv_open ("UTF-8", "ISO-8859-2");
   iconv_t cd_utf8_to_88592 = iconv_open ("ISO-8859-2", "UTF-8");
   iconv_t cd_utf7_to_utf8 = iconv_open ("UTF-8", "UTF-7");
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
   iconv_t cd_ascii_to_gb18030 = iconv_open ("GB18030", "ASCII");
   iconv_t cd_utf8_to_gb18030 = iconv_open ("GB18030", "UTF-8");
   iconv_t cd_88591_to_gb18030 = iconv_open ("GB18030", "ISO-8859-1");
@@ -82,7 +82,7 @@ main ()
   iconveh_t cdeh_88591_to_utf8;
   iconveh_t cdeh_utf8_to_88591;
   iconveh_t cdeh_utf7_to_utf8;
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
   iconveh_t cdeh_ascii_to_gb18030;
   iconveh_t cdeh_88591_to_gb18030;
   iconveh_t cdeh_utf7_to_gb18030;
@@ -93,7 +93,7 @@ main ()
   ASSERT (cd_utf8_to_88591 != (iconv_t)(-1));
   ASSERT (cd_88592_to_utf8 != (iconv_t)(-1));
   ASSERT (cd_utf8_to_88592 != (iconv_t)(-1));
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
   ASSERT (cd_ascii_to_gb18030 != (iconv_t)(-1));
   ASSERT (cd_utf8_to_gb18030 != (iconv_t)(-1));
 # endif
@@ -130,7 +130,7 @@ main ()
   cdeh_utf7_to_utf8.cd1 = cd_utf7_to_utf8;
   cdeh_utf7_to_utf8.cd2 = (iconv_t)(-1);
 
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
   cdeh_ascii_to_gb18030.cd = cd_ascii_to_gb18030;
   cdeh_ascii_to_gb18030.cd1 = cd_ascii_to_utf8;
   cdeh_ascii_to_gb18030.cd2 = cd_utf8_to_gb18030;
@@ -330,7 +330,7 @@ main ()
         }
     }
 
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
   /* Test conversion from ISO-8859-1 to GB18030 with no errors.  */
   for (h = 0; h < SIZEOF (handlers); h++)
     {
@@ -462,7 +462,7 @@ main ()
         }
     }
 
-# if defined _LIBICONV_VERSION || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
   /* Test conversion from ASCII to GB18030 with invalid input (EILSEQ).
      Note: glibc's GB18030 converter was buggy in glibc-2.15; fixed by
      Andreas Schwab on 2012-02-06.  */
@@ -648,7 +648,7 @@ main ()
           free (result);
         }
 
-#  if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+#  if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
       /* Test conversion from UTF-7 to GB18030 with EINVAL.  */
       for (h = 0; h < SIZEOF (handlers); h++)
         {
@@ -748,7 +748,7 @@ main ()
             }
         }
 
-#   if defined _LIBICONV_VERSION || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
+#   if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
       /* Test conversion from UTF-7 to GB18030 with EILSEQ.
          Note: glibc's GB18030 converter was buggy in glibc-2.15; fixed by
          Andreas Schwab on 2012-02-06.  */
@@ -926,7 +926,7 @@ main ()
       free (result);
     }
 
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
   /* Test conversion from ISO-8859-1 to GB18030 with no errors.  */
   for (h = 0; h < SIZEOF (handlers); h++)
     {
@@ -989,7 +989,7 @@ main ()
         }
     }
 
-# if defined _LIBICONV_VERSION || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
   /* Test conversion from ASCII to GB18030 with invalid input (EILSEQ).
      Note: glibc's GB18030 converter was buggy in glibc-2.15; fixed by
      Andreas Schwab on 2012-02-06.  */
@@ -1207,7 +1207,7 @@ main ()
         }
     }
 
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
   /* Test conversion from ISO-8859-1 to GB18030 with no errors.  */
   for (h = 0; h < SIZEOF (handlers); h++)
     {
@@ -1427,7 +1427,7 @@ main ()
       free (result);
     }
 
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
   /* Test conversion from ISO-8859-1 to GB18030 with no errors.  */
   for (h = 0; h < SIZEOF (handlers); h++)
     {
diff --git a/tests/test-striconveha.c b/tests/test-striconveha.c
index 657ec127c4..c401177e29 100644
--- a/tests/test-striconveha.c
+++ b/tests/test-striconveha.c
@@ -308,7 +308,8 @@ main ()
     }
 
   /* autodetect_jp is only supported when iconv() support ISO-2022-JP-2.  */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
   if (iconv_supports_encoding ("ISO-2022-JP-2"))
     {
       /* Test conversions from autodetect_jp to UTF-8.  */
@@ -547,7 +548,8 @@ main ()
     }
 
   /* autodetect_jp is only supported when iconv() support ISO-2022-JP-2.  */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
   if (iconv_supports_encoding ("ISO-2022-JP-2"))
     {
       /* Test conversions from autodetect_jp to UTF-8.  */
diff --git a/tests/uniconv/test-u16-conv-from-enc.c b/tests/uniconv/test-u16-conv-from-enc.c
index c917445335..48c7fd7760 100644
--- a/tests/uniconv/test-u16-conv-from-enc.c
+++ b/tests/uniconv/test-u16-conv-from-enc.c
@@ -117,7 +117,8 @@ main ()
     }
 
   /* autodetect_jp is only supported when iconv() support ISO-2022-JP-2.  */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
   if (iconv_supports_encoding ("ISO-2022-JP-2"))
     {
       /* Test conversions from autodetect_jp to UTF-16.  */
diff --git a/tests/uniconv/test-u16-strconv-from-enc.c b/tests/uniconv/test-u16-strconv-from-enc.c
index 495112aed7..b1cb1a881a 100644
--- a/tests/uniconv/test-u16-strconv-from-enc.c
+++ b/tests/uniconv/test-u16-strconv-from-enc.c
@@ -71,7 +71,8 @@ main ()
     }
 
   /* autodetect_jp is only supported when iconv() support ISO-2022-JP-2.  */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
   if (iconv_supports_encoding ("ISO-2022-JP-2"))
     {
       /* Test conversions from autodetect_jp to UTF-16.  */
diff --git a/tests/uniconv/test-u32-conv-from-enc.c b/tests/uniconv/test-u32-conv-from-enc.c
index e9e34def5f..994bfb49fd 100644
--- a/tests/uniconv/test-u32-conv-from-enc.c
+++ b/tests/uniconv/test-u32-conv-from-enc.c
@@ -117,7 +117,8 @@ main ()
     }
 
   /* autodetect_jp is only supported when iconv() support ISO-2022-JP-2.  */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
   if (iconv_supports_encoding ("ISO-2022-JP-2"))
     {
       /* Test conversions from autodetect_jp to UTF-16.  */
diff --git a/tests/uniconv/test-u32-strconv-from-enc.c b/tests/uniconv/test-u32-strconv-from-enc.c
index 0b03a245bd..320bc185cd 100644
--- a/tests/uniconv/test-u32-strconv-from-enc.c
+++ b/tests/uniconv/test-u32-strconv-from-enc.c
@@ -71,7 +71,8 @@ main ()
     }
 
   /* autodetect_jp is only supported when iconv() support ISO-2022-JP-2.  */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
   if (iconv_supports_encoding ("ISO-2022-JP-2"))
     {
       /* Test conversions from autodetect_jp to UTF-16.  */
diff --git a/tests/uniconv/test-u8-conv-from-enc.c b/tests/uniconv/test-u8-conv-from-enc.c
index e663aae347..641200f2b5 100644
--- a/tests/uniconv/test-u8-conv-from-enc.c
+++ b/tests/uniconv/test-u8-conv-from-enc.c
@@ -112,7 +112,8 @@ main ()
     }
 
   /* autodetect_jp is only supported when iconv() support ISO-2022-JP-2.  */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
   if (iconv_supports_encoding ("ISO-2022-JP-2"))
     {
       /* Test conversions from autodetect_jp to UTF-8.  */
diff --git a/tests/uniconv/test-u8-strconv-from-enc.c b/tests/uniconv/test-u8-strconv-from-enc.c
index cd1b44e000..61e3230ba6 100644
--- a/tests/uniconv/test-u8-strconv-from-enc.c
+++ b/tests/uniconv/test-u8-strconv-from-enc.c
@@ -62,7 +62,8 @@ main ()
     }
 
   /* autodetect_jp is only supported when iconv() support ISO-2022-JP-2.  */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+     || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
   if (iconv_supports_encoding ("ISO-2022-JP-2"))
     {
       /* Test conversions from autodetect_jp to UTF-8.  */





^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: Don't treat Apple's new Citrus/FreeBSD-based iconv like GNU libiconv
  2024-02-14 22:45 Don't treat Apple's new Citrus/FreeBSD-based iconv like GNU libiconv Bruno Haible
@ 2024-02-24 13:01 ` Bruno Haible
  0 siblings, 0 replies; 2+ messages in thread
From: Bruno Haible @ 2024-02-24 13:01 UTC (permalink / raw)
  To: bug-gnulib

On macOS 12.5, I'm seeing this test failure:

$ ./test-striconveha
../../tests/test-striconveha.c:426: assertion 'retval == 0' failed

Apparently the transliteration of /usr/lib/libiconv.2.dylib does
not work like the GNU libiconv one.
Either this is a copy of GNU libiconv 1.11 with modified transliteration,
or it's a backport of the bastard Apple iconv that they deploy on newer
macOS releases since fall 2023.

This patch avoids the failure.


2024-02-24  Bruno Haible  <bruno@clisp.org>

	striconveha tests: Avoid test failure on macOS 12.5.
	* tests/test-striconveha.c (main): Skip transliteration tests when using
	Apple's modified GNU libiconv or the bastard Apple iconv.

diff --git a/tests/test-striconveha.c b/tests/test-striconveha.c
index c401177e29..376f3cb603 100644
--- a/tests/test-striconveha.c
+++ b/tests/test-striconveha.c
@@ -406,7 +406,7 @@ main ()
     }
 # endif
 
-# if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) && !defined __UCLIBC__) || _LIBICONV_VERSION >= 0x0105
+# if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) && !defined __UCLIBC__) || (_LIBICONV_VERSION >= 0x0105 && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__))
   /* Test conversion from UTF-8 to ISO-8859-1 with transliteration.  */
   for (h = 0; h < SIZEOF (handlers); h++)
     {
@@ -586,7 +586,7 @@ main ()
     }
 # endif
 
-# if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) && !defined __UCLIBC__) || _LIBICONV_VERSION >= 0x0105
+# if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) && !defined __UCLIBC__) || (_LIBICONV_VERSION >= 0x0105 && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__))
   /* Test conversion from UTF-8 to ISO-8859-1 with transliteration.  */
   for (h = 0; h < SIZEOF (handlers); h++)
     {





^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-02-24 13:02 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-14 22:45 Don't treat Apple's new Citrus/FreeBSD-based iconv like GNU libiconv Bruno Haible
2024-02-24 13:01 ` Bruno Haible

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).