mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-02 10:30:49 +02:00
* Patch from Noel Duffy to add TrySTrToHost* functions
git-svn-id: trunk@45376 -
This commit is contained in:
parent
5a9fc1c01c
commit
f432bd9307
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -18286,6 +18286,7 @@ tests/webtbs/tw3695.pp svneol=native#text/plain
|
|||||||
tests/webtbs/tw3697.pp svneol=native#text/plain
|
tests/webtbs/tw3697.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw3700.pp svneol=native#text/plain
|
tests/webtbs/tw3700.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw37013.pp svneol=native#text/plain
|
tests/webtbs/tw37013.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw37060.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw37062.pp svneol=native#text/pascal
|
tests/webtbs/tw37062.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw3708.pp svneol=native#text/plain
|
tests/webtbs/tw3708.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw3719.pp svneol=native#text/plain
|
tests/webtbs/tw3719.pp svneol=native#text/plain
|
||||||
|
@ -12,7 +12,10 @@
|
|||||||
**********************************************************************}
|
**********************************************************************}
|
||||||
{$PACKRECORDS 2}
|
{$PACKRECORDS 2}
|
||||||
{.$DEFINE SOCKETS_DEBUG}
|
{.$DEFINE SOCKETS_DEBUG}
|
||||||
|
{$ModeSwitch out}
|
||||||
|
|
||||||
unit Sockets;
|
unit Sockets;
|
||||||
|
|
||||||
Interface
|
Interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
**********************************************************************}
|
**********************************************************************}
|
||||||
{$PACKRECORDS 2}
|
{$PACKRECORDS 2}
|
||||||
{.$DEFINE SOCKETS_DEBUG}
|
{.$DEFINE SOCKETS_DEBUG}
|
||||||
|
{$ModeSwitch out}
|
||||||
|
|
||||||
unit Sockets;
|
unit Sockets;
|
||||||
Interface
|
Interface
|
||||||
|
|
||||||
|
@ -302,6 +302,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function StrToHostAddr(IP : AnsiString) : in_addr ;
|
function StrToHostAddr(IP : AnsiString) : in_addr ;
|
||||||
|
var
|
||||||
|
ip4: in_addr;
|
||||||
|
begin
|
||||||
|
ip4.s_addr := 0;
|
||||||
|
StrToHostAddr.s_addr:=0; //:=NoAddress;
|
||||||
|
if TryStrToHostAddr(IP, ip4) then
|
||||||
|
StrToHostAddr := ip4;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TryStrToHostAddr(IP: AnsiString; out ip4: in_addr): Boolean;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
AllowedChars = ['.','0'..'9'];
|
AllowedChars = ['.','0'..'9'];
|
||||||
@ -312,7 +322,8 @@ Var
|
|||||||
Temp : in_addr;
|
Temp : in_addr;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
strtohostaddr.s_addr:=0; //:=NoAddress;
|
TryStrToHostAddr := False;
|
||||||
|
ip4.s_addr:=0; //:=NoAddress;
|
||||||
for I:=1 to Length(IP) do
|
for I:=1 to Length(IP) do
|
||||||
if Not (IP[I] in AllowedChars) then
|
if Not (IP[I] in AllowedChars) then
|
||||||
exit;
|
exit;
|
||||||
@ -339,7 +350,8 @@ begin
|
|||||||
If array4int(temp.s_addr)[i]<>k then
|
If array4int(temp.s_addr)[i]<>k then
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
strtohostaddr.s_addr:=ntohl(Temp.s_addr);
|
ip4.s_addr:=ntohl(Temp.s_addr);
|
||||||
|
TryStrToHostAddr := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function StrToNetAddr(IP : AnsiString) : in_addr;
|
function StrToNetAddr(IP : AnsiString) : in_addr;
|
||||||
@ -450,7 +462,24 @@ begin
|
|||||||
SetLength(HostAddrToStr6, Length(HostAddrToStr6)-1);
|
SetLength(HostAddrToStr6, Length(HostAddrToStr6)-1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function StrToHostAddr6(IP: String): in6_addr;
|
function StrToHostAddr6(IP: AnsiString): in6_addr;
|
||||||
|
var
|
||||||
|
i6: in6_addr;
|
||||||
|
begin
|
||||||
|
i6.u6_addr32[0] := 0;
|
||||||
|
i6.u6_addr32[1] := 0;
|
||||||
|
i6.u6_addr32[2] := 0;
|
||||||
|
i6.u6_addr32[3] := 0;
|
||||||
|
StrToHostAddr6.u6_addr32[0] := 0;
|
||||||
|
StrToHostAddr6.u6_addr32[1] := 0;
|
||||||
|
StrToHostAddr6.u6_addr32[2] := 0;
|
||||||
|
StrToHostAddr6.u6_addr32[3] := 0;
|
||||||
|
|
||||||
|
if TryStrToHostAddr6(IP, i6) then
|
||||||
|
StrToHostAddr6 := i6;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TryStrToHostAddr6(IP: AnsiString; out ip6: in6_addr): Boolean;
|
||||||
type
|
type
|
||||||
TCharClass = (cHexDigit, cColon, cDot, cUnknown, cEndStr);
|
TCharClass = (cHexDigit, cColon, cDot, cUnknown, cEndStr);
|
||||||
TParserMode = (pmIPv6, pmIPv4);
|
TParserMode = (pmIPv6, pmIPv4);
|
||||||
@ -553,10 +582,11 @@ var
|
|||||||
tmpByte: Byte = 0;
|
tmpByte: Byte = 0;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
StrToHostAddr6.s6_addr32[0] := 0;
|
TryStrToHostAddr6 := False;
|
||||||
StrToHostAddr6.s6_addr32[1] := 0;
|
ip6.s6_addr32[0] := 0;
|
||||||
StrToHostAddr6.s6_addr32[2] := 0;
|
ip6.s6_addr32[1] := 0;
|
||||||
StrToHostAddr6.s6_addr32[3] := 0;
|
ip6.s6_addr32[2] := 0;
|
||||||
|
ip6.s6_addr32[3] := 0;
|
||||||
|
|
||||||
if (Length(IP) > 45) or (Length(IP) < 2) then exit;
|
if (Length(IP) > 45) or (Length(IP) < 2) then exit;
|
||||||
|
|
||||||
@ -681,7 +711,7 @@ begin
|
|||||||
if coll_zero_seen then
|
if coll_zero_seen then
|
||||||
begin
|
begin
|
||||||
for tmpByte := 0 to coll_start_idx do
|
for tmpByte := 0 to coll_start_idx do
|
||||||
StrToHostAddr6.s6_addr16[tmpByte] := hextet_arr[tmpByte];
|
ip6.s6_addr16[tmpByte] := hextet_arr[tmpByte];
|
||||||
|
|
||||||
// hextet_idx-1 points to the final byte we processed, in the hextet_arr
|
// hextet_idx-1 points to the final byte we processed, in the hextet_arr
|
||||||
// array. starting there, reading back to coll_start_idx, we copy these
|
// array. starting there, reading back to coll_start_idx, we copy these
|
||||||
@ -693,7 +723,7 @@ begin
|
|||||||
idx := 7;
|
idx := 7;
|
||||||
while tmpByte > coll_start_idx do
|
while tmpByte > coll_start_idx do
|
||||||
begin
|
begin
|
||||||
StrToHostAddr6.s6_addr16[idx] := hextet_arr[tmpByte];
|
ip6.s6_addr16[idx] := hextet_arr[tmpByte];
|
||||||
Dec(tmpByte);
|
Dec(tmpByte);
|
||||||
Dec(idx);
|
Dec(idx);
|
||||||
end;
|
end;
|
||||||
@ -704,8 +734,9 @@ begin
|
|||||||
// NOTE: optimization note: memmove/memcpy equivalent could help here.
|
// NOTE: optimization note: memmove/memcpy equivalent could help here.
|
||||||
if hextet_idx < 8 then exit;
|
if hextet_idx < 8 then exit;
|
||||||
for tmpByte := 0 to 7 do
|
for tmpByte := 0 to 7 do
|
||||||
StrToHostAddr6.s6_addr16[tmpByte] := hextet_arr[tmpByte];
|
ip6.s6_addr16[tmpByte] := hextet_arr[tmpByte];
|
||||||
end;
|
end;
|
||||||
|
TryStrToHostAddr6 := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function NetAddrToStr6 (Entry : TIn6_Addr) : ansiString;
|
function NetAddrToStr6 (Entry : TIn6_Addr) : ansiString;
|
||||||
|
@ -193,6 +193,8 @@ function HostAddrToStr(Entry : in_addr) : AnsiString;
|
|||||||
function StrToHostAddr(IP : AnsiString) : in_addr ;
|
function StrToHostAddr(IP : AnsiString) : in_addr ;
|
||||||
function StrToNetAddr (IP : AnsiString) : in_addr;
|
function StrToNetAddr (IP : AnsiString) : in_addr;
|
||||||
|
|
||||||
|
function TryStrToHostAddr(IP : AnsiString; out ip4: in_addr) : Boolean ;
|
||||||
|
|
||||||
{ these for are for netdb legacy compat}
|
{ these for are for netdb legacy compat}
|
||||||
Function HostToNet (Host : in_addr) : in_addr; deprecated;
|
Function HostToNet (Host : in_addr) : in_addr; deprecated;
|
||||||
Function NetToHost (Net : in_addr) : in_addr; deprecated;
|
Function NetToHost (Net : in_addr) : in_addr; deprecated;
|
||||||
@ -203,9 +205,10 @@ Function ShortNetToHost(Net : Word) : Word; deprecated;
|
|||||||
|
|
||||||
// ipv6
|
// ipv6
|
||||||
function HostAddrToStr6(Entry : Tin6_addr) : AnsiString;
|
function HostAddrToStr6(Entry : Tin6_addr) : AnsiString;
|
||||||
function StrToHostAddr6(IP : String) : Tin6_addr; // not implemented?!?
|
function StrToHostAddr6(IP : AnsiString) : Tin6_addr; // not implemented?!?
|
||||||
function NetAddrToStr6 (Entry: Tin6_addr) : AnsiString;
|
function NetAddrToStr6 (Entry: Tin6_addr) : AnsiString;
|
||||||
function StrToNetAddr6 (IP : AnsiString) : TIn6_Addr;
|
function StrToNetAddr6 (IP : AnsiString) : TIn6_Addr;
|
||||||
|
function TryStrToHostAddr6(IP: AnsiString; out ip6: in6_addr): Boolean;
|
||||||
|
|
||||||
CONST
|
CONST
|
||||||
NoAddress : in_addr = (s_addr:0);
|
NoAddress : in_addr = (s_addr:0);
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
**********************************************************************}
|
**********************************************************************}
|
||||||
|
|
||||||
{$mode objfpc}
|
{$mode objfpc}
|
||||||
|
{$ModeSwitch out}
|
||||||
|
|
||||||
unit Sockets;
|
unit Sockets;
|
||||||
|
|
||||||
Interface
|
Interface
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
**********************************************************************}
|
**********************************************************************}
|
||||||
|
|
||||||
{$mode objfpc}
|
{$mode objfpc}
|
||||||
|
{$ModeSwitch out}
|
||||||
|
|
||||||
unit Sockets;
|
unit Sockets;
|
||||||
|
|
||||||
Interface
|
Interface
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
{$MODE ObjFPC}
|
{$MODE ObjFPC}
|
||||||
{ $DEFINE notUnix} // To make ssockets.pp compile
|
{ $DEFINE notUnix} // To make ssockets.pp compile
|
||||||
|
{$ModeSwitch out}
|
||||||
|
|
||||||
unit Sockets;
|
unit Sockets;
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
**********************************************************************}
|
**********************************************************************}
|
||||||
unit Sockets;
|
unit Sockets;
|
||||||
Interface
|
Interface
|
||||||
|
{$ModeSwitch out}
|
||||||
|
|
||||||
{$ifdef Unix}
|
{$ifdef Unix}
|
||||||
Uses baseunix,UnixType;
|
Uses baseunix,UnixType;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
**********************************************************************}
|
**********************************************************************}
|
||||||
{$mode objfpc}
|
{$mode objfpc}
|
||||||
|
{$ModeSwitch out}
|
||||||
unit Sockets;
|
unit Sockets;
|
||||||
|
|
||||||
Interface
|
Interface
|
||||||
|
362
tests/webtbs/tw37060.pp
Normal file
362
tests/webtbs/tw37060.pp
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
program fp37060;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
uses sockets, Classes, SysUtils;
|
||||||
|
|
||||||
|
procedure BuildBadAddrs4(out bad_addrs: TStringList);
|
||||||
|
begin
|
||||||
|
bad_addrs.Add('1.1.1.1.1'); // too many octets
|
||||||
|
bad_addrs.Add('0xa.3.4.5'); //hex in octets
|
||||||
|
bad_addrs.Add('9.$c.4.5'); //hex in octets
|
||||||
|
bad_addrs.Add('12.$2.1.1.1'); //hex in octets
|
||||||
|
bad_addrs.Add('000001.2.3.4'); // too many digits in octet
|
||||||
|
bad_addrs.Add('1.000002.3.4'); // ditto second octet
|
||||||
|
bad_addrs.Add('1.2.000003.4'); // ditto third octet
|
||||||
|
bad_addrs.Add('1.2.3.000004'); // ditto fourth octet
|
||||||
|
bad_addrs.Add('1.2.3.+4'); // math sign in octet
|
||||||
|
bad_addrs.Add('1.2.-3.4'); // math sign in octet
|
||||||
|
bad_addrs.Add('1.+2.3.4'); // math sign in octet
|
||||||
|
bad_addrs.Add('-1.2.3.4'); // math sign in octet
|
||||||
|
bad_addrs.Add('192.168.1'); // too few octets
|
||||||
|
bad_addrs.Add('192.168'); // fewer still
|
||||||
|
bad_addrs.Add('192'); // just one octet
|
||||||
|
bad_addrs.Add('172.16.231.25.'); // ends with dot
|
||||||
|
bad_addrs.Add('.172.16.231.25'); // starts with dot
|
||||||
|
bad_addrs.Add('10...'); // dots but no digits
|
||||||
|
bad_addrs.Add('310.259.1.1'); // overflow in octet 1
|
||||||
|
bad_addrs.Add('10.259.1.1'); // ditto octet 2
|
||||||
|
bad_addrs.Add('10.25.300.1'); // ditto octet 3
|
||||||
|
bad_addrs.Add('10.25.30.301'); //ditto octet 4
|
||||||
|
bad_addrs.Add('%1111.%11001110.30.4'); // binary
|
||||||
|
bad_addrs.Add('&7.&5.30.4'); // octal
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure BuildGoodAddrs4(out good_addrs: TStringList);
|
||||||
|
begin
|
||||||
|
good_addrs.Add('127.0.0.1|127.0.0.1');
|
||||||
|
good_addrs.Add('0.0.0.0|0.0.0.0');
|
||||||
|
good_addrs.Add('172.16.31.241|172.16.31.241');
|
||||||
|
good_addrs.Add('255.255.255.255|255.255.255.255');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure BuildBadAddrs6(out bad_addrs: TStringList);
|
||||||
|
begin
|
||||||
|
// start with some obviously bad formats.
|
||||||
|
bad_addrs.Add('');
|
||||||
|
bad_addrs.Add(':');
|
||||||
|
bad_addrs.Add(':::');
|
||||||
|
bad_addrs.Add('::.');
|
||||||
|
bad_addrs.Add('::::');
|
||||||
|
bad_addrs.Add('fe80:');
|
||||||
|
bad_addrs.Add('x:');
|
||||||
|
bad_addrs.Add('.');
|
||||||
|
bad_addrs.Add('....');
|
||||||
|
|
||||||
|
// invalid chars in all 8 hextets.
|
||||||
|
bad_addrs.Add('fe@0:b46c:c2a1:a202:9*6e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b4%c:c2a1:a202:9*6e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2#1:a202:926e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a2^2:926e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:9*6e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9!d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:a=20:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:a520:41+2');
|
||||||
|
|
||||||
|
// $ sign in hextets.
|
||||||
|
bad_addrs.Add('$fe80:b46c:c2a1:a202:926e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b$46c:c2a1:a202:926e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1$:a202:926e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926$e:9d2f:a520:4172');
|
||||||
|
|
||||||
|
// last char is :
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:a520:4172:');
|
||||||
|
|
||||||
|
// first char is :
|
||||||
|
bad_addrs.Add(':fe80:b46c:c2a1:a202:926e:9d2f:a520:4172');
|
||||||
|
|
||||||
|
// two sequences of collapsed zeroes. :: is the Highlander
|
||||||
|
// sequence. There can be only one.
|
||||||
|
bad_addrs.Add('fe80::c2a1:a202::9d2f:a520:4172');
|
||||||
|
|
||||||
|
// 8 hextets plus collapsed zeroes, which means at least 1 hextet
|
||||||
|
// of all zeroes, equaling 9 hextets.
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1::a202:926e:9d2f:a520:4172');
|
||||||
|
|
||||||
|
// try the same with the :: at the start.
|
||||||
|
bad_addrs.Add('::b46c:c2a1:8fcb:a202:926e:9d2f:a520:4172');
|
||||||
|
|
||||||
|
// and now try the same with the :: at the ned.
|
||||||
|
bad_addrs.Add('b46c:a771:8fcb:a202:926e:9d2f:a520:4172::');
|
||||||
|
|
||||||
|
// too many hextets
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:a520:4172:1211');
|
||||||
|
|
||||||
|
// too few hextets
|
||||||
|
bad_addrs.Add('fe80:b46c:9d2f:a520:4172:1211');
|
||||||
|
|
||||||
|
// too many digits in each of the 8 hextets
|
||||||
|
bad_addrs.Add('fe801:b46c:c2a1:a202:926e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46cb:c2a1:a202:926e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:0c2ad:a202:926e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a2022:926e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e6:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:09d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:a5209:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:a520:04172');
|
||||||
|
|
||||||
|
// math signs in hextets. naive parsing of hextets with
|
||||||
|
// math signs produces a positive result, but these are not
|
||||||
|
// valid.
|
||||||
|
bad_addrs.Add('fe80:-b46c:c2a1:a202:926e:9d2f:a520:4172');
|
||||||
|
bad_addrs.Add('fe80:b46c:-c2a1:a202:926e:9d2f:a520:4172');
|
||||||
|
|
||||||
|
// Hybrid 6 and 4 addresses.
|
||||||
|
|
||||||
|
// ipv4 octet can't contain hex
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:19F.168.1.2');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.1A8.1.2');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.168.B.2');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.168.1.C');
|
||||||
|
|
||||||
|
// ipv4 octets can't contain math signs
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:-192.168.1.1');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.-168.1.1');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.168.-1.1');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.168.1.-1');
|
||||||
|
|
||||||
|
// invalid hybrid ipv6/ipv4 address, because there are 7
|
||||||
|
// hextets before the ipv4. there can be only 6, as the 4
|
||||||
|
// octets make up 2 hextets, and there can be no more than 8
|
||||||
|
// hextets in total.
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:a520:192.168.1.2');
|
||||||
|
|
||||||
|
// 5 hextets plus 2 hextets (4 octets) = 7. Must be 8.
|
||||||
|
bad_addrs.Add('fe80:b46c:926e:9d2f:a520:192.168.1.2');
|
||||||
|
|
||||||
|
// too few octets in ipv4 bit.
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.168.1');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.168');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192');
|
||||||
|
|
||||||
|
// 7 hextets plus two octets of ipv4 = 8 hextets, but still must
|
||||||
|
// not be parsed as valid because there must be 4 octets.
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:e2fc:192.168');
|
||||||
|
|
||||||
|
// too many ipv4 octets
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.168.1.17.32');
|
||||||
|
|
||||||
|
// addr starts with .
|
||||||
|
bad_addrs.Add('.fe80:b46c:c2a1:a202:926e:9d2f:192.168.1.17');
|
||||||
|
// addr ends with .
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.168.1.17.');
|
||||||
|
|
||||||
|
// 6 hextets + 2 hextets (4 octets) plus collapsed zero sequence = 9 hextets.
|
||||||
|
bad_addrs.Add('fe80:b46c::c2a1:a202:926e:9d2f:72.16.32.1');
|
||||||
|
|
||||||
|
// repeat with :: at start
|
||||||
|
bad_addrs.Add('::fe80:b46c:c2a1:a202:926e:9d2f:72.16.32.1');
|
||||||
|
// and at end
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f::72.16.32.1');
|
||||||
|
|
||||||
|
// ipv4 octets > 255
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:351.16.32.1');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:72.123216.32.1');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:72.16.9999999999999999999.1');
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:72.16.32.5e21');
|
||||||
|
|
||||||
|
// dot sequence
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192..168.1.17');
|
||||||
|
|
||||||
|
// start with dot
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:.192.168.1.17');
|
||||||
|
|
||||||
|
// end with dot
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:9d2f:192.168.1.17.');
|
||||||
|
|
||||||
|
// ipv4 octets followed by hextet
|
||||||
|
bad_addrs.Add('fe80:b46c:c2a1:a202:926e:192.168.1.1:a2c1');
|
||||||
|
|
||||||
|
// all zeroes but for mathematical operator.
|
||||||
|
bad_addrs.Add('::-');
|
||||||
|
|
||||||
|
// end on colon, but with earlier collapsed section.
|
||||||
|
bad_addrs.Add('fe80::a202:926e:a2c1:');
|
||||||
|
|
||||||
|
// too many digits in ipv4 octet
|
||||||
|
bad_addrs.Add('21ac:d349:07c4:198e:6fab:df5a:0192.168.1.17');
|
||||||
|
bad_addrs.Add('21ac:d349:07c4:198e:6fab:df5a:192.0168.1.17');
|
||||||
|
bad_addrs.Add('21ac:d349:07c4:198e:6fab:df5a:192.168.0001.17');
|
||||||
|
bad_addrs.Add('21ac:d349:07c4:198e:6fab:df5a:192.0168.1.0017');
|
||||||
|
|
||||||
|
// just ipv4 address
|
||||||
|
bad_addrs.Add('127.0.0.2');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure BuildGoodAddrs6(out addrlist: TStringList);
|
||||||
|
begin
|
||||||
|
// Each str is two parts, separated by a pipe. The left part is the input
|
||||||
|
// address to be parsed, and the right is the expected result of taking the
|
||||||
|
// resulting address and converting back to a string. This provides an
|
||||||
|
// easy way to verify that the StrToHostAddr6 function parsed the address
|
||||||
|
// correctly.
|
||||||
|
// The values on the right have been double-checked with libc's inet_pton.
|
||||||
|
addrlist.Add('::1|::0001');
|
||||||
|
addrlist.Add('::|::');
|
||||||
|
addrlist.Add('2001:4860:4000::|2001:4860:4000::');
|
||||||
|
addrlist.Add('21ac:d349:07c4:198e:6fab:df5a:192.168.1.17|21AC:D349:07C4:198E:6FAB:DF5A:C0A8:0111');
|
||||||
|
addrlist.Add('21ac:d349:07c4:198e:6fab:df5a:0.0.0.0|21AC:D349:07C4:198E:6FAB:DF5A::');
|
||||||
|
addrlist.Add('::213.41.35.14|::D529:230E');
|
||||||
|
addrlist.Add('fe80:b46c:c2a1:a202:926e:9d2f:a520:4172|FE80:B46C:C2A1:A202:926E:9D2F:A520:4172');
|
||||||
|
addrlist.Add('a:b:c:d:e:f:0:1|000A:000B:000C:000D:000E:000F::0001');
|
||||||
|
addrlist.Add('a:B:c:D:e:f:9:1|000A:000B:000C:000D:000E:000F:0009:0001');
|
||||||
|
addrlist.Add('::0.0.0.0|::');
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TestAddrs4(al: TStringList): Cardinal;
|
||||||
|
var
|
||||||
|
bad_addr: String;
|
||||||
|
i4: in_addr;
|
||||||
|
res: Boolean;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
for bad_addr in al do
|
||||||
|
begin
|
||||||
|
res := TryStrToHostAddr(bad_addr, i4);
|
||||||
|
if res = True then
|
||||||
|
begin
|
||||||
|
writeln(' [x] '+bad_addr);
|
||||||
|
Inc(Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TestGoodAddrs4(al: TStringList): Cardinal;
|
||||||
|
var
|
||||||
|
addr,instr,parsed_addr,expected: String;
|
||||||
|
i4: in_addr;
|
||||||
|
idx: Cardinal;
|
||||||
|
res: Boolean;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
for addr in al do
|
||||||
|
begin
|
||||||
|
idx := Pos('|', addr);
|
||||||
|
if idx > 0 then
|
||||||
|
begin
|
||||||
|
instr := Copy(addr,1,idx-1);
|
||||||
|
res := TryStrToHostAddr(instr, i4);
|
||||||
|
if res = False then
|
||||||
|
begin
|
||||||
|
writeln(' [x] '+instr);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
expected := Copy(addr, idx+1, Length(addr)-idx);
|
||||||
|
parsed_addr := HostAddrToStr(i4);
|
||||||
|
if parsed_addr <> expected then
|
||||||
|
writeln(' [X] "'+instr+' -> '+parsed_addr)
|
||||||
|
else
|
||||||
|
Inc(Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TestAddrs6(al: TStringList): Cardinal;
|
||||||
|
var
|
||||||
|
bad_addr: String;
|
||||||
|
i6: in6_addr;
|
||||||
|
res: Boolean;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
for bad_addr in al do
|
||||||
|
begin
|
||||||
|
res := TryStrToHostAddr6(bad_addr, i6);
|
||||||
|
if res = True then
|
||||||
|
begin
|
||||||
|
writeln(' [x] '+bad_addr);
|
||||||
|
Inc(Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TestGoodAddrs6(al: TStringList): Cardinal;
|
||||||
|
var
|
||||||
|
addr,instr,parsed_addr,expected: String;
|
||||||
|
i6: in6_addr;
|
||||||
|
idx: Cardinal;
|
||||||
|
res: Boolean;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
for addr in al do
|
||||||
|
begin
|
||||||
|
idx := Pos('|', addr);
|
||||||
|
if idx > 0 then
|
||||||
|
begin
|
||||||
|
instr := Copy(addr,1,idx-1);
|
||||||
|
res := TryStrToHostAddr6(instr, i6);
|
||||||
|
if res = False then
|
||||||
|
begin
|
||||||
|
writeln(' [x] '+instr);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
expected := Copy(addr, idx+1, Length(addr)-idx);
|
||||||
|
parsed_addr := HostAddrToStr6(i6);
|
||||||
|
if parsed_addr <> expected then
|
||||||
|
writeln(' [X] "'+instr+' -> '+parsed_addr)
|
||||||
|
else
|
||||||
|
Inc(Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
addrlist: TStringList;
|
||||||
|
count: Cardinal;
|
||||||
|
begin
|
||||||
|
ExitCode := 0;
|
||||||
|
addrlist := TStringList.Create;
|
||||||
|
|
||||||
|
// IPv4 Tests
|
||||||
|
|
||||||
|
writeln('IPv4');
|
||||||
|
BuildBadAddrs4(addrlist);
|
||||||
|
count := TestAddrs4(addrlist);
|
||||||
|
writeln('Got True result for '+inttostr(count)+' out of '+
|
||||||
|
inttostr(addrlist.Count)+' ip4 bad addresses.');
|
||||||
|
// if we successfully parsed any bad addresses
|
||||||
|
if count > 0 then ExitCode := 1;
|
||||||
|
|
||||||
|
addrlist.Clear;
|
||||||
|
BuildGoodAddrs4(addrlist);
|
||||||
|
count := TestGoodAddrs4(addrlist);
|
||||||
|
writeln('Got True result for '+inttostr(count)+' out of '+
|
||||||
|
inttostr(addrlist.Count)+' good ip4 addresses.');
|
||||||
|
writeln();
|
||||||
|
|
||||||
|
// if we didn't parse all the good addresses.
|
||||||
|
if count < addrlist.Count then
|
||||||
|
ExitCode := 1;
|
||||||
|
|
||||||
|
// IPv6 Tests
|
||||||
|
|
||||||
|
writeln('IPv6');
|
||||||
|
BuildBadAddrs6(addrlist);
|
||||||
|
count := TestAddrs6(addrlist);
|
||||||
|
writeln('Got True result for '+inttostr(count)+' out of '+
|
||||||
|
inttostr(addrlist.Count)+' ip6 bad addresses.');
|
||||||
|
// if we successfully parsed any bad addresses
|
||||||
|
if count > 0 then ExitCode := 1;
|
||||||
|
|
||||||
|
addrlist.Clear;
|
||||||
|
BuildGoodAddrs6(addrlist);
|
||||||
|
count := TestGoodAddrs6(addrlist);
|
||||||
|
writeln('Got True result for '+inttostr(count)+' out of '+
|
||||||
|
inttostr(addrlist.Count)+' good ip6 addresses.');
|
||||||
|
|
||||||
|
// if we didn't parse all the good addresses.
|
||||||
|
if count < addrlist.Count then
|
||||||
|
ExitCode := 1;
|
||||||
|
|
||||||
|
addrlist.Free;
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user