* patch by Bart B to fix fpc_val_smallint_shortstr similiar to #39406, resolves #39528

This commit is contained in:
florian 2022-01-13 22:51:10 +01:00
parent d6a26f2c28
commit 9a90db79c3

View File

@ -1504,17 +1504,22 @@ end;
Function fpc_val_smallint_shortstr(Const S: ShortString; out Code: ValSInt): SmallInt; [public, alias:'FPC_VAL_SMALLINT_SHORTSTR']; compilerproc;
var u, temp, prev, maxprevvalue, maxnewvalue : word;
var u, temp, prev, maxprevvalue : word;
base : byte;
negative : boolean;
const maxlongint=longword($7fffffff);
maxlongword=longword($ffffffff);
UnsignedUpperLimit: ValUInt;
const
ValueArray : array['0'..'f'] of byte = (0,1,2,3,4,5,6,7,8,9,$FF,$FF,$FF,$FF,$FF,$FF,$FF,10,11,12,13,14,15,
$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,
10,11,12,13,14,15);
begin
fpc_val_smallint_shortstr := 0;
Temp:=0;
Code:=InitVal(s,negative,base);
if (base=10) or negative then
UnsignedUpperLimit := Word(High(SmallInt))+Ord(negative)
else
UnsignedUpperLimit := High(Word);
if Code>length(s) then
exit;
if (s[Code]=#0) then
@ -1523,27 +1528,22 @@ end;
Code:=0;
exit;
end;
maxprevvalue := maxlongword div base;
if (base = 10) then
maxnewvalue := maxlongint + ord(negative)
else
maxnewvalue := maxlongword;
maxprevvalue := High(Word) div base;
while Code<=Length(s) do
begin
case s[Code] of
'0'..'9' : u:=Ord(S[Code])-Ord('0');
'A'..'F' : u:=Ord(S[Code])-(Ord('A')-10);
'a'..'f' : u:=Ord(S[Code])-(Ord('a')-10);
u:=16;
case s[code] of
'0'..'f' : u:=ValueArray[S[Code]];
#0 : break;
else
u:=16;
;
end;
Prev:=Temp;
Temp:=Temp*longword(base);
If (u >= base) or
(longword(maxnewvalue-u) < temp) or
(prev > maxprevvalue) Then
If (u >= base) or
(prev > maxPrevValue) or
((Temp)>(UnsignedUpperLimit-u)) Then
Begin
fpc_val_smallint_shortstr := 0;
Exit
@ -1552,7 +1552,7 @@ end;
inc(code);
end;
code:=0;
fpc_val_smallint_shortstr:=longint(Temp);
fpc_val_smallint_shortstr:=SmallInt(Temp);
If Negative Then
fpc_val_smallint_shortstr:=-fpc_val_smallint_shortstr;
end;