Skip to content

fix(importer): reject malformed GPX containers instead of looping forever - #2991

Merged
Danielku15 merged 1 commit into
developfrom
feature/issue-2967
Oct 29, 2026
Merged

Danielku15 merged 1 commit into
developfrom
feature/issue-2967

Conversation

@Danielku15

@Danielku15 Danielku15 commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Note

AI-authored disclosure (alphatab-ai-authored-v1)

Portions of this content were authored by an AI agent. The agent has read
AGENTS.md and the human submitter accepts responsibility for
compliance with the rules in that document.

Issues

Fixes #2967

Proposed changes

A GPX (BCFS) file entry whose data sectors lie before the entry made GpxFileSystem jump back to the entry and read it again, forever, allocating a new buffer each pass. Because import is synchronous, a 12 KB crafted file froze the caller and eventually ran it out of memory. The same applied to the .NET and Android builds.

The fix is in the container layer:

  • The sector scan only moves forward (the next entry follows the furthest data sector).
  • Sector pointers that are negative or point past the container, unterminated sector lists, truncated entry headers and file sizes outside the container are rejected with UnsupportedFormatError. In C#/Kotlin these previously surfaced as index errors; in JS a negative offset silently read from the end of the buffer.
  • The decompressed BCFZ size respects importer.maxDecodingBufferSize (OverflowError, as for the other binary importers since 1.9.0 hardening: fix release-review findings across rendering, importers, player and packaging #2990), and a truncated compressed stream is rejected instead of failing with a RangeError.
  • GpifParser rejects a score.gpif without root element as unsupported instead of failing later with a TypeError.

All 37 .gpx files in test-data load byte-identically to before; none has a backward or out-of-range sector. New in-memory tests cover each rejected case, plus the issue's exact bytes through ScoreLoader.

Checklist

  • I consent that this change becomes part of alphaTab under its current or any future open source license
  • This PR is linked to an accepted issue (see above)
  • Changes are implemented
  • New tests were added
  • I have read AGENTS.md if an AI helped draft any part of this PR

AI authorship disclosure

  • No AI agent authored any part of this PR (description, code, tests, or commit messages)
  • An AI agent contributed to this PR. The AI-authored disclosure block
    (alphatab-ai-authored-v1) is present at the top of this body, and I have
    personally reviewed every change and can explain each one

Further details

  • This is a breaking change
  • This change will require update of the documentation/website

…ever

A file entry whose data sectors lie before the entry made the sector scan
revisit the same entry endlessly while allocating memory. The scan now only
moves forward, sector pointers and file sizes are validated against the
container, the decompressed size respects maxDecodingBufferSize and a
score.gpif without root element is rejected as unsupported.

Fixes #2967
@Danielku15
Danielku15 merged commit d479481 into develop Oct 29, 2026
8 checks passed
@Danielku15
Danielku15 deleted the feature/issue-2967 branch October 29, 2026 18:14
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.

Node.js import of a malformed GPX file does not return

1 participant