fix out-of-bounds read in string to struct cast by jmestwa-coder · Pull Request #23384 · duckdb/duckdb · GitHub
Skip to content

fix out-of-bounds read in string to struct cast - #23384

Merged
Mytherin merged 1 commit into
duckdb:v1.5-variegatafrom
jmestwa-coder:struct-cast-oob-read
Jun 23, 2026
Merged

Mytherin merged 1 commit into
duckdb:v1.5-variegatafrom
jmestwa-coder:struct-cast-oob-read

Conversation

@jmestwa-coder

Copy link
Copy Markdown
Contributor

Out-of-bounds read in SplitStruct
After consuming the opening {/( and skipping whitespace, the empty-struct check reads buf[pos] without testing pos against len, so a non-inlined string that is just the opening character followed by spaces reads one byte past the buffer. The list and map splitters already guard this spot (pos < len / pos == len); matched the struct path to them.

ASan on CAST('{ ' AS STRUCT(a INTEGER)) before the fix:

ERROR: AddressSanitizer: heap-buffer-overflow ... READ of size 1
    #0 ... duckdb::VectorStringToStruct::SplitStruct(...) vector_cast_helpers.cpp:462

@duckdb-draftbot
duckdb-draftbot marked this pull request as draft June 20, 2026 09:43
@Mytherin

Mytherin commented Jun 22, 2026 •

Copy link
Copy Markdown
Member

@jmestwa-coder
jmestwa-coder force-pushed the struct-cast-oob-read branch from e8889ab to 28aa0a2 Compare June 22, 2026 13:37
@jmestwa-coder
jmestwa-coder changed the base branch from main to v1.5-variegata June 22, 2026 13:37
@jmestwa-coder

Copy link
Copy Markdown
Contributor Author

done, rebased onto v1.5-variegata and retargeted the base. diff is just the SplitStruct guard plus the two regression cases.

@Mytherin
Mytherin marked this pull request as ready for review June 22, 2026 15:36
@Mytherin
Mytherin merged commit 15d896e into duckdb:v1.5-variegata Jun 23, 2026
65 checks passed
@Mytherin

Copy link
Copy Markdown
Member

kaka11chen pushed a commit to kaka11chen/astrovela_vane that referenced this pull request Aug 14, 2026
**Out-of-bounds read in SplitStruct**
After consuming the opening `{`/`(` and skipping whitespace, the
empty-struct check reads `buf[pos]` without testing `pos` against `len`,
so a non-inlined string that is just the opening character followed by
spaces reads one byte past the buffer. The list and map splitters
already guard this spot (`pos < len` / `pos == len`); matched the struct
path to them.

ASan on `CAST('{               ' AS STRUCT(a INTEGER))` before the fix:
```
ERROR: AddressSanitizer: heap-buffer-overflow ... READ of size 1
    #0 ... duckdb::VectorStringToStruct::SplitStruct(...) vector_cast_helpers.cpp:462
```

Upstream-Commit: duckdb/duckdb@15d896e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants