fix: guard against uint32 underflow in memset/memcpy and strings unit
When size=0 was passed to memset() or memcpy(), the loop bound `0 to size-1` underflowed to $FFFFFFFF, iterating ~4 billion times and causing an immediate page fault. Added `if size = 0 then exit` guards to both memset() and memcpy() in util.pas. Also guarded all `for i:=0 to X-1` loops in strings.pas where X could be 0 on empty string inputs: - stringToUpper: wrap loop in `if stringSize > 0` - stringToLower: wrap loop in `if stringSize > 0` - stringEquals: early exit when both sizes are 0 - stringToInt: early exit when string is empty Additionally fixed all previously identified bugs in strings.pas: - hexStringToInt: guard against empty string underflow - stringConcat: cache stringSize calls to avoid redundant O(n) scans - stringTrim: clamp length to source string size - stringSub: bounds check start/size against source length - stringReplace: complete rewrite - was using stringEquals() for substring matching (only matched at string end), dropped prefix chars, had dangling assignment overwriting valid result with uninitialized pointer, and had unused variable - stringIndexOf: rewritten to use new stringMatchAt() helper for correct substring matching - stringContains: simplified to delegate to fixed stringIndexOf(), also fixing uint32 underflow when sub was empty - stringToInt: removed always-true `v >= 0` check on uint32 - intToString: implemented (was a stub returning ' ') - Added stringMatchAt() helper for prefix comparison - Added comprehensive UnitTest procedure with 77 assertions including adversarial empty/nil/boundary inputs
This commit is contained in:
1 parent
084130da80
commit
beb4b253ab
3 files changed
+382
-89
No files matched your search
+377
-89
File diff suppressed because it is too large.
Load diff
@@ -414,6 +414,7 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
//push_trace('util.memset');
|
//push_trace('util.memset');
|
||||||
|
if size = 0 then exit;
|
||||||
for i:=0 to size-1 do begin
|
for i:=0 to size-1 do begin
|
||||||
loc:= puint8(location + i);
|
loc:= puint8(location + i);
|
||||||
loc^:= value;
|
loc^:= value;
|
||||||
@@ -428,6 +429,7 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
//push_trace('util.memcpy');
|
//push_trace('util.memcpy');
|
||||||
|
if size = 0 then exit;
|
||||||
for i:=0 to size-1 do begin
|
for i:=0 to size-1 do begin
|
||||||
src:= puint8(source + i);
|
src:= puint8(source + i);
|
||||||
dst:= puint8(dest + i);
|
dst:= puint8(dest + i);
|
||||||
|
|||||||
@@ -251,6 +251,9 @@ begin
|
|||||||
{ Initialize visual terminal (registers with desktop search) }
|
{ Initialize visual terminal (registers with desktop search) }
|
||||||
vterminal.init;
|
vterminal.init;
|
||||||
|
|
||||||
|
{ Run unit tests }
|
||||||
|
strings.UnitTest;
|
||||||
|
|
||||||
{ Main render loop }
|
{ Main render loop }
|
||||||
syslog.logln('KERNEL', 'Entering main render loop.');
|
syslog.logln('KERNEL', 'Entering main render loop.');
|
||||||
tracer.push_trace('kmain.MAINLOOP');
|
tracer.push_trace('kmain.MAINLOOP');
|
||||||
|
|||||||
Reference in new issue
Block a user