From 42190900cd0f9a4010c404cb20d2d5fc2667f64e Mon Sep 17 00:00:00 2001 From: Vanilagy <1696106+Vanilagy@users.noreply.github.com> Date: Fri, 5 Sep 2025 19:02:43 +0200 Subject: [PATCH] Disallow non-Latin-1 strings for WAVE metadata tags --- src/wave/wave-muxer.ts | 62 ++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/wave/wave-muxer.ts b/src/wave/wave-muxer.ts index c8126da..e1259f6 100644 --- a/src/wave/wave-muxer.ts +++ b/src/wave/wave-muxer.ts @@ -14,7 +14,7 @@ import { RiffWriter } from './riff-writer'; import { Writer } from '../writer'; import { EncodedPacket } from '../packet'; import { WavOutputFormat } from '../output-format'; -import { assert, assertNever, keyValueIterator } from '../misc'; +import { assert, assertNever, isIso88591Compatible, keyValueIterator } from '../misc'; import { MetadataTags, metadataTagsAreEmpty } from '../tags'; export class WaveMuxer extends Muxer { @@ -189,20 +189,46 @@ export class WaveMuxer extends Muxer { const writtenTags = new Set(); + const writeInfoTag = (tag: string, value: string) => { + if (!isIso88591Compatible(value)) { + // No Unicode supported here + console.warn(`Didn't write tag '${tag}' because '${value}' is not ISO 8859-1-compatible.`); + return; + } + + const size = value.length + 1; // +1 for null terminator + const bytes = new Uint8Array(size); + + for (let i = 0; i < value.length; i++) { + bytes[i] = value.charCodeAt(i); + } + + this.riffWriter.writeAscii(tag); + this.riffWriter.writeU32(size); + this.writer.write(bytes); + + // Add padding byte if size is odd + if (size & 1) { + this.writer.write(new Uint8Array(1)); + } + + writtenTags.add(tag); + }; + for (const { key, value } of keyValueIterator(metadata)) { switch (key) { case 'title': { - this.writeInfoTag('INAM', value); + writeInfoTag('INAM', value); writtenTags.add('INAM'); }; break; case 'artist': { - this.writeInfoTag('IART', value); + writeInfoTag('IART', value); writtenTags.add('IART'); }; break; case 'album': { - this.writeInfoTag('IPRD', value); + writeInfoTag('IPRD', value); writtenTags.add('IPRD'); }; break; @@ -211,22 +237,22 @@ export class WaveMuxer extends Muxer { ? `${value}/${metadata.tracksTotal}` : value.toString(); - this.writeInfoTag('ITRK', string); + writeInfoTag('ITRK', string); writtenTags.add('ITRK'); }; break; case 'genre': { - this.writeInfoTag('IGNR', value); + writeInfoTag('IGNR', value); writtenTags.add('IGNR'); }; break; case 'date': { - this.writeInfoTag('ICRD', value.toISOString().slice(0, 10)); + writeInfoTag('ICRD', value.toISOString().slice(0, 10)); writtenTags.add('ICRD'); }; break; case 'comment': { - this.writeInfoTag('ICMT', value); + writeInfoTag('ICMT', value); writtenTags.add('ICMT'); }; break; @@ -256,7 +282,7 @@ export class WaveMuxer extends Muxer { } if (typeof value === 'string') { - this.writeInfoTag(key, value); + writeInfoTag(key, value); } } } @@ -274,24 +300,6 @@ export class WaveMuxer extends Muxer { } } - private writeInfoTag(tag: string, value: string) { - const size = value.length + 1; // +1 for null terminator - const bytes = new Uint8Array(size); - - for (let i = 0; i < value.length; i++) { - bytes[i] = value.charCodeAt(i); - } - - this.riffWriter.writeAscii(tag); - this.riffWriter.writeU32(size); - this.writer.write(bytes); - - // Add padding byte if size is odd - if (size & 1) { - this.writer.write(new Uint8Array(1)); - } - } - async finalize() { const release = await this.mutex.acquire();