diff options
| author | Valentin Popov <valentin@popov.link> | 2026-02-12 00:21:32 +0300 |
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2026-02-12 00:21:32 +0300 |
| commit | 3410b54793c3a1808e58d0fae94fb2ebd5f81015 (patch) | |
| tree | 4384f2bec57a6326c815231c1e283b1b42352c17 /crates/rsli/src/parse.rs | |
| parent | 041b1a6cb3159463fe81f4b2d18cb968d6f3fd87 (diff) | |
| download | fparkan-3410b54793c3a1808e58d0fae94fb2ebd5f81015.tar.xz fparkan-3410b54793c3a1808e58d0fae94fb2ebd5f81015.zip | |
feat: добавить тесты для проверки структурных инвариантов и корректности сортировки в RsLi
Diffstat (limited to 'crates/rsli/src/parse.rs')
| -rw-r--r-- | crates/rsli/src/parse.rs | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/crates/rsli/src/parse.rs b/crates/rsli/src/parse.rs index 272e076..9a916dc 100644 --- a/crates/rsli/src/parse.rs +++ b/crates/rsli/src/parse.rs @@ -149,13 +149,31 @@ pub fn parse_library(bytes: Arc<[u8]>, opts: OpenOptions) -> Result<Library> { let presorted_flag = u16::from_le_bytes([bytes[14], bytes[15]]); if presorted_flag == 0xABBA { + let mut seen = vec![false; count]; for entry in &entries { let idx = i32::from(entry.sort_to_original); - if idx < 0 || usize::try_from(idx).map_err(|_| Error::IntegerOverflow)? >= count { + if idx < 0 { return Err(Error::CorruptEntryTable( "sort_to_original is not a valid permutation index", )); } + let idx = usize::try_from(idx).map_err(|_| Error::IntegerOverflow)?; + if idx >= count { + return Err(Error::CorruptEntryTable( + "sort_to_original is not a valid permutation index", + )); + } + if seen[idx] { + return Err(Error::CorruptEntryTable( + "sort_to_original is not a permutation", + )); + } + seen[idx] = true; + } + if seen.iter().any(|value| !*value) { + return Err(Error::CorruptEntryTable( + "sort_to_original is not a permutation", + )); } } else { let mut sorted: Vec<usize> = (0..count).collect(); |
