build: win: change from win-iconv to GNU libiconv
What changed, and why it matters
This commit changes how Electrum builds its Windows installer. It swaps one helper library (win-iconv) for another (GNU libiconv) used by the QR-code scanner (zbar). The reason is that newer compilers now treat a type-mismatch warning as a fatal error, so the old library no longer compiles. The patch also fixes a similar pointer-size issue inside GNU libiconv itself. This is a build-system/maintenance change, not a fix for an active security vulnerability in Electrum's wallet code.
Treat as a routine build-maintenance commit. Verify the new libiconv source tarball hash, review the patch for correctness, and ensure Windows release builds still pass CI. No urgent security response is indicated.
Security signals we found
Build dependency swap triggered by compiler hardening (warning promoted to error)
Pointer-cast patch in libiconv to prevent integer-truncation warnings/errors on 64-bit builds
No runtime code change in Electrum wallet logic
No mention of CVE, vulnerability, or security bug in commit message
Evidence from the diff
The Windows build script (contrib/build-wine/make_win.sh) is updated to download and build GNU libiconv 1.18 instead of cloning and building win-iconv. A new patch (libiconv-fix-pointer-buf.patch) replaces (int)(long) casts with (int)(intptr_t) in libiconv’s alias table generation to avoid 64-bit pointer-to-int truncation warnings/errors. The Dockerfile gains cmake/pkgconf, and prepare-wine.sh now copies all built DLLs rather than listing them individually. The change is driven by GCC now promoting -Wincompatible-pointer-types from warning to error, which breaks win-iconv when compiling zbar.
Changed components
contrib/build-wine/Dockerfilecontrib/build-wine/make_win.shcontrib/build-wine/patches/libiconv-fix-pointer-buf.patchcontrib/build-wine/prepare-wine.shWindows release build pipelineBundled zbar QR scanner dependencyInspect captured patch +67 / −24
diff --git a/contrib/build-wine/Dockerfile b/contrib/build-wine/Dockerfile
index f45f1a9..de547a3 100644
--- a/contrib/build-wine/Dockerfile
+++ b/contrib/build-wine/Dockerfile
@@ -22,6 +22,8 @@ RUN dpkg --add-architecture i386 && \
git \
p7zip-full \
make \
+ cmake \
+ pkgconf \
mingw-w64 \
mingw-w64-tools \
autotools-dev \
diff --git a/contrib/build-wine/make_win.sh b/contrib/build-wine/make_win.sh
index 13ee21d..9ce2856 100755
--- a/contrib/build-wine/make_win.sh
+++ b/contrib/build-wine/make_win.sh
@@ -53,28 +53,34 @@ if [ -f "$DLL_TARGET_DIR/libzbar-0.dll" ]; then
info "libzbar already built, skipping"
else
(
- # As debian bullseye doesn't provide win-iconv-mingw-w64-dev, we need to build it:
- WIN_ICONV_COMMIT="9f98392dfecadffd62572e73e9aba878e03496c4"
- # ^ tag "v0.0.8"
- info "Building win-iconv..."
- cd "$CACHEDIR"
- if [ ! -d win-iconv ]; then
- git clone https://github.com/win-iconv/win-iconv.git
- fi
- cd win-iconv
- if ! $(git cat-file -e ${WIN_ICONV_COMMIT}) ; then
- info "Could not find requested version $WIN_ICONV_COMMIT in local clone; fetching..."
- git fetch --all
- fi
- git reset --hard
- git clean -dfxq
- git checkout "${WIN_ICONV_COMMIT}^{commit}"
-
- # note: "-j1" as parallel jobs lead to non-reproducibility seemingly due to ordering issues
- # see https://github.com/win-iconv/win-iconv/issues/42
- CC="${GCC_TRIPLET_HOST}-gcc" make -j1 || fail "Could not build win-iconv"
+ # iconv is needed for zbar. see https://github.com/mchehab/zbar/blob/a549566ea11eb03622bd4458a1728ffe3f589163/README-windows.md
+ # (previously were using win-iconv, but changed to GNU libiconv due to compilation errors with modern gcc)
+ LIBICONV_VER="1.18"
+ download_if_not_exist "$CACHEDIR/libiconv-${LIBICONV_VER}.tar.gz" "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-${LIBICONV_VER}.tar.gz"
+ verify_hash "$CACHEDIR/libiconv-${LIBICONV_VER}.tar.gz" "3b08f5f4f9b4eb82f151a7040bfd6fe6c6fb922efe4b1659c66ea933276965e8"
+ tar xf "$CACHEDIR/libiconv-${LIBICONV_VER}.tar.gz" -C "$CACHEDIR"
+ # ref https://github.com/msys2/MINGW-packages/blob/7f68e9f2488737bbe03888ade094eaee8021d1c5/mingw-w64-libiconv/PKGBUILD
+ info "Building libiconv..."
+ cd "$CACHEDIR/libiconv-${LIBICONV_VER}"
+ # Patches taken from msys2/MINGW-packages
+ patch -p1 < "$here/patches/libiconv-fix-pointer-buf.patch"
+ ./configure \
+ $AUTOCONF_FLAGS \
+ --prefix="/usr/${GCC_TRIPLET_HOST}" \
+ --disable-static \
+ --enable-shared \
+ --enable-extra-encodings \
+ --enable-relocatable \
+ --disable-rpath \
+ --enable-silent-rules \
+ --enable-nls
+ CC="${GCC_TRIPLET_HOST}-gcc" make "-j$CPU_COUNT" || fail "Could not build libiconv"
+ cp -fpv "libcharset/lib/.libs/libcharset-1.dll" "$DLL_TARGET_DIR/" || fail "Could not copy the libcharset binary to DLL_TARGET_DIR"
+ cp -fpv "lib/.libs/libiconv-2.dll" "$DLL_TARGET_DIR/" || fail "Could not copy the libiconv binary to DLL_TARGET_DIR"
# FIXME avoid using sudo
- sudo make install prefix="/usr/${GCC_TRIPLET_HOST}" || fail "Could not install win-iconv"
+ sudo make install || fail "Could not install libiconv"
+ # workaround to delete files owned by root, created by "make install":
+ make clean
)
"$CONTRIB"/make_zbar.sh || fail "Could not build zbar"
fi
diff --git a/contrib/build-wine/patches/libiconv-fix-pointer-buf.patch b/contrib/build-wine/patches/libiconv-fix-pointer-buf.patch
new file mode 100644
index 0000000..914b87b
--- /dev/null
+++ b/contrib/build-wine/patches/libiconv-fix-pointer-buf.patch
@@ -0,0 +1,37 @@
+--- a/lib/iconv.c 2018-05-03 23:18:55.997221700 -0400
++++ b/lib/iconv.c 2018-05-03 23:26:47.611682700 -0400
+@@ -170,12 +170,12 @@ static const struct stringpool2_t string
+ #include "aliases2.h"
+ #undef S
+ };
+ #define stringpool2 ((const char *) &stringpool2_contents)
+ static const struct alias sysdep_aliases[] = {
+-#define S(tag,name,encoding_index) { (int)(long)&((struct stringpool2_t *)0)->stringpool_##tag, encoding_index },
++#define S(tag,name,encoding_index) { (int)(intptr_t)&((struct stringpool2_t *)0)->stringpool_##tag, encoding_index },
+ #include "aliases2.h"
+ #undef S
+ };
+ #ifdef __GNUC__
+ __inline
+ #else
+--- a/lib/genaliases.c 2023-01-14 00:00:00.000000000 +0000
++++ b/lib/genaliases.c 2023-01-14 10:18:00.000000000 +0000
+@@ -50,7 +50,7 @@
+ putc(c, out2);
+ }
+ }
+- fprintf(out2,"\")' tmp.h | sed -e 's|^.*\\(stringpool_str[0-9]*\\).*$| (int)(long)\\&((struct stringpool_t *)0)->\\1,|'\n");
++ fprintf(out2,"\")' tmp.h | sed -e 's|^.*\\(stringpool_str[0-9]*\\).*$| (int)(intptr_t)\\&((struct stringpool_t *)0)->\\1,|'\n");
+ for (; n > 0; names++, n--)
+ emit_alias(out1, *names, c_name);
+ }
+--- a/lib/genaliases2.c 2023-01-14 00:00:00.000000000 +0000
++++ b/lib/genaliases2.c 2023-01-14 10:18:00.000000000 +0000
+@@ -44,6 +44,6 @@
+ static void emit_encoding (FILE* out1, FILE* out2, const char* tag, const char* const* names, size_t n, const char* c_name)
+ {
+- fprintf(out2," (int)(long)&((struct stringpool2_t *)0)->stringpool_%s_%u,\n",tag,counter);
++ fprintf(out2," (int)(intptr_t)&((struct stringpool2_t *)0)->stringpool_%s_%u,\n",tag,counter);
+ for (; n > 0; names++, n--)
+ emit_alias(out1, tag, *names, c_name);
+ }
diff --git a/contrib/build-wine/prepare-wine.sh b/contrib/build-wine/prepare-wine.sh
index f9553f7..5d5328e 100755
--- a/contrib/build-wine/prepare-wine.sh
+++ b/contrib/build-wine/prepare-wine.sh
@@ -53,9 +53,7 @@ $WINE_PYTHON -m pip install --no-build-isolation --no-dependencies --no-binary :
# copy already built DLLs
-cp "$DLL_TARGET_DIR"/libsecp256k1-*.dll $WINEPREFIX/drive_c/electrum/electrum/ || fail "Could not copy libsecp to its destination"
-cp "$DLL_TARGET_DIR/libzbar-0.dll" $WINEPREFIX/drive_c/electrum/electrum/ || fail "Could not copy libzbar to its destination"
-cp "$DLL_TARGET_DIR/libusb-1.0.dll" $WINEPREFIX/drive_c/electrum/electrum/ || fail "Could not copy libusb to its destination"
+cp "$DLL_TARGET_DIR"/*.dll "$WINEPREFIX/drive_c/electrum/electrum/" || fail "Could not copy DLLs to destination"
info "Building PyInstaller."
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.