fix(art): default the .tar cover loader ON (wOPL parity) + 4 real tar-engine defects (#54)#207
Merged
Merged
Conversation
… defects in the tar engine (#54) brenotomaz-eng (#54): "I used to use Wopl and the .tar covers worked perfectly, but in this fork RiptOPL they don't load. I looked for an activation option but couldn't find it in the display tab." ROOT CAUSE: `gEnableArtTar = 0`. That is the whole bug. wOPL has NO equivalent gate on EITHER branch -- verified against the actual source (`git grep -iE 'gEnableArtTar|ENABLE_ART_TAR' wopl/wOPL-base wopl/wOPL-release` returns nothing); both try the archive FIRST, unconditionally, with the loose ART/ file as the fallback. So we shipped the feature he asked for, switched off, and he told us in the report that he went looking for the switch and could not find it. Note #54 was never HW-confirmed either: he tried to retest and his console hung at boot -- that is the separate exFAT-USB/WOPLSDK boot hang, not art.tar. SETTLED NEGATIVES (checked against wOPL, do not re-litigate): the in-archive entry name is byte-for-byte correct ("<value>_<suffix>.png", no folder prefix, no "./"), the ustar parser matches (size@124, 12 octal digits, 512-byte blocks, zero-block terminator), and art_cache.bin's header is byte-identical -- a version mismatch is rejected and self-heals by re-parsing. The engine was never the problem. Flip the default (the toggle stays as an escape hatch) and fix what default-ON makes load-bearing: 1. INDEX CORRUPTION (real bug, we were LESS robust than wOPL). tarParseFile clamped rawSize to MAX_FILE_SIZE and then derived paddedSize FROM THE CLAMPED VALUE, so any member >4 MiB seeked SHORT: the walk landed mid-data and indexed every SUBSEQUENT entry at a garbage offset -- and tarWriteCache PERSISTED that corrupt index to art_cache.bin, where it passes revalidation (which only rejects rawSize > MAX_FILE_SIZE, and the clamped value is exactly ==) and survives reboots until the archive's size changes. Now the seek always uses the UNCAPPED padded size and an oversized member is skipped (wOPL refuses the whole archive; skipping keeps the rest usable and still never desynchronises). 2. SILENT SESSION-WIDE KILL SWITCH. tarParseFile opened with a stat() existence probe whose failure latched s_inactive[kind] -- write-once, process-wide, and nothing live cleared it (tarInvalidate had ZERO callers). The probe was pure redundancy: the caller already proved the file opens, and this function opens it again two lines later. So any driver where open() works but stat() does not killed art.tar for the whole session with the archive sitting right there. Removed; open() is now the single arbiter of existence. 3. THE TOGGLE COULDN'T RE-ARM. Because that latch is write-once and tarInvalidate was dead code, turning the loader ON after boot kept returning nothing until a reboot -- i.e. the toggle looked broken. gui.c now calls tarInvalidate(TAR_KIND_ART) when the setting actually changes. 4. OOB ON THE DECLARED TYPE. TarEntryArt.filename was [41], but the parser derives its copy length from the entry STRIDE, not the array: nameMax = entrySize - sizeof(TarEntryBase) - 1 = 64-16-1 = 47, so it memcpy'd 47 bytes and NUL-terminated at [47] -- 7 past the declared size. Benign in practice (it landed in the struct's own tail padding) but out of bounds on the type and one refactor away from corrupting the next entry. Verified [48] keeps sizeof(TarEntryArt) == 64, so entrySize, nameMax, copyLen, the on-disk art_cache.bin layout and wOPL cache compatibility are ALL unchanged (no ARC_VERSION bump). Also: src/tar.c shipped with ZERO LOG() calls, so every "art.tar doesn't work" report was unfalsifiable (the CHT path announces its hit + device at supportbase.c). Added tracing for the index hit, per-device parse failure, the oversized skip, and the latch arming. Perf of default-ON is answered by wOPL's own author (dcf273bd, "Fix tar device probing ... Fixes lag on game selection when tar files aren't present"): a setup with no art.tar costs one failed open per device per session, then zero -- that latch is exactly why wOPL needs no user toggle. Struct changed -> validated with a full `make clean` rebuild, exit 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The report (brenotomaz-eng, #54)
Root cause — it's one line
gEnableArtTar = 0;wOPL has no equivalent gate on either branch — verified against the real source, not from memory:
Both wOPL branches try the archive first, unconditionally, with the loose
ART/file as fallback. We shipped exactly the feature he asked for, switched off — and he told us in the report that he went looking for the switch and couldn't find it.Worth noting #54 was never HW-confirmed: he tried to retest, and his console hung at boot — that's the separate exFAT-USB/WOPLSDK boot hang, not art.tar.
Settled negatives (checked against wOPL — don't re-litigate)
<value>_<suffix>.png, no folder prefix, no./).art_cache.binheader is byte-identical; a version mismatch is rejected and self-heals.The engine was never the problem.
What else this fixes (default-ON makes these load-bearing)
1. Index corruption — we were less robust than wOPL.
tarParseFileclampedrawSizetoMAX_FILE_SIZEthen derivedpaddedSizefrom the clamped value, so any member >4 MiB seeked short: the walk landed mid-data and indexed every subsequent entry at a garbage offset — andtarWriteCachepersisted that to art_cache.bin, where it passes revalidation (which only rejects> MAX_FILE_SIZE, and the clamped value is exactly==) and survives reboots. Now the seek always uses the uncapped padded size and oversized members are skipped.2. Silent session-wide kill switch. A redundant
stat()existence probe latcheds_inactive[kind]— write-once, process-wide, and nothing live cleared it (tarInvalidatehad zero callers). The probe was pointless: the caller already proved the file opens and the function opens it again two lines later. Any driver whereopen()works butstat()doesn't killed art.tar for the whole session with the archive sitting right there.3. The toggle couldn't re-arm. Because that latch is write-once and
tarInvalidatewas dead code, turning the loader on after boot returned nothing until a reboot — i.e. the toggle looked broken. Now wired on change.4. OOB on the declared type.
filename[41], but the parser derives its copy length from the entry stride:nameMax = 64-16-1 = 47→ memcpy 47 + NUL at[47]= 7 bytes past. Benign (landed in tail padding) but out of bounds and one refactor from corrupting the next entry. Verified[48]keepssizeof(TarEntryArt) == 64:Plus tracing:
src/tar.cshipped with zeroLOG()calls, so every "art.tar doesn't work" report was unfalsifiable (the CHT path announces its hit + device). Added logging for the index hit, per-device parse failure, the oversized skip, and the latch arming.Why default-ON is safe
wOPL's own author answered the perf objection — commit
dcf273bd"Fix tar device probing ... Fixes lag on game selection when tar files aren't present": a setup with no art.tar costs one failed open per device per session, then zero. That latch is precisely why wOPL needs no user toggle. Ours stays as an escape hatch.Validation
Struct changed → full
make cleanrebuild, exit 0.🤖 Generated with Claude Code