Skip to content

Tolerate duplicate iconv aliases on macOS - #81

Merged
rrthomas merged 2 commits into
rrthomas:masterfrom
pnavais:fix/darwin-iconv-duplicate-aliases
Oct 4, 2026
Merged

rrthomas merged 2 commits into
rrthomas:masterfrom
pnavais:fix/darwin-iconv-duplicate-aliases

Conversation

@pnavais

@pnavais pnavais commented Sep 28, 2026

Copy link
Copy Markdown

On macOS, iconv -l lists some charset aliases under more than one group. In particular, WINDOWS-874 appears with both CP1162 and CP874. When tables.py turns that listing into iconvdecl.h, module_iconv then tries to declare the same alias for two different charsets and aborts initialization with a contradiction error. That makes the check phase fail on aarch64-darwin (and likely x86_64-darwin as well).

This change:

  1. In tables.py, when digesting iconv -l, keep only the first occurrence of each alias name.
  2. In module_iconv, if an alias is already bound to a different charset, keep the existing binding instead of failing.

Verified on aarch64-darwin with recode 3.7.16: 488 good tests.

macOS libiconv lists some names (e.g. WINDOWS-874) under more than one
charset group. Treat the first binding as authoritative so module_iconv
initialization no longer fails during the check phase on Darwin.
@pnavais

pnavais commented Sep 30, 2026

Copy link
Copy Markdown
Author

For reference, the macOS job in the existing CI already fails on master with this bug, and it affects both architectures:

I've opened #82 with those workflow changes, adding Intel macOS and fixing the Homebrew paths and the ASAN preload. It depends on this PR, so the two can be reviewed and merged together.

Drop the empty else-if branch; only declare aliases that are not
already known, with the explanatory comment moved above the check.
@pnavais
pnavais force-pushed the fix/darwin-iconv-duplicate-aliases branch from b83b13d to ba15819 Compare September 30, 2026 20:14
@rrthomas

rrthomas commented Oct 4, 2026

Copy link
Copy Markdown
Owner

Thanks for this!

@rrthomas
rrthomas merged commit 2a77bfe into rrthomas:master Oct 4, 2026
@DaVinci42 DaVinci42 mentioned this pull request Oct 5, 2026
4 tasks done
@dwt

dwt commented Oct 7, 2026

Copy link
Copy Markdown

As this is triggering a build failure for fortune in nixpkgs - can you guys perhaps give us a hint when this will be released?

@pnavais

pnavais commented Oct 7, 2026

Copy link
Copy Markdown
Author

Hi @dwt !

Agreed this needs a release for packagers. The fix is already on master (#81, slightly simplified by @rrthomas on merge); #82 also landed so macOS CI (arm64 + Intel) is green again. A new release is up to @rrthomas (likely 3.7.17). Once that tag/tarball is out, nixpkgs can bump recode from 3.7.16.

Until then, from my side, I'm currently applying a small overlay to have fortune-mod + recode build on nix-darwin (It's basically the same change included in this PR)

Sharing here in case you find it useful :

overlays/recode.nix

# macOS libiconv lists some aliases (e.g. WINDOWS-874) under more than one
# charset group. recode 3.7.16 treats that as a fatal init error and fails
# its check phase on aarch64-darwin. Keep the first binding instead.
final: prev: {
  recode = prev.recode.overrideAttrs (old: {
    patches = (old.patches or []) ++ [
      ./recode-darwin-iconv-aliases.patch
    ];
  });
}

overlays/recode-darwin-iconv-aliases.patch

diff --git a/src/iconv.c b/src/iconv.c
index a44fd8c..c96fed0 100644
--- a/src/iconv.c
+++ b/src/iconv.c
@@ -272,11 +272,18 @@ module_iconv (RECODE_OUTER outer)
 	  RECODE_ALIAS alias
 	    = recode_find_alias (outer, *cursor, ALIAS_FIND_AS_CHARSET);
 
-	  /* If there is a charset contradiction, call recode_declare_alias
-	     nevertheless, as the error processing will occur there.  */
-	  if (!alias || alias->symbol->name != charset_name)
-	    if (!recode_declare_alias (outer, *cursor, charset_name))
-	      return false;
+	  if (!alias)
+	    {
+	      if (!recode_declare_alias (outer, *cursor, charset_name))
+		return false;
+	    }
+	  else if (alias->symbol->name != charset_name)
+	    {
+	      /* Some iconv implementations (notably macOS libiconv) list the
+		 same alias under more than one charset group — e.g.
+		 WINDOWS-874 appears with both CP1162 and CP874.  Keep the
+		 first binding instead of aborting initialization.  */
+	    }
 	}
     }
 
diff --git a/tables.py b/tables.py
index 1d7bc9a..aecaade 100755
--- a/tables.py
+++ b/tables.py
@@ -468,6 +468,7 @@ class Iconv(Options):
         libc = None
         import os
         names = []
+        seen = set()
         for line in os.popen('iconv -l'):
             if libc is None:
                 libc = len(line.split('/')) == 3
@@ -484,7 +485,19 @@ class Iconv(Options):
                     if alias in canonical:
                         alias = canonical[alias]
                     aliases.append(alias)
-                self.data.append((aliases[0], aliases[1:]))
+                # Prefer the first charset group for each alias name.  Some
+                # iconv implementations (macOS libiconv) repeat names across
+                # groups — e.g. WINDOWS-874 under both CP1162 and CP874 —
+                # which would otherwise make module_iconv abort.
+                filtered = []
+                for alias in aliases:
+                    key = alias.upper()
+                    if key in seen:
+                        continue
+                    seen.add(key)
+                    filtered.append(alias)
+                if filtered:
+                    self.data.append((filtered[0], filtered[1:]))
 
     def complete(self, french):
         def write_charset(format, charset):

@rrthomas

rrthomas commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Releasing 3.7.17 now.

@pnavais

pnavais commented Oct 7, 2026

Copy link
Copy Markdown
Author

Thanks a lot Reuben !

@pnavais

pnavais commented Oct 7, 2026

Copy link
Copy Markdown
Author

Bot already created the PR on nixpkgs : NixOS/nixpkgs#571390

Let's see if this gets merged soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants