Skip to content

Commit

Permalink
Throw ParserError on duplicate attribute list keys
Browse files Browse the repository at this point in the history
  • Loading branch information
kanongil committed Jan 1, 2025
1 parent 73cbfb4 commit fb043b7
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 10 deletions.
24 changes: 15 additions & 9 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export class M3U8Parser {

if (this.lineNo === 1) {
if (line !== '#EXTM3U') {
throw new ParserError('Missing required #EXTM3U header', line, this.lineNo);
throw new ParserError('Missing required #EXTM3U header', { line, line_no: this.lineNo });
}

return;
Expand All @@ -196,8 +196,13 @@ export class M3U8Parser {
const cmd = matches[1];
const arg = matches[2].length > 1 ? matches[2].slice(1) : null;

if (!this._parseExt(cmd, arg)) {
return this.debug('ignoring unknown #EXT:' + cmd, this.lineNo);
try {
if (!this._parseExt(cmd, arg)) {
return this.debug('ignoring unknown #EXT:' + cmd, this.lineNo);
}
}
catch (err) {
throw new ParserError('Ext parsing failed', { line, line_no: this.lineNo, cause: err });
}
}
else if (state.m3u8.master) {
Expand All @@ -207,7 +212,7 @@ export class M3U8Parser {
}
else {
if (!('duration' in state.meta)) {
throw new ParserError('Missing #EXTINF before media file URI', line, this.lineNo);
throw new ParserError('Missing #EXTINF before media file URI', { line, line_no: this.lineNo });
}

(state.m3u8.segments ??= []).push(new MediaSegment(line, state.meta, state.m3u8.version));
Expand Down Expand Up @@ -239,7 +244,7 @@ export class M3U8Parser {
state.meta.title = title.join(',');

if (state.meta.duration <= 0) {
throw new ParserError('Invalid duration', '#EXTINF:' + arg, this.lineNo);
throw new Error('Invalid duration');
}

return true;
Expand Down Expand Up @@ -267,15 +272,16 @@ export class ParserError extends Error {

readonly name = 'ParserError';

cause: any;
line: string;
lineNumber: number;

// eslint-disable-next-line @typescript-eslint/ban-types
constructor(msg: string, line?: string, line_no?: number, constr?: Function) {
constructor(msg: string, options?: { line?: string; line_no?: number; cause?: unknown }) {

super(msg ?? 'Error');
super(msg ?? 'Error', options?.cause ? { cause: options.cause } : undefined);

this.line = line ?? '';
this.lineNumber = line_no ?? -1;
this.line = options?.line ?? '';
this.lineNumber = options?.line_no ?? -1;
}
}
2 changes: 1 addition & 1 deletion src/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"composite": true,
"allowSyntheticDefaultImports": true,
"target": "ES2020",
"lib": [ "ES2020" ],
"lib": [ "ES2020", "ES2022.Error" ],
"module": "Node16",
"moduleResolution": "node16",
"isolatedModules": true,
Expand Down
6 changes: 6 additions & 0 deletions test/m3u8parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ describe('M3U8Parse', () => {
const stream = Fs.createReadStream(Path.join(fixtureDir, 'empty.m3u8'));
await expect(M3U8Parse(stream)).to.reject(ParserError);
});

it('throws a ParserError for duplicate attribute list keys', () => {

const err = expect(() => M3U8Parse('#EXTM3U\n#EXT-X-SKIP:ABC=1,ABC=2')).to.throw(ParserError, 'Ext parsing failed');
expect(err.cause).to.be.an.error('Duplicate attribute key: abc');
});
});

describe('M3U8Playlist', () => {
Expand Down

0 comments on commit fb043b7

Please sign in to comment.