Add new test code to verify that tentfile.buf limits are not overpassed

This commit is contained in:
Pierre Muller 2023-05-19 17:19:59 +02:00
parent 513b02f3fd
commit c38cc828e8
2 changed files with 196 additions and 3 deletions

View File

@ -33,7 +33,11 @@ const
maxentrysize = 1024; maxentrysize = 1024;
// Unused, and wrong as there are entries that are larger then 1024 bytes // Unused, and wrong as there are entries that are larger then 1024 bytes
{$ifdef CHECK_INPUTPOINTER_LIMITS}
default_entryfilebufsize = 16384;
{$else not CHECK_INPUTPOINTER_LIMITS}
entryfilebufsize = 16384; entryfilebufsize = 16384;
{$endif CHECK_INPUTPOINTER_LIMITS}
{ppu entries} {ppu entries}
mainentryid = 1; mainentryid = 1;
@ -243,6 +247,9 @@ type
ppu_log_level : longint; ppu_log_level : longint;
ppu_log_idx : integer; ppu_log_idx : integer;
{$endif} {$endif}
{$ifdef CHECK_INPUTPOINTER_LIMITS}
entryfilebufsize :longint;
{$endif CHECK_INPUTPOINTER_LIMITS}
mode : byte; {0 - Closed, 1 - Reading, 2 - Writing} mode : byte; {0 - Closed, 1 - Reading, 2 - Writing}
fisfile : boolean; fisfile : boolean;
fname : string; fname : string;
@ -262,7 +269,11 @@ type
has_more, has_more,
{$endif not generic_cpu} {$endif not generic_cpu}
error : boolean; error : boolean;
constructor create(const fn:string); constructor create(const fn:string
{$ifdef CHECK_INPUTPOINTER_LIMITS}
;aentryfilebufsize : longint = default_entryfilebufsize
{$endif CHECK_INPUTPOINTER_LIMITS}
);
destructor destroy;override; destructor destroy;override;
function getversion:integer; function getversion:integer;
procedure flush; {$ifdef USEINLINE}inline;{$endif} procedure flush; {$ifdef USEINLINE}inline;{$endif}
@ -370,7 +381,11 @@ begin
end; end;
constructor tentryfile.create(const fn:string); constructor tentryfile.create(const fn:string
{$ifdef CHECK_INPUTPOINTER_LIMITS}
;aentryfilebufsize : longint = default_entryfilebufsize
{$endif CHECK_INPUTPOINTER_LIMITS}
);
begin begin
fname:=fn; fname:=fn;
fisfile:=false; fisfile:=false;
@ -380,6 +395,9 @@ begin
error:=false; error:=false;
closed:=true; closed:=true;
tempclosed:=false; tempclosed:=false;
{$ifdef CHECK_INPUTPOINTER_LIMITS}
entryfilebufsize:=aentryfilebufsize;
{$endif CHECK_INPUTPOINTER_LIMITS}
getmem(buf,entryfilebufsize); getmem(buf,entryfilebufsize);
{$ifdef DEBUG_PPU} {$ifdef DEBUG_PPU}
assign(flog,fn+'.debug-log'); assign(flog,fn+'.debug-log');

View File

@ -118,9 +118,20 @@ interface
public public
inputfile : tinputfile; { current inputfile list } inputfile : tinputfile; { current inputfile list }
inputfilecount : longint; inputfilecount : longint;
{$ifdef CHECK_INPUTPOINTER_LIMITS}
private
hidden_inputbuffer, { input buffer }
hidden_inputpointer : pchar;
{ Gets char at inputpointer with offset,
after checking that it doesn't overflow inputfile.bufsize }
function get_inputpointer_char(offset : longint = 0) : char;
procedure inc_inputpointer(amount : longint = 1);
procedure dec_inputpointer;
public
{$else not CHECK_INPUTPOINTER_LIMITS}
inputbuffer, { input buffer } inputbuffer, { input buffer }
inputpointer : pchar; inputpointer : pchar;
{$endif}
inputstart : longint; inputstart : longint;
line_no, { line } line_no, { line }
@ -2732,7 +2743,11 @@ type
begin begin
inc(current_scanner.inputfilecount); inc(current_scanner.inputfilecount);
{ we need to reread the current char } { we need to reread the current char }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
current_scanner.dec_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
dec(current_scanner.inputpointer); dec(current_scanner.inputpointer);
{$endif CHECK_INPUTPOINTER_LIMITS}
{ reset c } { reset c }
c:=#0; c:=#0;
{ shutdown current file } { shutdown current file }
@ -2882,8 +2897,13 @@ type
current_module.sourcefiles.register_file(inputfile); current_module.sourcefiles.register_file(inputfile);
{ reset localinput } { reset localinput }
c:=#0; c:=#0;
{$ifdef CHECK_INPUTPOINTER_LIMITS}
hidden_inputbuffer:=nil;
hidden_inputpointer:=nil;
{$else not CHECK_INPUTPOINTER_LIMITS}
inputbuffer:=nil; inputbuffer:=nil;
inputpointer:=nil; inputpointer:=nil;
{$endif CHECK_INPUTPOINTER_LIMITS}
inputstart:=0; inputstart:=0;
{ reset scanner } { reset scanner }
preprocstack:=nil; preprocstack:=nil;
@ -2936,8 +2956,13 @@ type
begin begin
openinputfile:=inputfile.open; openinputfile:=inputfile.open;
{ load buffer } { load buffer }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
hidden_inputbuffer:=inputfile.buf;
hidden_inputpointer:=inputfile.buf;
{$else not CHECK_INPUTPOINTER_LIMITS}
inputbuffer:=inputfile.buf; inputbuffer:=inputfile.buf;
inputpointer:=inputfile.buf; inputpointer:=inputfile.buf;
{$endif CHECK_INPUTPOINTER_LIMITS}
inputstart:=inputfile.bufstart; inputstart:=inputfile.bufstart;
{ line } { line }
line_no:=0; line_no:=0;
@ -2951,8 +2976,13 @@ type
begin begin
inputfile.close; inputfile.close;
{ reset buffer } { reset buffer }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
hidden_inputbuffer:=nil;
hidden_inputpointer:=nil;
{$else not CHECK_INPUTPOINTER_LIMITS}
inputbuffer:=nil; inputbuffer:=nil;
inputpointer:=nil; inputpointer:=nil;
{$endif CHECK_INPUTPOINTER_LIMITS}
inputstart:=0; inputstart:=0;
{ reset line } { reset line }
line_no:=0; line_no:=0;
@ -2969,8 +2999,13 @@ type
exit; exit;
tempopeninputfile:=inputfile.tempopen; tempopeninputfile:=inputfile.tempopen;
{ reload buffer } { reload buffer }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
hidden_inputbuffer:=inputfile.buf;
hidden_inputpointer:=inputfile.buf;
{$else not CHECK_INPUTPOINTER_LIMITS}
inputbuffer:=inputfile.buf; inputbuffer:=inputfile.buf;
inputpointer:=inputfile.buf; inputpointer:=inputfile.buf;
{$endif CHECK_INPUTPOINTER_LIMITS}
inputstart:=inputfile.bufstart; inputstart:=inputfile.bufstart;
end; end;
@ -2979,18 +3014,31 @@ type
begin begin
if inputfile.closed or inputfile.is_macro then if inputfile.closed or inputfile.is_macro then
exit; exit;
{$ifdef CHECK_INPUTPOINTER_LIMITS}
inputfile.setpos(inputstart+(hidden_inputpointer-hidden_inputbuffer));
{$else not CHECK_INPUTPOINTER_LIMITS}
inputfile.setpos(inputstart+(inputpointer-inputbuffer)); inputfile.setpos(inputstart+(inputpointer-inputbuffer));
{$endif CHECK_INPUTPOINTER_LIMITS}
inputfile.tempclose; inputfile.tempclose;
{ reset buffer } { reset buffer }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
hidden_inputbuffer:=nil;
hidden_inputpointer:=nil;
{$else not CHECK_INPUTPOINTER_LIMITS}
inputbuffer:=nil; inputbuffer:=nil;
inputpointer:=nil; inputpointer:=nil;
{$endif CHECK_INPUTPOINTER_LIMITS}
inputstart:=0; inputstart:=0;
end; end;
procedure tscannerfile.saveinputfile; procedure tscannerfile.saveinputfile;
begin begin
{$ifdef CHECK_INPUTPOINTER_LIMITS}
inputfile.saveinputpointer:=hidden_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
inputfile.saveinputpointer:=inputpointer; inputfile.saveinputpointer:=inputpointer;
{$endif CHECK_INPUTPOINTER_LIMITS}
inputfile.savelastlinepos:=lastlinepos; inputfile.savelastlinepos:=lastlinepos;
inputfile.saveline_no:=line_no; inputfile.saveline_no:=line_no;
end; end;
@ -2998,8 +3046,13 @@ type
procedure tscannerfile.restoreinputfile; procedure tscannerfile.restoreinputfile;
begin begin
{$ifdef check_inputpointer_limits}
hidden_inputbuffer:=inputfile.buf;
hidden_inputpointer:=inputfile.saveinputpointer;
{$else not check_inputpointer_limits}
inputbuffer:=inputfile.buf; inputbuffer:=inputfile.buf;
inputpointer:=inputfile.saveinputpointer; inputpointer:=inputfile.saveinputpointer;
{$endif check_inputpointer_limits}
lastlinepos:=inputfile.savelastlinepos; lastlinepos:=inputfile.savelastlinepos;
line_no:=inputfile.saveline_no; line_no:=inputfile.saveline_no;
if not inputfile.is_macro then if not inputfile.is_macro then
@ -3033,6 +3086,26 @@ type
end; end;
{$ifdef CHECK_INPUTPOINTER_LIMITS}
function tscannerfile.get_inputpointer_char(offset : longint = 0) : char;
begin
assert(hidden_inputpointer-hidden_inputbuffer+offset<=inputfile.bufsize);
get_inputpointer_char:=(hidden_inputpointer+offset)^;
end;
procedure tscannerfile.inc_inputpointer(amount : longint = 1);
begin
assert(hidden_inputpointer-hidden_inputbuffer+amount<=inputfile.bufsize);
inc(hidden_inputpointer,amount);
end;
procedure tscannerfile.dec_inputpointer;
begin
assert(hidden_inputpointer>hidden_inputbuffer);
dec(hidden_inputpointer);
end;
{$endif}
procedure tscannerfile.startrecordtokens(buf:tdynamicarray); procedure tscannerfile.startrecordtokens(buf:tdynamicarray);
begin begin
if not assigned(buf) then if not assigned(buf) then
@ -3504,8 +3577,13 @@ type
{ save current scanner state } { save current scanner state }
replaystack:=treplaystack.create(token,idtoken,orgpattern,pattern, replaystack:=treplaystack.create(token,idtoken,orgpattern,pattern,
cstringpattern,patternw,current_settings,replaytokenbuf,change_endian_for_replay,replaystack); cstringpattern,patternw,current_settings,replaytokenbuf,change_endian_for_replay,replaystack);
{$ifdef check_inputpointer_limits}
if assigned(hidden_inputpointer) then
dec_inputpointer;
{$else not check_inputpointer_limits}
if assigned(inputpointer) then if assigned(inputpointer) then
dec(inputpointer); dec(inputpointer);
{$endif check_inputpointer_limits}
{ install buffer } { install buffer }
replaytokenbuf:=buf; replaytokenbuf:=buf;
@ -3557,11 +3635,19 @@ type
{ restore compiler settings } { restore compiler settings }
current_settings:=replaystack.settings; current_settings:=replaystack.settings;
popreplaystack; popreplaystack;
{$ifdef check_inputpointer_limits}
if assigned(hidden_inputpointer) then
begin
c:=get_inputpointer_char;
inc_inputpointer;
end;
{$else not check_inputpointer_limits}
if assigned(inputpointer) then if assigned(inputpointer) then
begin begin
c:=inputpointer^; c:=inputpointer^;
inc(inputpointer); inc(inputpointer);
end; end;
{$endif check_inputpointer_limits}
exit; exit;
end; end;
repeat repeat
@ -3703,22 +3789,44 @@ type
the place of the #0 in the buffer with tempopen } the place of the #0 in the buffer with tempopen }
if (c=#0) and (bufsize>0) and if (c=#0) and (bufsize>0) and
not(inputfile.is_macro) and not(inputfile.is_macro) and
{$ifdef CHECK_INPUTPOINTER_LIMITS}
(hidden_inputpointer-hidden_inputbuffer<bufsize) then
{$else not CHECK_INPUTPOINTER_LIMITS}
(inputpointer-inputbuffer<bufsize) then (inputpointer-inputbuffer<bufsize) then
{$endif CHECK_INPUTPOINTER_LIMITS}
begin begin
c:=' '; c:=' ';
{$ifdef CHECK_INPUTPOINTER_LIMITS}
inc_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
inc(inputpointer); inc(inputpointer);
{$endif CHECK_INPUTPOINTER_LIMITS}
exit; exit;
end; end;
{ can we read more from this file ? } { can we read more from this file ? }
if (c<>#26) and (not endoffile) then if (c<>#26) and (not endoffile) then
begin begin
readbuf; readbuf;
{$ifdef CHECK_INPUTPOINTER_LIMITS}
hidden_inputpointer:=buf;
hidden_inputbuffer:=buf;
{$else not CHECK_INPUTPOINTER_LIMITS}
inputpointer:=buf; inputpointer:=buf;
inputbuffer:=buf; inputbuffer:=buf;
{$endif CHECK_INPUTPOINTER_LIMITS}
inputstart:=bufstart; inputstart:=bufstart;
{ first line? } { first line? }
if line_no=0 then if line_no=0 then
begin begin
{$ifdef CHECK_INPUTPOINTER_LIMITS}
c:=get_inputpointer_char;
{ eat utf-8 signature? }
if (bufsize>2) and
(ord(get_inputpointer_char)=$ef) and
(ord(get_inputpointer_char(1))=$bb) and
(ord(get_inputpointer_char(2))=$bf) then
begin
{$else not CHECK_INPUTPOINTER_LIMITS}
c:=inputpointer^; c:=inputpointer^;
{ eat utf-8 signature? } { eat utf-8 signature? }
if (bufsize>2) and if (bufsize>2) and
@ -3726,6 +3834,7 @@ type
(ord((inputpointer+1)^)=$bb) and (ord((inputpointer+1)^)=$bb) and
(ord((inputpointer+2)^)=$bf) then (ord((inputpointer+2)^)=$bf) then
begin begin
{$endif CHECK_INPUTPOINTER_LIMITS}
(* we don't support including files with an UTF-8 bom (* we don't support including files with an UTF-8 bom
inside another file that wasn't encoded as UTF-8 inside another file that wasn't encoded as UTF-8
already (we don't support {$codepage xxx} switches in already (we don't support {$codepage xxx} switches in
@ -3733,7 +3842,11 @@ type
if (current_settings.sourcecodepage<>CP_UTF8) and if (current_settings.sourcecodepage<>CP_UTF8) and
not current_module.in_global then not current_module.in_global then
Message(scanner_f_illegal_utf8_bom); Message(scanner_f_illegal_utf8_bom);
{$ifdef CHECK_INPUTPOINTER_LIMITS}
inc_inputpointer(3);
{$else not CHECK_INPUTPOINTER_LIMITS}
inc(inputpointer,3); inc(inputpointer,3);
{$endif CHECK_INPUTPOINTER_LIMITS}
message(scan_c_switching_to_utf8); message(scan_c_switching_to_utf8);
current_settings.sourcecodepage:=CP_UTF8; current_settings.sourcecodepage:=CP_UTF8;
exclude(current_settings.moduleswitches,cs_system_codepage); exclude(current_settings.moduleswitches,cs_system_codepage);
@ -3742,7 +3855,11 @@ type
line_no:=1; line_no:=1;
if cs_asm_source in current_settings.globalswitches then if cs_asm_source in current_settings.globalswitches then
{$ifdef CHECK_INPUTPOINTER_LIMITS}
inputfile.setline(line_no,inputstart+hidden_inputpointer-hidden_inputbuffer);
{$else not CHECK_INPUTPOINTER_LIMITS}
inputfile.setline(line_no,inputstart+inputpointer-inputbuffer); inputfile.setline(line_no,inputstart+inputpointer-inputbuffer);
{$endif CHECK_INPUTPOINTER_LIMITS}
end; end;
end end
else else
@ -3774,8 +3891,13 @@ type
end; end;
end; end;
{ load next char } { load next char }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
c:=get_inputpointer_char;
inc_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
c:=inputpointer^; c:=inputpointer^;
inc(inputpointer); inc(inputpointer);
{$endif CHECK_INPUTPOINTER_LIMITS}
until c<>#0; { if also end, then reload again } until c<>#0; { if also end, then reload again }
end; end;
end; end;
@ -3786,7 +3908,11 @@ type
hp : tinputfile; hp : tinputfile;
begin begin
{ save old postion } { save old postion }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
dec_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
dec(inputpointer); dec(inputpointer);
{$endif CHECK_INPUTPOINTER_LIMITS}
tempcloseinputfile; tempcloseinputfile;
{ create macro 'file' } { create macro 'file' }
{ use special name to dispose after !! } { use special name to dispose after !! }
@ -3797,8 +3923,13 @@ type
inc(macro_nesting_depth); inc(macro_nesting_depth);
setmacro(p,len); setmacro(p,len);
{ local buffer } { local buffer }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
hidden_inputbuffer:=buf;
hidden_inputpointer:=buf;
{$else not CHECK_INPUTPOINTER_LIMITS}
inputbuffer:=buf; inputbuffer:=buf;
inputpointer:=buf; inputpointer:=buf;
{$endif CHECK_INPUTPOINTER_LIMITS}
inputstart:=bufstart; inputstart:=bufstart;
ref_index:=fileindex; ref_index:=fileindex;
internally_generated_macro:=internally_generated; internally_generated_macro:=internally_generated;
@ -3809,14 +3940,23 @@ type
lasttokenpos:=0; lasttokenpos:=0;
nexttokenpos:=0; nexttokenpos:=0;
{ load new c } { load new c }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
c:=get_inputpointer_char;
inc_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
c:=inputpointer^; c:=inputpointer^;
inc(inputpointer); inc(inputpointer);
{$endif CHECK_INPUTPOINTER_LIMITS}
end; end;
procedure tscannerfile.do_gettokenpos(out tokenpos: longint; out filepos: tfileposinfo); procedure tscannerfile.do_gettokenpos(out tokenpos: longint; out filepos: tfileposinfo);
begin begin
{$ifdef CHECK_INPUTPOINTER_LIMITS}
tokenpos:=inputstart+(hidden_inputpointer-hidden_inputbuffer);
{$else not CHECK_INPUTPOINTER_LIMITS}
tokenpos:=inputstart+(inputpointer-inputbuffer); tokenpos:=inputstart+(inputpointer-inputbuffer);
{$endif CHECK_INPUTPOINTER_LIMITS}
filepos.line:=line_no; filepos.line:=line_no;
filepos.column:=tokenpos-lastlinepos; filepos.column:=tokenpos-lastlinepos;
filepos.fileindex:=inputfile.ref_index; filepos.fileindex:=inputfile.ref_index;
@ -3896,23 +4036,40 @@ type
begin begin
with inputfile do with inputfile do
begin begin
{$ifdef CHECK_INPUTPOINTER_LIMITS}
if (byte(get_inputpointer_char)=0) and not(endoffile) then
{$else not CHECK_INPUTPOINTER_LIMITS}
if (byte(inputpointer^)=0) and not(endoffile) then if (byte(inputpointer^)=0) and not(endoffile) then
{$endif CHECK_INPUTPOINTER_LIMITS}
begin begin
cur:=c; cur:=c;
reload; reload;
if byte(cur)+byte(c)<>23 then if byte(cur)+byte(c)<>23 then
{$ifdef CHECK_INPUTPOINTER_LIMITS}
dec_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
dec(inputpointer); dec(inputpointer);
{$endif CHECK_INPUTPOINTER_LIMITS}
end end
else else
begin begin
{ Support all combination of #10 and #13 as line break } { Support all combination of #10 and #13 as line break }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
if (byte(get_inputpointer_char)+byte(c)=23) then
inc_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
if (byte(inputpointer^)+byte(c)=23) then if (byte(inputpointer^)+byte(c)=23) then
inc(inputpointer); inc(inputpointer);
{$endif CHECK_INPUTPOINTER_LIMITS}
end; end;
{ Always return #10 as line break } { Always return #10 as line break }
c:=#10; c:=#10;
{ increase line counters } { increase line counters }
{$ifdef CHECK_INPUTPOINTER_LIMITS}
lastlinepos:=inputstart+(hidden_inputpointer-hidden_inputbuffer);
{$else not CHECK_INPUTPOINTER_LIMITS}
lastlinepos:=inputstart+(inputpointer-inputbuffer); lastlinepos:=inputstart+(inputpointer-inputbuffer);
{$endif CHECK_INPUTPOINTER_LIMITS}
inc(line_no); inc(line_no);
{ update linebuffer } { update linebuffer }
if cs_asm_source in current_settings.globalswitches then if cs_asm_source in current_settings.globalswitches then
@ -4212,11 +4369,19 @@ type
procedure tscannerfile.readchar; procedure tscannerfile.readchar;
begin begin
{$ifdef CHECK_INPUTPOINTER_LIMITS}
c:=get_inputpointer_char;
{$else not CHECK_INPUTPOINTER_LIMITS}
c:=inputpointer^; c:=inputpointer^;
{$endif CHECK_INPUTPOINTER_LIMITS}
if c=#0 then if c=#0 then
reload reload
else else
{$ifdef CHECK_INPUTPOINTER_LIMITS}
inc_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
inc(inputpointer); inc(inputpointer);
{$endif CHECK_INPUTPOINTER_LIMITS}
end; end;
@ -4251,8 +4416,13 @@ type
err:=true; err:=true;
end; end;
end; end;
{$ifdef CHECK_INPUTPOINTER_LIMITS}
c:=get_inputpointer_char;
inc_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
c:=inputpointer^; c:=inputpointer^;
inc(inputpointer); inc(inputpointer);
{$endif CHECK_INPUTPOINTER_LIMITS}
end; end;
#0 : #0 :
reload; reload;
@ -4273,8 +4443,13 @@ type
err:=true; err:=true;
end; end;
end; end;
{$ifdef CHECK_INPUTPOINTER_LIMITS}
c:=get_inputpointer_char;
inc_inputpointer;
{$else not CHECK_INPUTPOINTER_LIMITS}
c:=inputpointer^; c:=inputpointer^;
inc(inputpointer); inc(inputpointer);
{$endif CHECK_INPUTPOINTER_LIMITS}
end end
else else
break; break;