Skip to content

Commit 888e511

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

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

deps/build.jl

+26-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,34 @@ 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. glibc, GNU libiconv and win_iconv behave that way.
10+
function validate_iconv(n, h)
11+
Libdl.dlsym_e(h, "iconv_open") == C_NULL && return false
12+
13+
cd = ccall((:iconv_open, h), Ptr{Void}, (Cstring, Cstring), "ASCII", "UTF-8")
14+
cd == Ptr{Void}(-1) && return false
15+
16+
s = "café"
17+
a = similar(s.data)
18+
inbufptr = Ref{Ptr{UInt8}}(pointer(s.data))
19+
inbytesleft = Ref{Csize_t}(length(s.data))
20+
outbufptr = Ref{Ptr{UInt8}}(pointer(a))
21+
outbytesleft = Ref{Csize_t}(length(a))
22+
ret = ccall((:iconv, h), Csize_t,
23+
(Ptr{Void}, Ptr{Ptr{UInt8}}, Ref{Csize_t}, Ptr{Ptr{UInt8}}, Ref{Csize_t}),
24+
cd, inbufptr, inbytesleft, outbufptr, outbytesleft)
25+
ccall((:iconv_close, h), Void, (Ptr{Void},), cd) == -1 && return false
26+
27+
return ret == -1 % Csize_t && Base.Libc.errno() == Base.Libc.EILSEQ
28+
end
29+
530
libiconv = library_dependency("libiconv", aliases = ["libc", "iconv"],
631
# Check whether libc provides iconv_open (as on Linux)
7-
validate = (n, h) -> Libdl.dlsym_e(h, "iconv_open") != C_NULL)
32+
validate = validate_iconv)
833

934
@windows_only begin
1035
using WinRPM

0 commit comments

Comments
 (0)