Skip to content

Fix SST parsing for strings spanning Continue record boundaries - #2

Open
mattf-intex wants to merge 1 commit into
PleaseDont:mainfrom
ketbra:sst_fix
Open

Fix SST parsing for strings spanning Continue record boundaries#2
mattf-intex wants to merge 1 commit into
PleaseDont:mainfrom
ketbra:sst_fix

Conversation

@mattf-intex

Copy link
Copy Markdown

The SST decoder was incorrectly concatenating Continue record bytes without accounting for the grbit byte that prefixes string continuations. Per MS-XLS spec (2.4.265 SST, 2.4.39 Continue), when a string spans a Continue record boundary, the Continue record begins with a 1-byte grbit field indicating the encoding of the remaining characters.

This caused "sst get" index errors when reading XLS files with large shared string tables that span multiple Continue records.

The fix rewrites the decode method to:

  • Track position across SST and Continue record boundaries
  • Skip the grbit byte at Continue boundaries when parsing strings
  • Handle encoding changes (compressed vs UTF-16) at boundaries

Or a shorter version:

Fix SST parsing to handle Continue record boundaries correctly

Strings spanning Continue records were corrupted because the grbit byte at Continue boundaries was being included as string data. Now properly skips grbit and handles encoding changes per MS-XLS spec.

Fixes "sst get" errors on XLS files with large shared string tables.

The SST decoder was incorrectly concatenating Continue record bytes
without accounting for the grbit byte that prefixes string continuations.
Per MS-XLS spec (2.4.265 SST, 2.4.39 Continue), when a string spans a
Continue record boundary, the Continue record begins with a 1-byte grbit
field indicating the encoding of the remaining characters.

This caused "sst get" index errors when reading XLS files with large
shared string tables that span multiple Continue records.

The fix rewrites the decode method to:
- Track position across SST and Continue record boundaries
- Skip the grbit byte at Continue boundaries when parsing strings
- Handle encoding changes (compressed vs UTF-16) at boundaries

Or a shorter version:

Fix SST parsing to handle Continue record boundaries correctly

Strings spanning Continue records were corrupted because the grbit byte
at Continue boundaries was being included as string data. Now properly
skips grbit and handles encoding changes per MS-XLS spec.

Fixes "sst get" errors on XLS files with large shared string tables.
ketbra pushed a commit to ketbra/xlrd that referenced this pull request Jan 21, 2026
Incorporates fix from PR #2 (PleaseDont#2)

Problem:
The SST (Shared String Table) decoder was incorrectly handling string
data that spans multiple Continue records. When strings span across
Continue record boundaries, each continuation starts with a 1-byte
grbit field indicating character encoding. The old implementation
concatenated all Continue record bytes without accounting for these
grbit bytes, treating them as string data instead of metadata.

This caused:
- String corruption in large shared string tables
- "sst get" index errors when processing XLS files
- Incorrect string decoding when encoding changed at record boundaries

Solution:
Complete rewrite of SST parsing with new SstReader struct:
- Tracks position across main SST record and Continue records
- Properly skips grbit byte when transitioning to Continue records mid-string
- Handles encoding transitions (compressed ↔ UTF-16) at record boundaries
- Manually iterates through strings with proper boundary awareness

Key changes (src/record/sst.rs):
- Add SstReader struct with methods: read_byte(), read_u16(), read_i32()
- Add read_string_bytes() to handle Continue boundaries correctly
- Rewrite decode() to use SstReader instead of naive concatenation
- Remove XLUnicodeRichExtendedString struct (no longer needed)
- Remove until_eof import (now doing manual iteration)

Test Results: **71/71 files now pass (100%)**
- Previously: 70/71 (98.6%) - 55982.xls failed with "sst get" error
- Now: 71/71 (100%) - ALL files parse successfully!

This fix is critical for correctly reading XLS files with large shared
string tables that require multiple BIFF records.
mattf-intex pushed a commit to mattf-intex/xlrd that referenced this pull request Feb 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants