• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37997

29 Jan 2025 02:08AM UTC coverage: 17.283% (-68.7%) from 85.981%
#37997

push

local

web-flow
bpart: Start enforcing min_world for global variable definitions (#57150)

This is the analog of #57102 for global variables. Unlike for consants,
there is no automatic global backdate mechanism. The reasoning for this
is that global variables can be declared at any time, unlike constants
which can only be decalared once their value is available. As a result
code patterns using `Core.eval` to declare globals are rarer and likely
incorrect.

1 of 22 new or added lines in 3 files covered. (4.55%)

31430 existing lines in 188 files now uncovered.

7903 of 45728 relevant lines covered (17.28%)

98663.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

2.42
/stdlib/Sockets/src/IPAddr.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
"""
4
    IPAddr
5

6
Abstract supertype for IP addresses. [`IPv4`](@ref) and [`IPv6`](@ref) are subtypes of this.
7
"""
8
abstract type IPAddr end
9

UNCOV
10
Base.isless(a::T, b::T) where {T<:IPAddr} = isless(a.host, b.host)
×
UNCOV
11
(dt::Type{<:Integer})(ip::IPAddr) = dt(ip.host)::dt
×
12

13
# Allow IP addresses to broadcast as unwrapped scalars
UNCOV
14
Base.Broadcast.broadcastable(ip::IPAddr) = Ref(ip)
×
15

16
struct IPv4 <: IPAddr
17
    host::UInt32
UNCOV
18
    IPv4(host::UInt32) = new(host)
×
UNCOV
19
    IPv4(a::UInt8,b::UInt8,c::UInt8,d::UInt8) = new(UInt32(a)<<24|
×
20
                                                    UInt32(b)<<16|
21
                                                    UInt32(c)<<8|
22
                                                    d)
UNCOV
23
    function IPv4(a::Integer,b::Integer,c::Integer,d::Integer)
×
UNCOV
24
        if !(0<=a<=255 && 0<=b<=255 && 0<=c<=255 && 0<=d<=255)
×
UNCOV
25
            throw(ArgumentError("IPv4 field out of range (must be 0-255)"))
×
26
        end
UNCOV
27
        IPv4(UInt8(a),UInt8(b),UInt8(c),UInt8(d))
×
28
    end
29
end
30

31
"""
32
    IPv4(host::Integer) -> IPv4
33

34
Return an IPv4 object from IP address `host` formatted as an [`Integer`](@ref).
35

36
# Examples
37
```jldoctest
38
julia> IPv4(3223256218)
39
ip"192.30.252.154"
40
```
41
"""
UNCOV
42
function IPv4(host::Integer)
×
UNCOV
43
    if host < 0
×
UNCOV
44
        throw(ArgumentError("IPv4 address must be positive"))
×
UNCOV
45
    elseif typemax(typeof(host)) > typemax(UInt32) && host > typemax(UInt32)
×
UNCOV
46
        throw(ArgumentError("IPv4 address must fit within 32 bits"))
×
47
    else
UNCOV
48
        return IPv4(UInt32(host))
×
49
    end
50
end
51

52
"""
53
    IPv4(str::AbstractString) -> IPv4
54

55
Parse an IPv4 address string into an `IPv4` object.
56

57
# Examples
58
```jldoctest
59
julia> IPv4("127.0.0.1")
60
ip"127.0.0.1"
61
```
62
"""
63
IPv4(str::AbstractString) = parse(IPv4, str)
5✔
64

UNCOV
65
show(io::IO,ip::IPv4) = print(io,"ip\"",ip,"\"")
×
UNCOV
66
print(io::IO,ip::IPv4) = print(io,string((ip.host&(0xFF000000))>>24),".",
×
67
                                  string((ip.host&(0xFF0000))>>16),".",
68
                                  string((ip.host&(0xFF00))>>8),".",
69
                                  string(ip.host&0xFF))
70

71
struct IPv6 <: IPAddr
72
    host::UInt128
UNCOV
73
    IPv6(host::UInt128) = new(host)
×
74
    IPv6(a::UInt16,b::UInt16,c::UInt16,d::UInt16,
×
75
     e::UInt16,f::UInt16,g::UInt16,h::UInt16) = new(UInt128(a)<<(7*16)|
76
                            UInt128(b)<<(6*16)|
77
                            UInt128(c)<<(5*16)|
78
                            UInt128(d)<<(4*16)|
79
                            UInt128(e)<<(3*16)|
80
                            UInt128(f)<<(2*16)|
81
                            UInt128(g)<<(1*16)|
82
                            h)
UNCOV
83
    function IPv6(a::Integer,b::Integer,c::Integer,d::Integer,
×
84
          e::Integer,f::Integer,g::Integer,h::Integer)
UNCOV
85
        if !(0<=a<=0xFFFF && 0<=b<=0xFFFF && 0<=c<=0xFFFF && 0<=d<=0xFFFF &&
×
86
             0<=e<=0xFFFF && 0<=f<=0xFFFF && 0<=g<=0xFFFF && 0<=h<=0xFFFF)
UNCOV
87
            throw(ArgumentError("IPv6 field out of range (must be 0-65535)"))
×
88
        end
UNCOV
89
        IPv6(UInt16(a),UInt16(b),UInt16(c),UInt16(d),
×
90
             UInt16(e),UInt16(f),UInt16(g),UInt16(h))
91
    end
92
end
93

94
"""
95
    IPv6(host::Integer) -> IPv6
96

97
Return an IPv6 object from IP address `host` formatted as an [`Integer`](@ref).
98

99
# Examples
100
```jldoctest
101
julia> IPv6(3223256218)
102
ip"::c01e:fc9a"
103
```
104
"""
UNCOV
105
function IPv6(host::Integer)
×
UNCOV
106
    if host < 0
×
UNCOV
107
        throw(ArgumentError("IPv6 address must be positive"))
×
108
        # We allow passing bigger integer types, but need to be careful to avoid overflow
109
        # Let's hope promotion rules are sensible
UNCOV
110
    elseif typemax(typeof(host)) > typemax(UInt128) && host > typemax(UInt128)
×
111
        throw(ArgumentError("IPv6 address must fit within 128 bits"))
×
112
    else
UNCOV
113
        return IPv6(UInt128(host))
×
114
    end
115
end
116

117
"""
118
    IPv6(str::AbstractString) -> IPv6
119

120
Parse an IPv6 address string into an `IPv6` object.
121

122
# Examples
123
```jldoctest
124
julia> IPv6("::1")
125
ip"::1"
126
```
127
"""
UNCOV
128
IPv6(str::AbstractString) = parse(IPv6, str)
×
129

130
# Suppress leading '0's and "0x"
UNCOV
131
print_ipv6_field(io,field::UInt16) = print(io,string(field, base = 16))
×
132

133
print_ipv6_field(io,ip,i) = print_ipv6_field(io,ipv6_field(ip,i))
×
UNCOV
134
function ipv6_field(ip::IPv6,i)
×
UNCOV
135
    if i < 0 || i > 7
×
UNCOV
136
        throw(BoundsError())
×
137
    end
UNCOV
138
    UInt16((ip.host&(UInt128(0xFFFF)<<(i*16))) >> (i*16))
×
139
end
140

UNCOV
141
show(io::IO, ip::IPv6) = print(io,"ip\"",ip,"\"")
×
142
# RFC 5952 compliant show function
143
# https://tools.ietf.org/html/rfc5952
UNCOV
144
function print(io::IO,ip::IPv6)
×
UNCOV
145
    i = 8
×
UNCOV
146
    m = 0
×
UNCOV
147
    longest_sub_i = -1
×
UNCOV
148
    while i!=0
×
UNCOV
149
        i-=1
×
UNCOV
150
        field = ipv6_field(ip,i)
×
UNCOV
151
        if field == 0 && longest_sub_i == -1
×
152
            # Find longest subsequence of 0
UNCOV
153
            longest_sub_i,j,m,c = i,i,1,1
×
UNCOV
154
            while j != 0
×
UNCOV
155
                j-=1
×
UNCOV
156
                if ipv6_field(ip,j) == 0
×
UNCOV
157
                    c += 1
×
158
                else
UNCOV
159
                    c = 0
×
160
                end
UNCOV
161
                if c > m
×
UNCOV
162
                    if j+c != longest_sub_i+1
×
UNCOV
163
                        longest_sub_i = j+c-1
×
164
                    end
UNCOV
165
                    m = c
×
166
                end
UNCOV
167
            end
×
168
            # Prevent single 0 from contracting to :: as required
UNCOV
169
            if m == 1
×
UNCOV
170
                longest_sub_i = 9
×
171
            end
172
        end
UNCOV
173
        if i == longest_sub_i
×
UNCOV
174
            print(io,":")
×
UNCOV
175
            i -= m-1
×
UNCOV
176
            if i == 0
×
177
                print(io,":")
×
178
                break
×
179
            end
180
        else
UNCOV
181
            if i != 7
×
UNCOV
182
                print(io,":")
×
183
            end
UNCOV
184
            print_ipv6_field(io,field)
×
185
        end
UNCOV
186
    end
×
187
end
188

189
# Parsing
190

191
const ipv4_leading_zero_error = """
192
Leading zeros in IPv4 addresses are disallowed due to ambiguity.
193
If the address is in octal or hexadecimal, convert it to decimal, otherwise remove the leading zero.
194
"""
195

UNCOV
196
function parse(::Type{IPv4}, str::AbstractString)
×
UNCOV
197
    fields = split(str,'.')
×
198
    i = 1
×
199
    ret = 0
×
UNCOV
200
    for f in fields
×
UNCOV
201
        if isempty(f)
×
UNCOV
202
            throw(ArgumentError("empty field in IPv4 address"))
×
203
        end
UNCOV
204
        if length(f) > 1 && f[1] == '0'
×
UNCOV
205
            throw(ArgumentError(ipv4_leading_zero_error))
×
206
        else
UNCOV
207
            r = parse(Int, f, base = 10)
×
208
        end
UNCOV
209
        if i != length(fields)
×
UNCOV
210
            if r < 0 || r > 255
×
UNCOV
211
                throw(ArgumentError("IPv4 field out of range (must be 0-255)"))
×
212
            end
UNCOV
213
            ret |= UInt32(r) << ((4-i)*8)
×
214
        else
UNCOV
215
            if r > ((UInt64(1)<<((5-length(fields))*8))-1)
×
216
                throw(ArgumentError("IPv4 field too large"))
×
217
            end
UNCOV
218
            ret |= r
×
219
        end
UNCOV
220
        i+=1
×
UNCOV
221
    end
×
UNCOV
222
    IPv4(ret)
×
223
end
224

225
function parseipv6fields(fields,num_fields)
UNCOV
226
    if length(fields) > num_fields
×
227
        throw(ArgumentError("too many fields in IPv6 address"))
×
228
    end
229
    cf = 7
×
230
    ret = UInt128(0)
×
UNCOV
231
    for f in fields
×
UNCOV
232
        if isempty(f)
×
233
            # ::abc:... and ..:abc::
UNCOV
234
            if cf != 7 && cf != 0
×
UNCOV
235
                cf -= num_fields-length(fields)
×
236
            end
UNCOV
237
            cf -= 1
×
UNCOV
238
            continue
×
239
        end
UNCOV
240
        ret |= UInt128(parse(Int, f, base = 16))<<(cf*16)
×
UNCOV
241
        cf -= 1
×
UNCOV
242
    end
×
UNCOV
243
    ret
×
244
end
UNCOV
245
parseipv6fields(fields) = parseipv6fields(fields,8)
×
246

UNCOV
247
function parse(::Type{IPv6}, str::AbstractString)
×
UNCOV
248
    fields = split(str,':')
×
UNCOV
249
    if length(fields) > 8
×
UNCOV
250
        throw(ArgumentError("too many fields in IPv6 address"))
×
UNCOV
251
    elseif length(fields) == 8
×
UNCOV
252
        return IPv6(parseipv6fields(fields))
×
UNCOV
253
    elseif in('.',fields[end])
×
UNCOV
254
        return IPv6((parseipv6fields(fields[1:(end-1)],6))
×
255
            | parse(IPv4, fields[end]).host )
256
    else
UNCOV
257
        return IPv6(parseipv6fields(fields))
×
258
    end
259
end
260

261
#
262
# This supports IP addresses in the common dot (IPv4) or colon (IPv6)
263
# separated formats. Most other common formats use a standard integer encoding
264
# of the appropriate size and should use the appropriate constructor
265
#
266

267
function parse(::Type{IPAddr}, str::AbstractString)
268
    if ':' in str
8✔
UNCOV
269
        return parse(IPv6, str)
×
270
    else
271
        return parse(IPv4, str)
8✔
272
    end
273
end
274

275
"""
276
    @ip_str str -> IPAddr
277

278
Parse `str` as an IP address.
279

280
# Examples
281
```jldoctest
282
julia> ip"127.0.0.1"
283
ip"127.0.0.1"
284

285
julia> @ip_str "2001:db8:0:0:0:0:2:1"
286
ip"2001:db8::2:1"
287
```
288
"""
289
macro ip_str(str)
290
    return parse(IPAddr, str)
291
end
292

293
struct InetAddr{T<:IPAddr}
UNCOV
294
    host::T
×
295
    port::UInt16
296
end
297

298
"""
299
    InetAddr(ip::IPAddr, port) -> InetAddr
300

301
Return an `InetAddr` object from ip address `ip` and port number `port`.
302

303
# Examples
304
```jldoctest
305
julia> Sockets.InetAddr(ip"127.0.0.1", 8000)
306
Sockets.InetAddr{IPv4}(ip"127.0.0.1", 8000)
307
```
308
"""
UNCOV
309
InetAddr(ip::IPAddr, port) = InetAddr{typeof(ip)}(ip, port)
×
310

311
"""
312
    InetAddr(str::AbstractString, port) -> InetAddr
313

314
Return an `InetAddr` object from ip address `str` formatted as [`AbstractString`](@ref)
315
and port number `port`.
316

317
!!! compat "Julia 1.3"
318
    This constructor requires at least Julia 1.3.
319

320
# Examples
321
```jldoctest
322
julia> Sockets.InetAddr("127.0.0.1", 8000)
323
Sockets.InetAddr{IPv4}(ip"127.0.0.1", 8000)
324
```
325
"""
UNCOV
326
InetAddr(str::AbstractString, port) = InetAddr(parse(IPAddr, str), port)
×
327

UNCOV
328
function show(io::IO, addr::InetAddr)
×
UNCOV
329
    show(io, typeof(addr))
×
UNCOV
330
    print(io, "(")
×
UNCOV
331
    show(io, addr.host)
×
UNCOV
332
    print(io, ", ", Int(addr.port), ")")
×
333
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc