diff --git a/spec/std/socket/address_spec.cr b/spec/std/socket/address_spec.cr index 13869ad336af..66618128f4e1 100644 --- a/spec/std/socket/address_spec.cr +++ b/spec/std/socket/address_spec.cr @@ -305,6 +305,8 @@ describe Socket::IPAddress do it { Socket::IPAddress.parse_v6_fields?("c0a8").should be_nil } it { Socket::IPAddress.parse_v6_fields?("fe80::a:b%eth0").should eq UInt16.static_array(0xfe80, 0, 0, 0, 0, 0, 0xa, 0xb) } it { Socket::IPAddress.parse_v6_fields?("fe80:0:0:0:ffff:c0a8:5e4%lo").should eq UInt16.static_array(0xfe80, 0, 0, 0, 0xffff, 0xc0a8, 0x5e4, 0) } + + it { Socket::IPAddress.parse_v6_fields?("fe80::192.168.0.1%eth0").should eq UInt16.static_array(0xfe80, 0, 0, 0, 0, 0, 0xc0a8, 0x0001) } end describe ".v4" do diff --git a/src/socket/address.cr b/src/socket/address.cr index ab4e5a00d7d4..66f3c5381b3c 100644 --- a/src/socket/address.cr +++ b/src/socket/address.cr @@ -352,7 +352,12 @@ class Socket end if need_v4 - x0, x1, x2, x3 = parse_v4_fields?(Slice.new(ptr, finish - ptr)) || return nil + slice = Slice.new(ptr, finish - ptr) + if suffix = slice.index('%'.ord.to_u8!) + zone_slice = slice[suffix..] + 1 + slice = slice[0, suffix] + end + x0, x1, x2, x3 = parse_v4_fields?(slice) || return nil fields[6] = x0.to_u16! << 8 | x1 fields[7] = x2.to_u16! << 8 | x3 end