Merge branch 'tb/macos-iconv-workarounds' into jch

The iconv library on macOS fails to correctly handle stateful
ISO/IEC 2022 encoded strings.  Work it around instead of replacing
it wholesale from homebrew.

RFC.
needs to be debased from older rs/macos-iconv-workaround topic.

* tb/macos-iconv-workarounds:
  utf8.c: Enable workaround for iconv under macOS 14/15
  utf8.c: Prepare workaround for iconv under macOS 14/15
This commit is contained in:
Junio C Hamano 2026-01-09 06:55:44 -08:00
commit bc3e4c6c7b
3 changed files with 21 additions and 0 deletions

View File

@ -1693,6 +1693,7 @@ ifeq ($(uname_S),Darwin)
ifeq ($(shell test -d /opt/local/lib && echo y),y)
BASIC_CFLAGS += -I/opt/local/include
BASIC_LDFLAGS += -L/opt/local/lib
HAS_GOOD_LIBICONV = Yes
endif
endif
ifndef NO_APPLE_COMMON_CRYPTO
@ -1715,6 +1716,7 @@ endif
ifdef USE_HOMEBREW_LIBICONV
ifeq ($(shell test -d $(HOMEBREW_PREFIX)/opt/libiconv && echo y),y)
ICONVDIR ?= $(HOMEBREW_PREFIX)/opt/libiconv
HAS_GOOD_LIBICONV = Yes
endif
endif
endif
@ -1860,6 +1862,11 @@ ifndef NO_ICONV
endif
EXTLIBS += $(ICONV_LINK) -liconv
endif
ifdef NEEDS_GOOD_LIBICONV
ifndef HAS_GOOD_LIBICONV
BASIC_CFLAGS += -DICONV_RESTART_RESET
endif
endif
endif
ifdef ICONV_OMITS_BOM
BASIC_CFLAGS += -DICONV_OMITS_BOM

View File

@ -157,6 +157,7 @@ ifeq ($(uname_S),Darwin)
endif
ifeq ($(shell test "$(DARWIN_MAJOR_VERSION)" -ge 24 && echo 1),1)
USE_HOMEBREW_LIBICONV = UnfortunatelyYes
NEEDS_GOOD_LIBICONV = UnfortunatelyYes
endif
# The builtin FSMonitor on MacOS builds upon Simple-IPC. Both require

13
utf8.c
View File

@ -515,6 +515,19 @@ char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv,
out = xrealloc(out, outalloc);
outpos = out + sofar;
outsz = outalloc - sofar - 1;
#ifdef ICONV_RESTART_RESET
/*
* If iconv(3) messes up piecemeal conversions
* then restore the original pointers, sizes,
* and converter state, then retry converting
* the full string using the reallocated buffer.
*/
insz += cp - (iconv_ibp)in; /* Restore insz */
cp = (iconv_ibp)in; /* original start value */
outpos = out + bom_len; /* original start value */
outsz = outalloc - bom_len - 1; /* new len */
iconv(conv, NULL, NULL, NULL, NULL); /* reset iconv machinery */
#endif
}
else {
*outpos = '\0';