Skip to content

Fix Database::getHeaderInfo() signed-shift UB and use fixed-width Header types#558

Merged
SRombauts merged 1 commit into
masterfrom
fix-getheaderinfo-shift-ub
Jun 30, 2026
Merged

Fix Database::getHeaderInfo() signed-shift UB and use fixed-width Header types#558
SRombauts merged 1 commit into
masterfrom
fix-getheaderinfo-shift-ub

Conversation

@SRombauts

Copy link
Copy Markdown
Owner

Summary

Fixes two findings from the deep code review (DB-02, DB-03) in Database::getHeaderInfo() and the public Header struct.

DB-02 — signed left-shift UB in the big-endian assembly

The multi-byte header fields were assembled from unsigned char operands, which promote to int before the << 24 shift. For any byte with the high bit set this is signed-left-shift undefined behaviour, and the int result was then sign-extended when widened to the (LP64) unsigned long fields.

Each byte is now cast to std::uint32_t before shifting, through a small local readBE32 helper that also collapses the 14 repeated 4-line blocks.

DB-03 — platform-variable field widths

Header used unsigned long, which is 32-bit on LLP64 (Windows) but 64-bit on LP64 (Linux/macOS), so the struct layout and field widths differed across platforms. The struct now uses fixed-width <cstdint> types (std::uint8_t / std::uint32_t).

Test plan

  • Built SQLiteCpp_tests (MSVC, Debug) — clean.
  • ctest -C Debug — 100% passed, including Database.getHeaderInfo.

No public API behaviour changes; the parsed values are identical, only the field types and the (previously UB) assembly path change.

The big-endian assembly shifted unsigned char operands that promote to int,
so bytes with the high bit set produced signed left-shift UB and sign-extended
when widened to the Header fields. Cast each byte to uint32_t before shifting,
via a local readBE32 helper that also removes the repetitive byte arithmetic.

Header used platform-variable `unsigned long` (32-bit on LLP64 Windows, 64-bit
on LP64), giving a cross-platform field-width mismatch. Switch the struct to
fixed-width <cstdint> types (uint8_t / uint32_t).

Fixes DB-02 and DB-03 from the code review.
@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 99.688% (-0.02%) from 99.711% — fix-getheaderinfo-shift-ub into master

@SRombauts SRombauts self-assigned this Jun 30, 2026
@SRombauts SRombauts added the bug label Jun 30, 2026
@SRombauts SRombauts merged commit 6c7a96f into master Jun 30, 2026
36 of 38 checks passed
@SRombauts SRombauts deleted the fix-getheaderinfo-shift-ub branch June 30, 2026 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants