sbfs: give sbfsMatchEntry a counter of its own

sbfsFind counts a block's eight entries in SbfsCount and calls
sbfsMatchEntry for each one, and sbfsMatchEntry used the same variable for
its own twenty two byte comparison. A name differing at its first byte
returned without decrementing, leaving 22 in the entry counter, so the
search then walked twenty two entries through a buffer holding eight: off
the end of it, into whatever data happened to follow, matching against
rubbish and reporting a file that is not there as found.

It had always been there. What decided whether it looked like it worked
was the bytes after SbfsBuffer, so it stayed hidden until unrelated data
was added and changed them. It showed up as "dir" followed by any failed
"load" reporting that the file could not be read rather than that it does
not exist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Anachronaut
2026-08-19 18:18:12 -04:00
co-authored by Claude Opus 5
parent be402cc9be
commit 301716e869
+10 -1
View File
@@ -350,13 +350,20 @@ sbfsWalkName:
; Compares the name in the entry at DP2 with the one kept in SbfsWanted. Q is zero if ; Compares the name in the entry at DP2 with the one kept in SbfsWanted. Q is zero if
; they are the same. Names are padded with zeroes rather than terminated, so a name that ; they are the same. Names are padded with zeroes rather than terminated, so a name that
; fills the field has no terminator to look for, which is why the count is what stops it. ; fills the field has no terminator to look for, which is why the count is what stops it.
; A COUNTER OF ITS OWN, and that matters more than it looks. sbfsFind counts the eight
; entries of a block in SbfsCount and calls this for each one; when this used SbfsCount too,
; a failed comparison left the ENTRY count holding however far the NAME comparison had got.
; A name differing at its first byte left 22 there, so the search walked twenty two entries
; through a buffer holding eight - off the end of it, into whatever data happened to follow,
; and reported a match against rubbish. What followed the buffer decided whether it looked
; like it worked, which is why it went unnoticed until unrelated data was added.
sbfsMatchEntry: sbfsMatchEntry:
PSHD.2 PSHD.2
POPD.0 POPD.0
DPUP.0 0d06 ; The name inside the entry. DPUP.0 0d06 ; The name inside the entry.
SETD.2 SbfsWanted SETD.2 SbfsWanted
INIA 0d22 INIA 0d22
SETD.1 SbfsCount SETD.1 SbfsMatchLeft
STA.1 STA.1
sbfsMatchLoop: sbfsMatchLoop:
@@ -1228,6 +1235,8 @@ SbfsOne:
0x00 0x01 0x00 0x01
SbfsCount: SbfsCount:
0x00 0x00
SbfsMatchLeft:
0x00
SbfsLeft: SbfsLeft:
0x00 0x00