music-metadata: uncatchable process crash parsing a crafted `.dsf` (residual of GHSA-v6c2-xwv6-8xf7)
## Summary `DsfParser.parseChunks` skips an unrecognised chunk's payload with an **un-awaited** call: ```js this.tokenizer.ignore(Number(chunkHeader.size) - ChunkHeader.len); // lib/dsf/DsfParser.js:51 — no await ``` `ChunkHeader.len` is 12. A crafted `.dsf` chunk with `id != 'fmt '` and `size` in `0..11` makes the argument negative; strtok3 (≥ 10.3.5) throws `RangeError` on a negative `ignore`. Because the call is fire-and-forget, the rejection is **detached from the `parseBuffer()` promise chain** → unhandled rejection → Node's default (≥ 15) **crashes the process** — **after** `parseBuffer()` already resolved, so a caller's `try/catch` catches nothing and is still taken down. Residual of GHSA-v6c2-xwv6-8xf7: the ASF site was fixed in 11.12.3 (size validation) and strtok3 now throws on negative `ignore`; the DSF site was never validated, and its missing `await` escalates that throw into an **uncatchable** crash. ## Root cause (`lib/dsf/DsfParser.js:34-56`) ```js while (bytesRemaining >= ChunkHeader.len) { // ChunkHeader.len = 12 const chunkHeader = await this.tokenizer.readToken(ChunkHeader); // { id, size } switch (chunkHeader.id) { case 'fmt ': { ...; return; } default: this.tokenizer.ignore(Number(chunkHeader.size) - ChunkHeader.len); break; // size<12 -> negative, no await } bytesRemaining -= chunkHeader.size; } ``` strtok3 `AbstractTokenizer.ignore` (L78-79): `if (length < 0) throw new RangeError('ignore length must be ≥ 0 bytes');` ## Steps to reproduce `repro/` — pub
- Products
- music-metadata
- Affected versions
- Not specified
- Fixed versions
- 11.15.0
- CVEs
- CVE-2026-107392
- Confirmed fixed CVEs
- Not specified
- Updated in this feed
- 28 Oct 2026, 10:04 UTC · Revision 1
Source evidence
music-metadata: uncatchable process crash parsing a crafted `.dsf` (residual of GHSA-v6c2-xwv6-8xf7)
core-osv · Original sourcePublished 8 Oct 2026, 19:40 UTC
## Summary `DsfParser.parseChunks` skips an unrecognised chunk's payload with an **un-awaited** call: ```js this.tokenizer.ignore(Number(chunkHeader.size) - ChunkHeader.len); // lib/dsf/DsfParser.js:51 — no await ``` `ChunkHeader.len` is 12. A crafted `.dsf` chunk with `id != 'fmt '` and `size` in `0..11` makes the argument negative; strtok3 (≥ 10.3.5) throws `RangeError` on a negative `ignore`. Because the call is fire-and-forget, the rejection is **detached from the `parseBuffer()` promise chain** → unhandled rejection → Node's default (≥ 15) **crashes the process** — **after** `parseBuffer()` already resolved, so a caller's `try/catch` catches nothing and is still taken down. Residual of GHSA-v6c2-xwv6-8xf7: the ASF site was fixed in 11.12.3 (size validation) and strtok3 now throws on negative `ignore`; the DSF site was never validated, and its missing `await` escalates that throw into an **uncatchable** crash. ## Root cause (`lib/dsf/DsfParser.js:34-56`) ```js while (bytesRemaining >= ChunkHeader.len) { // ChunkHeader.len = 12 const chunkHeader = await this.tokenizer.readToken(ChunkHeader); // { id, size } switch (chunkHeader.id) { case 'fmt ': { ...; return; } default: this.tokenizer.ignore(Number(chunkHeader.size) - ChunkHeader.len); break; // size<12 -> negative, no await } bytesRemaining -= chunkHeader.size; } ``` strtok3 `AbstractTokenizer.ignore` (L78-79): `if (length < 0) throw new RangeError('ignore length must be ≥ 0 bytes');` ## Steps to reproduce `repro/` — pub
osv:GHSA-8j4c-6x6g-rq3j
music-metadata
Fixed versions: 11.15.0
Complete source record
{
"id": "1dd7550116567d4bcb3db340208616baf66cacae7b46d7ab6568747f3f5207e6",
"url": "https://osv.dev/vulnerability/GHSA-8j4c-6x6g-rq3j",
"method": "structured",
"payload": {
"kind": "advisory",
"title": "music-metadata: uncatchable process crash parsing a crafted `.dsf` (residual of GHSA-v6c2-xwv6-8xf7)",
"summary": "## Summary `DsfParser.parseChunks` skips an unrecognised chunk's payload with an **un-awaited** call: ```js this.tokenizer.ignore(Number(chunkHeader.size) - ChunkHeader.len); // lib/dsf/DsfParser.js:51 — no await ``` `ChunkHeader.len` is 12. A crafted `.dsf` chunk with `id != 'fmt '` and `size` in `0..11` makes the argument negative; strtok3 (≥ 10.3.5) throws `RangeError` on a negative `ignore`. Because the call is fire-and-forget, the rejection is **detached from the `parseBuffer()` promise chain** → unhandled rejection → Node's default (≥ 15) **crashes the process** — **after** `parseBuffer()` already resolved, so a caller's `try/catch` catches nothing and is still taken down. Residual of GHSA-v6c2-xwv6-8xf7: the ASF site was fixed in 11.12.3 (size validation) and strtok3 now throws on negative `ignore`; the DSF site was never validated, and its missing `await` escalates that throw into an **uncatchable** crash. ## Root cause (`lib/dsf/DsfParser.js:34-56`) ```js while (bytesRemaining >= ChunkHeader.len) { // ChunkHeader.len = 12 const chunkHeader = await this.tokenizer.readToken(ChunkHeader); // { id, size } switch (chunkHeader.id) { case 'fmt ': { ...; return; } default: this.tokenizer.ignore(Number(chunkHeader.size) - ChunkHeader.len); break; // size<12 -> negative, no await } bytesRemaining -= chunkHeader.size; } ``` strtok3 `AbstractTokenizer.ignore` (L78-79): `if (length < 0) throw new RangeError('ignore length must be ≥ 0 bytes');` ## Steps to reproduce `repro/` — pub",
"evidence": "osv:GHSA-8j4c-6x6g-rq3j",
"products": [
{
"name": {
"value": "music-metadata",
"evidence": "/affected/0/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "11.15.0",
"evidence": "/affected/0/ranges"
}
],
"affected_versions": []
}
],
"severity": "medium",
"structured": {
"id": "GHSA-8j4c-6x6g-rq3j",
"aliases": [
"CVE-2026-107392",
"GHSA-8j4c-6x6g-rq3j"
],
"metrics": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
}
],
"affected": [
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "0"
},
{
"fixed": "11.15.0"
}
]
}
],
"package": {
"name": "music-metadata",
"purl": "pkg:npm/music-metadata",
"ecosystem": "npm"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-8j4c-6x6g-rq3j/GHSA-8j4c-6x6g-rq3j.json",
"last_known_affected_version_range": "<= 11.14.0"
}
}
],
"modified": "2026-10-08T20:00:05.860263177Z",
"provider": "osv",
"references": [
"https://github.com/Borewit/music-metadata/security/advisories/GHSA-8j4c-6x6g-rq3j",
"https://github.com/Borewit/music-metadata/pull/2700",
"https://github.com/Borewit/music-metadata/commit/e7fc27a96e789d41ece41fdac590fc7618274a41",
"https://github.com/Borewit/music-metadata",
"https://github.com/Borewit/music-metadata/releases/tag/v11.15.0"
],
"provider_metadata": {
"cwe_ids": [
"CWE-248",
"CWE-400"
],
"severity": "MODERATE",
"github_reviewed": true,
"nvd_published_at": null,
"github_reviewed_at": "2026-10-08T19:40:45Z"
}
},
"related_cves": [
{
"value": "CVE-2026-107392",
"evidence": "/aliases"
}
],
"security_relevant": true,
"severity_evidence": "/severity/0/score"
},
"source_id": "core-osv",
"document_id": 104571,
"published_at": "2026-10-08T19:40:45+00:00"
}