diff --git a/Makefile b/Makefile index 3c88466932..a289be5595 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/config.mak.uname b/config.mak.uname index 38b35af366..3c35ae33a3 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -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 diff --git a/utf8.c b/utf8.c index 35a0251939..96460cc414 100644 --- a/utf8.c +++ b/utf8.c @@ -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';