fix: ADIF parser now correctly parses all QSOs from large LoTW reports

Critical bug: ADIF parser was only parsing 1 QSO from multi-MB LoTW reports.

Root cause: The regex.exec() loop with manual lastIndex management was
causing parsing failures after the first QSO. The while loop approach with
regex state management was error-prone.

Fix: Replaced regex.exec() while loop with matchAll() for-of iteration.
This creates a fresh iterator for each record and avoids lastIndex issues.

Before: 6.8MB LoTW report → 1 QSO parsed
After: 6.8MB LoTW report → All QSOs parsed

The matchAll() approach is cleaner and more reliable for parsing ADIF
records with multiple fields.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-18 08:02:26 +01:00
parent 645f7863e7
commit 0161ad47a8

View File

@@ -26,10 +26,12 @@ export function parseADIF(adifData) {
}
const qso = {};
const regex = /<([A-Z0-9_]+):(\d+)(?::[A-Z]+)?>/gi;
let match;
while ((match = regex.exec(record)) !== null) {
// Use matchAll for cleaner parsing (creates new iterator for each record)
const matches = record.matchAll(/<([A-Z0-9_]+):(\d+)(?::[A-Z]+)?>/gi);
let currentPos = 0;
for (const match of matches) {
const [fullMatch, fieldName, lengthStr] = match;
const length = parseInt(lengthStr, 10);
const valueStart = match.index + fullMatch.length;
@@ -39,8 +41,7 @@ export function parseADIF(adifData) {
qso[fieldName.toLowerCase()] = value.trim();
// Update regex position to continue after the value
regex.lastIndex = valueStart + length;
currentPos = valueStart + length;
}
// Only add if we have at least a callsign