You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GpBinaryHelpers.gpReadStringByteLength (in Gp3To5Importer) treats the length-hint byte as the actual byte count to read, then skips to a fixed-width boundary:
When the hint exceeds the field width — which happens in real-world Guitar Pro 5 files where a user typed a chord-comment string longer than the on-disk field (the editor allows it; the file stores the original length byte verbatim with the data truncated) — the read advances stringLength bytes, overshooting the field by stringLength - length. The remainder of the beat parse is then misaligned.
Concrete failure mode: misalignment lands inside readBend, which interprets garbage as a 4-byte pointCount, enters a tight loop reading 9 bytes per iteration, and burns the V8 heap.
Node: OOM-crash after 5–30 seconds.
Browser: tab deadlocks at 100% CPU and eventually crashes the renderer (taking down sibling tabs in the same Chromium process).
This is a practical denial-of-service vector against any page that runs AlphaTab on user-supplied .gp5 input.
Expected Behavior
The function should read a fixed-width field (length bytes) and decode up to min(stringLength, length) of those bytes — matching the way PyGuitarPro (readByteSizeString(count)) and TuxGuitar (readStringByte(size)) handle the same field. With this semantic, oversized length hints decode cleanly and the rest of the beat parse stays aligned.
Steps To Reproduce
Obtain a Guitar Pro 5 file with a chord-comment field where the length byte exceeds the field width. Reference fixture: test-data/guitarpro5/chord-name-overflow.gp5 (a published GP 5.10 file with stringLength=32 in a 22-byte field). Fixture is committed in PR fix(importer): cap chord name read at field width in GP3-5 binary parser #2669.
Run ScoreLoader.loadScoreFromBytes(bytes) in Node.
Observe Node OOM-crash after several seconds (V8 reports Reached heap limit Allocation failed).
Link to jsFiddle, CodePen, Project
N/A — fixture committed in PR #2669 (packages/alphatab/test-data/guitarpro5/chord-name-overflow.gp5).
Version and Environment
alphaTab: 1.9.0 (commit f8ef24f, current HEAD of `develop`)
Node.js: v22.14.0
OS: Ubuntu 22.04.3 LTS on WSL2 (kernel 6.6.87.2-microsoft-standard-WSL2)
The bug is on the importer side, so it surfaces on every platform that consumes the resulting Score — Web, Node.js, .NET, Android, iOS all affected equally. Reproducer environment above is just where I observed it.
Platform
Node.js
Anything else?
After-fix validation: the fixture's beat-by-beat byte position matches PyGuitarPro 1217/1217 beats. Fix proposed in PR #2669. Two related bugs from the same area (#2671, #2673) are tracked separately.
Is there an existing issue for this?
Current Behavior
GpBinaryHelpers.gpReadStringByteLength(inGp3To5Importer) treats the length-hint byte as the actual byte count to read, then skips to a fixed-width boundary:When the hint exceeds the field width — which happens in real-world Guitar Pro 5 files where a user typed a chord-comment string longer than the on-disk field (the editor allows it; the file stores the original length byte verbatim with the data truncated) — the read advances
stringLengthbytes, overshooting the field bystringLength - length. The remainder of the beat parse is then misaligned.Concrete failure mode: misalignment lands inside
readBend, which interprets garbage as a 4-bytepointCount, enters a tight loop reading 9 bytes per iteration, and burns the V8 heap.This is a practical denial-of-service vector against any page that runs AlphaTab on user-supplied
.gp5input.Expected Behavior
The function should read a fixed-width field (
lengthbytes) and decode up tomin(stringLength, length)of those bytes — matching the way PyGuitarPro (readByteSizeString(count)) and TuxGuitar (readStringByte(size)) handle the same field. With this semantic, oversized length hints decode cleanly and the rest of the beat parse stays aligned.Steps To Reproduce
test-data/guitarpro5/chord-name-overflow.gp5(a published GP 5.10 file withstringLength=32in a 22-byte field). Fixture is committed in PR fix(importer): cap chord name read at field width in GP3-5 binary parser #2669.ScoreLoader.loadScoreFromBytes(bytes)in Node.Reached heap limit Allocation failed).Link to jsFiddle, CodePen, Project
N/A — fixture committed in PR #2669 (
packages/alphatab/test-data/guitarpro5/chord-name-overflow.gp5).Version and Environment
The bug is on the importer side, so it surfaces on every platform that consumes the resulting
Score— Web, Node.js, .NET, Android, iOS all affected equally. Reproducer environment above is just where I observed it.Platform
Node.js
Anything else?
After-fix validation: the fixture's beat-by-beat byte position matches PyGuitarPro 1217/1217 beats. Fix proposed in PR #2669. Two related bugs from the same area (#2671, #2673) are tracked separately.