Skip to content

Commit 32504b5

Browse files
committed
Only accept iconv implementations with the GNU behavior
1 parent 3f4c97e commit 32504b5

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

deps/build.jl

+30-2
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)