Skip to content

fix(importer): skip GPIF tempo automations on missing master bars#2668

Open
kaizenman wants to merge 2 commits intoCoderLine:developfrom
kaizenman:fix/gpif-orphan-tempo-automations
Open

fix(importer): skip GPIF tempo automations on missing master bars#2668
kaizenman wants to merge 2 commits intoCoderLine:developfrom
kaizenman:fix/gpif-orphan-tempo-automations

Conversation

@kaizenman
Copy link
Copy Markdown

@kaizenman kaizenman commented Apr 24, 2026

Issues

Fixes #2675

Proposed changes

GpifParser._buildModel iterates _masterTrackAutomations and dereferences score.masterBars[barNumber] without checking that the index is in range:

const masterBar: MasterBar = this.score.masterBars[barNumber];
// masterBar can be undefined when barNumber >= masterBars.length

On real-world Guitar Pro 7/8 files where the score has been edited (e.g. bars removed) without removing the corresponding <MasterTrack> automations, or in files with off-by-one bar indices, this throws:

TypeError: Cannot read properties of undefined (reading 'tempoAutomations')
    at GpifParser._buildModel (GpifParser.ts:2900)
    at GpifParser.parseXml (GpifParser.ts:176)
    at Gp7To8Importer.readScore (Gp7To8Importer.ts:75)

Reproducer

test-data/guitarpro8/orphan-tempo-automation.gp — a published Guitar Pro 8 file with 100 master bars and tempo automations targeting bars [0, 91-95, 97-100]. The automation at bar 100 is one past the score's last bar (off-by-one).

Fix

Skip the automation if the master bar is absent — matches Guitar Pro desktop behavior (silently ignores orphan automations and renders the score normally):

const masterBar: MasterBar | undefined = this.score.masterBars[barNumber];
if (!masterBar) {
    // automation references a bar that is not in the score's masterBars list
    continue;
}

Tests

Gp8ImporterTest > orphan-tempo-automation — loads the fixture and asserts masterBars.length === 100, tracks.length === 3. Without the fix this test throws the TypeError above.

All 27 GP8 importer tests pass.

Note

One of three independent fixes in the same area. The others address distinct root causes:

Checklist

  • I consent that this change becomes part of alphaTab under it's current or any future open source license
  • Changes are implemented
  • New tests were added

Further details

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

GpifParser._buildModel iterated _masterTrackAutomations and dereferenced
score.masterBars[barNumber] without checking that the index was within
range. Real-world GP7/8 files (off-by-one indexing, scores edited to
fewer bars) reference bar numbers past the masterBars list, producing:

  TypeError: Cannot read properties of undefined (reading 'tempoAutomations')

Skip the automation if the master bar is absent. The fixture
test-data/guitarpro8/orphan-tempo-automation.gp has 100 master bars and
a tempo automation targeting bar 100 (off-by-one) that previously
crashed the importer.
@Danielku15
Copy link
Copy Markdown
Member

Thanks for the fixes, can you open counterpart bug reports following the template so we have proper tracking of these items? Also: the issue and PR templates are not optional, please be sure to update your description accordingly.

1 similar comment
@Danielku15
Copy link
Copy Markdown
Member

Thanks for the fixes, can you open counterpart bug reports following the template so we have proper tracking of these items? Also: the issue and PR templates are not optional, please be sure to update your description accordingly.

@kaizenman
Copy link
Copy Markdown
Author

Thanks for the pointer. I've opened bug reports — #2671, #2672, #2673 (one per PR) plus #2674 to track the follow-up scope from PR #2670 — and updated all three PR descriptions to follow the template.

// build masterbar automations
for (const [barNumber, automations] of this._masterTrackAutomations) {
const masterBar: MasterBar = this.score.masterBars[barNumber];
const masterBar: MasterBar | undefined = this.score.masterBars[barNumber];
Copy link
Copy Markdown
Member

@Danielku15 Danielku15 Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not C# and Kotlin transpilation compatible. Add a custom out-of-bounds check instead of relying on undefined returns.

kaizenman added a commit to kaizenman/alphaTab that referenced this pull request Apr 28, 2026
The previous masterBar lookup used `score.masterBars[barNumber]` with
an `| undefined` type and an `if (!masterBar)` guard. That relies on
JS array out-of-bounds returning undefined — not C# / Kotlin
transpilation compatible, since the indexed access there throws
IndexOutOfRangeException / IndexOutOfBoundsException before the
undefined-check has a chance to run.

Replace with an explicit `barNumber < 0 || barNumber >= length` guard
before the access, matching the idiom already used 9 lines above for
sustain-pedal markers (GpifParser.ts) and in Gp3To5Importer.ts:508.

Addresses review feedback from @Danielku15 on PR CoderLine#2668.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous masterBar lookup used `score.masterBars[barNumber]` with
an `| undefined` type and an `if (!masterBar)` guard. That relies on
JS array out-of-bounds returning undefined — not C# / Kotlin
transpilation compatible, since the indexed access there throws
IndexOutOfRangeException / IndexOutOfBoundsException before the
undefined-check has a chance to run.

Replace with an explicit `barNumber < 0 || barNumber >= length` guard
before the access, matching the idiom already used 9 lines above for
sustain-pedal markers (GpifParser.ts) and in Gp3To5Importer.ts:508.

Addresses review feedback from @Danielku15 on PR CoderLine#2668.
@kaizenman kaizenman force-pushed the fix/gpif-orphan-tempo-automations branch from 5036de7 to 2206561 Compare April 28, 2026 11:38
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.

GpifParser crashes on orphan tempo automations referencing missing master bars

2 participants