Repository navigation
fix: read slot directories from the page prelude - #28
Merged
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
opensqlanywhere-docs | a621366 | Oct 25 2026, 12:17 PM |
Nathan-D-R
force-pushed
the
fix/ap-deobfuscation
branch
from
October 25, 2026 07:48
24d21e8 to
8944b1a
Compare
Nathan-D-R
force-pushed
the
fix/slot-directory
branch
from
October 25, 2026 07:52
5f6d335 to
061cb27
Compare
3 tasks done
The directory is the declared number of entries, confirmed against the plaintext trailer count, instead of the best run found by scanning the first 0x300 bytes. Small directories are read, long ones are read whole, and truncated, ambiguous, unconfirmed or self-overlapping directories are errors, or warnings under Leniency::DIRECTORY. Signed-off-by: Nathan Riley <git@nathanriley.com>
… a directory read left out Counts below four are unconfirmed, a declared count with no matching layout is UnknownPrelude, offsets below the array are rows, and truncation, ambiguity and left-out rows are typed errors and warnings that carry the entries read, the count declared and the number dropped. Signed-off-by: Nathan Riley <git@nathanriley.com>
Signed-off-by: Nathan Riley <git@nathanriley.com>
Nathan-D-R
force-pushed
the
fix/slot-directory
branch
from
October 25, 2026 08:18
061cb27 to
16c20b8
Compare
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.
Description
Stacked on #27. Fixes the slot directory findings (S1 6, 7, 8, 9 and S2 13, 14) and the review findings B2, S4 and S5.
SlottedPage::parseno longer scans for the longest descending run in the first0x300bytes. It reads the slot count the page prelude declares (a u16 four bytes before the array, or six with a zero word between), requires it to equal the plaintext trailer's count byte, and takes exactly that many entries. The old scan stays as an unconfirmed fallback.small_confirmed_directory_is_read).0x0040after a zero gap is not a slot (stray_value_after_a_zero_gap_is_not_a_slot).AmbiguousSlotDirectory; slot-like data the prelude does not confirm isNoSlotDirectory.SlotDirectoryTruncated(entries read, count declared, and the byte offset where the array broke); a 200-entry directory past the old search window is read whole.Row::exact()isfalsefor every row; decoding row headers is out of scope.overflow_prefixwas removed in feat!: API foundation (errors, options, warnings, non_exhaustive) #26.Review findings
NoSlotDirectory(orUnknownPreludewhen nothing fits) in strict mode, a directory withUnverifiedDirectoryunderLeniency::DIRECTORYonly when exactly one candidate exists. Testsmall_declared_counts_are_not_confirmed, including a page full of01 00words. The reviewer's null test (a wrong-count probe over 15,835 genuine pages) is the evidence; I did not add it as a unit test because it needs corpus pages.offset < end, which also rejected rows that legitimately sit below the array (page 116: catalog rows at0x2a..0x190, directory at0x1a7); it is nowarray_start <= offset < end(rows_below_the_directory_are_rows). Lenient mode no longer throws numbers away:SlotDirectoryTruncated { found, expected }andSlotOffsetsInDirectory { dropped }are typed warnings (lenient_reads_count_the_rows_they_leave_out,lenient_reads_flag_a_rejected_directory).0x1ff..0x205, i.e. at the sector 1 boundary, which points at a mis-decoded sector rather than a second run; where a continuation exists it is not unique (candidate starts1, 3, 5, ...are all suffixes of one run). I did not find a rule that is safe to accept without ambiguity, so multi-run directories are still reported as truncated, withstopped_atso the sector boundary is visible. This is not solved.Ok(None)now means the page declares no rows and nothing looks like a directory. A trailer count above zero with no matching layout isError::UnknownPrelude(a warning underLeniency::DIRECTORY).UnknownPreludeis constructed.Open question recorded
SPECIFICATION.mdsection 6 now records the two multi-run shapes the re-review found (a run that continues at the start of the page, page 284; a value wrap mid-array, page 292) and that strict mode cannot read pages with 1 to 3 rows. S4 stays deferred.Corpus delta
Decoded
Epages with a Verified or Calibratedbv(a quarter of the files; 28,900 pages, fewer than before because block anchors no longer confirm), parsed strictly:Earlier numbers (64,000 pages with block-anchor pages included): 34,436 confirmed, 7,560 unconfirmed, 4,434 truncated, 3,538 offset-in-directory, 1,245 ambiguous. The sets are different, so the rates are what compare: ambiguous fell from 1.9 % to 0.003 % (counts below 4 no longer create candidates), offset-in-directory from 5.5 % to 6.1 % of the sample but now only genuine overlaps, truncated from 6.9 % to 6.7 %.
API breaks
On top of #26:
SlotDirectory::declared_count(),SlottedPage::warnings()added;parsecan fail with five errors;Error::SlotDirectoryTruncatedgainsstopped_at.SlotDirectory::slots()no longer includes trailing zero entries.Tests changed
None existed for
slotted.rs; 15 added.Docs-site edits needed (release PR)
docs/docs/specification.mdsection 4.2: the confirmed prelude layout and the count-below-4 caveat.docs/docs/quickstart-rust.md:parsetakes options.OpenQBW follow-up
SlottedPage::parse(page, &opts)?,.directory(),.rows()(aRowwithoffset(),bytes(),exact()) replaceparse,.directory,row_bytes()in attribution_schema.rs, attribution_content.rs and transaction_header.rs. Row slices are inexact; its record decoders must not treat the slice length as the row length.overflow_prefixis gone: record stitching that used it needs the prelude decoded first. A page with a small row count now needsLeniency::DIRECTORY.Checklist
git commit -s