[fpc-pascal] Bugs in StrToHostAddr6 in sockets unit

Noel Duffy noelduffy at xtra.co.nz
Sun May 3 00:02:12 CEST 2020


Using fpc 3.0.4 on Fedora 30.

I've just started using the StrToHostAddr6 function in the sockets unit 
to parse IPv6 addresses. I've found a couple of issues with it.

1. Even if address parsing fails, StrToHostAddr6 doesn't return an 
all-zero result in the in6_addr return value. The documentation states 
that it does, but my tests show it doesn't.

This can be trivially demonstrated with a program like so:

program ip6bug;

uses
   SysUtils, sockets;

procedure parse_print_ip6(addr: String);
var
   ip6: in6_addr;
   idx: Cardinal;
begin
   ip6 := StrToHostAddr6(addr);
   write('"' + addr+'" ' + '-> ');
   for idx := 0 to 15 do
     write(IntToHex(byte(ip6.s6_addr8[idx]),2)+'-');
   writeln();
end;

const
   addr = 'fxg%::906e:9d2f:a520:4172';
begin
   parse_print_ip6(addr);
end.

On my machine this produces:

"fxg%::906e:9d2f:a520:4172" -> 
00-00-00-60-68-74-E0-00-00-00-00-61-4F-2B-60-00-

The problem is that the StrToHostAddr6 function doesn't set its return 
value until the end of the function. If a parse error occurs 
mid-function, it zeroes the record in which it's writing the result but 
exits without setting the function return value. What gets returned 
depends on what's on the stack.

I could have sworn that fpc would detect a function exiting without 
setting a return value, but clearly 3.0.4 doesn't.

2. The second problem is that a colon-separated string containing 
hexadecimal values of any length will be parsed and treated as valid by 
StrToHostAddr6. E.g, it will parse a string like 
"fe80ca2f1::906e:9d2f:a520:4172". The sample program produces this 
output for this string:

"fe80ca2f1::906e:9d2f:a520:4172" -> 
A2-F1-00-00-00-00-00-00-90-6E-9D-2F-A5-20-41-72-

For the part before the first colon, it has discarded all but the last 
two bytes, A2 and F1. But it should not have accepted this string at 
all. There can be only four characters between the colons.

Neither of these are difficult to fix. But I am curious to know why the 
compiler lets a function return without setting a return value and 
doesn't at least issue a warning. I know it does in some cases, because 
I've often seen the message "Function result doesn't appear to be set". 
But maybe that's only if you never set the result, as opposed to setting 
it only for some paths through the code.


More information about the fpc-pascal mailing list