Skip to content

fix(STLLoader): guard isBinary against buffers shorter than 84 bytes#431

Open
fursund wants to merge 1 commit into
pmndrs:mainfrom
fursund:fix/stl-loader-isbinary-short-buffer
Open

fix(STLLoader): guard isBinary against buffers shorter than 84 bytes#431
fursund wants to merge 1 commit into
pmndrs:mainfrom
fursund:fix/stl-loader-isbinary-short-buffer

Conversation

@fursund

@fursund fursund commented Jun 10, 2026

Copy link
Copy Markdown

The bug

STLLoader.parse() calls isBinary() first to choose between the binary and ASCII parsers. isBinary() unconditionally reads a little-endian uint32 at offset 80 via DataView.getUint32(80, true) to compute the expected binary file size. This call is not guarded by a buffer-length check and throws

RangeError: Offset is outside the bounds of the DataView

for any STL whose total payload is shorter than 84 bytes (the binary STL header: 80 bytes + 4-byte face count).

Such files exist in the wild: minimal/empty ASCII solids such as

solid s
endsolid s

are only 19 bytes, and they are perfectly legal STL. Today the loader crashes on them with the RangeError above before the ASCII-vs-binary disambiguation runs at all.

Reproduction

import { STLLoader } from 'three-stdlib'

const ascii = 'solid s\nendsolid s\n' // 19 bytes, legal ASCII STL
const buf = new TextEncoder().encode(ascii).buffer

new STLLoader().parse(buf)
// -> RangeError: Offset is outside the bounds of the DataView

The fix

Return false from isBinary() when the buffer is shorter than the binary header (84 bytes). Short payloads then fall through to parseASCII() as they should.

Notes

  • The same bug exists upstream in three.js examples/jsm/loaders/STLLoader.js — happy to mirror this patch there as a follow-up.
  • After this patch the reproduction case above parses to an empty BufferGeometry, which is what an empty solid should produce.

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

STLLoader.parse() calls isBinary() first, which reads a little-endian
uint32 at offset 80 via DataView.getUint32(80, true) to compute the
expected binary file size. This call is unconditional and throws

    RangeError: Offset is outside the bounds of the DataView

for any STL whose total payload is shorter than 84 bytes (the binary
STL header: 80 bytes + 4-byte face count). Such files do exist in the
wild: minimal/empty ASCII solids such as

    solid s
    endsolid s

are only 19 bytes and crash the parser before the ASCII-vs-binary
disambiguation runs at all. A short ASCII STL is a perfectly legal STL.

Return false from isBinary() when the buffer is shorter than the
binary header so short payloads cleanly fall through to parseASCII().

The same bug exists in three.js's examples/jsm/loaders/STLLoader.js.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codesandbox-ci

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

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.

1 participant