diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock new file mode 100644 index 000000000..a17d52712 --- /dev/null +++ b/.claude/scheduled_tasks.lock @@ -0,0 +1 @@ +{"sessionId":"ddc5edd3-51f2-4690-ada7-4273b04ae0c6","pid":2972655,"procStart":"43393170","acquiredAt":1778849010756} \ No newline at end of file diff --git a/packages/alphatab/src/importer/GpifParser.ts b/packages/alphatab/src/importer/GpifParser.ts index b7bd46907..f5954de2c 100644 --- a/packages/alphatab/src/importer/GpifParser.ts +++ b/packages/alphatab/src/importer/GpifParser.ts @@ -2892,6 +2892,10 @@ export class GpifParser { // build masterbar automations for (const [barNumber, automations] of this._masterTrackAutomations) { + if (barNumber < 0 || barNumber >= this.score.masterBars.length) { + // automation references a bar that is not in the score's masterBars list + continue; + } const masterBar: MasterBar = this.score.masterBars[barNumber]; for (let i: number = 0, j: number = automations.length; i < j; i++) { const automation: Automation = automations[i]; diff --git a/packages/alphatab/test-data/guitarpro8/orphan-tempo-automation.gp b/packages/alphatab/test-data/guitarpro8/orphan-tempo-automation.gp new file mode 100755 index 000000000..76543653b Binary files /dev/null and b/packages/alphatab/test-data/guitarpro8/orphan-tempo-automation.gp differ diff --git a/packages/alphatab/test/importer/Gp8Importer.test.ts b/packages/alphatab/test/importer/Gp8Importer.test.ts index 3b6ce94bd..15b8d7c0f 100644 --- a/packages/alphatab/test/importer/Gp8Importer.test.ts +++ b/packages/alphatab/test/importer/Gp8Importer.test.ts @@ -506,4 +506,14 @@ describe('Gp8ImporterTest', () => { const score = reader.readScore(); GpImporterTestHelper.checkHarmonics(score); }); + + it('orphan-tempo-automation', async () => { + // GPIF tempo automations can reference bar indices that are not + // present in the score's masterBars list (e.g. off-by-one or after + // bar deletion). Should be skipped instead of null-dereferencing. + const reader = await prepareImporterWithFile('guitarpro8/orphan-tempo-automation.gp'); + const score = reader.readScore(); + expect(score.masterBars.length).toBe(100); + expect(score.tracks.length).toBe(3); + }); }); diff --git a/packages/tooling/src/vitest.ts b/packages/tooling/src/vitest.ts index ba60e6ba7..4d2130e3e 100644 --- a/packages/tooling/src/vitest.ts +++ b/packages/tooling/src/vitest.ts @@ -28,7 +28,7 @@ export function defineVitestConfig(options: VitestPackageOptions = {}) { plugins: [tsconfigPaths()], test: { include: ['test/**/*.test.ts'], - testTimeout: options.testTimeout ?? 10000, + testTimeout: options.testTimeout ?? 30000, setupFiles: options.setupFiles, passWithNoTests: true, chaiConfig: options.truncateThreshold !== undefined