Skip to content

Commit 01ac5d1

Browse files
committed
Only accept iconv implementations with the GNU behavior
This ensures the package behave more consistently across platforms, and makes it possible to implement character fallback for invalid sequences. This is what GLib does by requiring e.g. libiconv on BSDs.
1 parent 3f4c97e commit 01ac5d1

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

deps/build.jl

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,37 @@ using BinDeps
22

33
@BinDeps.setup
44

5+
# Check for an iconv implementation with the GNU (non-POSIX) behavior:
6+
# EILSEQ is returned when a sequence cannot be converted to target encoding,
7+
# instead of succeeding and only returning the number of invalid conversions
8+
# This non-standard behavior is required to allow replacing invalid sequences
9+
# with a user-defined character.
10+
# Implementations with this behavior include glibc, GNU libiconv (on which Mac
11+
# OS X's is based) and win_iconv.
12+
function validate_iconv(n, h)
13+
# Needed to check libc
14+
f = Libdl.dlsym_e(h, "iconv_open")
15+
f == C_NULL && return false
16+
17+
cd = ccall(f, Ptr{Void}, (Cstring, Cstring), "ASCII", "UTF-8")
18+
cd == Ptr{Void}(-1) && return false
19+
20+
s = "café"
21+
a = similar(s.data)
22+
inbufptr = Ref{Ptr{UInt8}}(pointer(s.data))
23+
inbytesleft = Ref{Csize_t}(length(s.data))
24+
outbufptr = Ref{Ptr{UInt8}}(pointer(a))
25+
outbytesleft = Ref{Csize_t}(length(a))
26+
ret = ccall(Libdl.dlsym_e(h, "iconv"), Csize_t,
27+
(Ptr{Void}, Ptr{Ptr{UInt8}}, Ref{Csize_t}, Ptr{Ptr{UInt8}}, Ref{Csize_t}),
28+
cd, inbufptr, inbytesleft, outbufptr, outbytesleft)
29+
ccall(Libdl.dlsym_e(h, "iconv_close"), Void, (Ptr{Void},), cd) == -1 && return false
30+
31+
return ret == -1 % Csize_t && Libc.errno() == Libc.EILSEQ
32+
end
33+
534
libiconv = library_dependency("libiconv", aliases = ["libc", "iconv"],
6-
# Check whether libc provides iconv_open (as on Linux)
7-
validate = (n, h) -> Libdl.dlsym_e(h, "iconv_open") != C_NULL)
35+
validate = validate_iconv)
836

937
@windows_only begin
1038
using WinRPM

0 commit comments

Comments
 (0)