From 301716e869ec8d95e6a61101417ffd889b9c7300 Mon Sep 17 00:00:00 2001 From: Anachronaut Date: Wed, 19 Aug 2026 18:18:12 -0400 Subject: [PATCH] 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 --- Programs/CosmOS/Source/sbfs.asm | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Programs/CosmOS/Source/sbfs.asm b/Programs/CosmOS/Source/sbfs.asm index a81aaf3..05a49a2 100644 --- a/Programs/CosmOS/Source/sbfs.asm +++ b/Programs/CosmOS/Source/sbfs.asm @@ -350,13 +350,20 @@ sbfsWalkName: ; 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 ; 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: PSHD.2 POPD.0 DPUP.0 0d06 ; The name inside the entry. SETD.2 SbfsWanted INIA 0d22 - SETD.1 SbfsCount + SETD.1 SbfsMatchLeft STA.1 sbfsMatchLoop: @@ -1228,6 +1235,8 @@ SbfsOne: 0x00 0x01 SbfsCount: 0x00 +SbfsMatchLeft: + 0x00 SbfsLeft: 0x00