summaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorFrank Smit <frank@61924.nl>2020-08-30 13:39:54 +0000
committerFrank Smit <frank@61924.nl>2020-08-30 13:39:54 +0000
commite0efab37a8bbd245e60c9adffaba4182aeb17c87 (patch)
tree3356fae8cb5d642afd3517f79ee3d61243179451 /lib/std
parent026a628d0ebce3d347322d629031d0fdc93308bf (diff)
downloadmc-e0efab37a8bbd245e60c9adffaba4182aeb17c87.tar.gz
Fix IPv6 parsing.
2001:b88:1202::10 resulted in [32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] while it should be [32, 1, 11, 136, 18, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16]
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/ipparse.myr36
-rw-r--r--lib/std/test/ipparse.myr6
2 files changed, 28 insertions, 14 deletions
diff --git a/lib/std/ipparse.myr b/lib/std/ipparse.myr
index 1147888..f8bba34 100644
--- a/lib/std/ipparse.myr
+++ b/lib/std/ipparse.myr
@@ -52,21 +52,24 @@ const ip4parse = {ip
;;
}
+const ipv6seg = 8
+
const ip6parse = {ip
var val : byte[16]
- var expand, split
+ var expand
var v, ok
- var i, nseg
+ var nseg, segsplit
ok = true
expand = false
- split = 0
+ segsplit = 0
+
if ip.len > 2 && eq(ip[:2], "::")
expand = true
- split = 0
;;
+
nseg = 0
- for i = 0; ip.len > 0 && ok; i++
+ for var i = 0; ip.len > 0 && ok; i++
/* parse 'num' segment */
(v, ip, ok) = num(ip, 0, 65536, 16, ':', ok)
@@ -75,7 +78,7 @@ const ip6parse = {ip
val[i*2 + 1] = (v & 0xff : byte)
nseg++
- if ip.len == 0 || nseg == 8
+ if ip.len == 0 || nseg == ipv6seg
break
;;
@@ -84,14 +87,14 @@ const ip6parse = {ip
if ip.len > 0 && ip[0] == (':' : byte) && !expand
(ip, ok) = delim(ip, ':', ok)
expand = true
- split = i
+ segsplit = nseg
;;
;;
if ok && ip.len == 0
if expand
- expandsplit(val[:], split, i)
- elif nseg != 8
+ expandsplit(val[:], nseg, segsplit)
+ elif nseg != ipv6seg
-> `None
;;
-> `Some `Ipv6 val
@@ -101,12 +104,17 @@ const ip6parse = {ip
}
/* take "a:b::c:d" and expand it to "a:b:0:0:...:0:c:d" */
-const expandsplit = {ip, split, len
- var width
+const expandsplit = {ip, nseg, segsplit
+ var head, tail
+ var split, middle
+
+ split = segsplit * 2
+ middle = (ipv6seg - nseg) * 2
+ head = ip[:split]
+ tail = ip[split : ip.len - middle]
- width = 16 - len
- std.slcp(ip[split:len], ip[split+width:len+width])
- std.slfill(ip[len:len+width], 0)
+ std.slcp(ip[ip.len - tail.len:], tail)
+ std.slfill(ip[head.len : ip.len - tail.len], 0)
}
const delim = {ip, sep, ok
diff --git a/lib/std/test/ipparse.myr b/lib/std/test/ipparse.myr
index ae23709..ad408cb 100644
--- a/lib/std/test/ipparse.myr
+++ b/lib/std/test/ipparse.myr
@@ -52,6 +52,12 @@ const main = {
0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00])
+ eq("2001:b88:1202::10", \
+ `std.Some `std.Ipv6 [ \
+ 0x20, 0x01, 0x0b, 0x88, \
+ 0x12, 0x02, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x10])
/* invalid ipv4 addresses */
eq("2a03:2880:2110:df07:face:b00c:0:1:abc", `std.None) /* too long */