Skip to content

Commit 2e5676a

Browse files
committed
feat(audio-decoder): add validation for sampleRate and numberOfChannels
Add positive integer validation for AudioDecoder.configure() to comply with W3C WebCodecs spec requirement that unsigned long values must be positive integers. Validation: - sampleRate must be > 0 (throws TypeError if zero or negative) - numberOfChannels must be > 0 (throws TypeError if zero or negative) Tests: - Add edge case tests for zero/negative values - Add tests for missing required fields - Add test for whitespace-only codec string Aligns with W3C spec: unsigned long requires positive integer values.
1 parent 4b19d34 commit 2e5676a

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

lib/audio-decoder.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ export class AudioDecoder extends CodecBase {
7777
throw new TypeError('config.codec cannot be empty');
7878
}
7979

80+
// Validate positive values (W3C spec: unsigned long requires positive integer)
81+
is.assertPositiveInteger(config.sampleRate, 'config.sampleRate');
82+
is.assertPositiveInteger(config.numberOfChannels, 'config.numberOfChannels');
83+
8084
this._needsKeyFrame = true;
8185
// Configure synchronously to set state immediately per W3C spec
8286
this._native.configure(config);

test/unit/audio-decoder-methods.test.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,75 @@ describe('AudioDecoder Methods: 3.5', () => {
115115
);
116116
decoder.close();
117117
});
118+
119+
it('should throw TypeError for whitespace-only codec', () => {
120+
const decoder = createDecoder();
121+
assert.throws(
122+
() => decoder.configure({ codec: ' ', sampleRate: 48000, numberOfChannels: 2 }),
123+
TypeError,
124+
);
125+
decoder.close();
126+
});
127+
128+
it('should throw TypeError for missing sampleRate', () => {
129+
const decoder = createDecoder();
130+
assert.throws(
131+
() => {
132+
// @ts-expect-error Testing invalid input
133+
decoder.configure({ codec: 'opus', numberOfChannels: 2 });
134+
},
135+
TypeError,
136+
);
137+
decoder.close();
138+
});
139+
140+
it('should throw TypeError for missing numberOfChannels', () => {
141+
const decoder = createDecoder();
142+
assert.throws(
143+
() => {
144+
// @ts-expect-error Testing invalid input
145+
decoder.configure({ codec: 'opus', sampleRate: 48000 });
146+
},
147+
TypeError,
148+
);
149+
decoder.close();
150+
});
151+
152+
it('should throw TypeError for zero sampleRate', () => {
153+
const decoder = createDecoder();
154+
assert.throws(
155+
() => decoder.configure({ codec: 'opus', sampleRate: 0, numberOfChannels: 2 }),
156+
TypeError,
157+
);
158+
decoder.close();
159+
});
160+
161+
it('should throw TypeError for negative sampleRate', () => {
162+
const decoder = createDecoder();
163+
assert.throws(
164+
() => decoder.configure({ codec: 'opus', sampleRate: -48000, numberOfChannels: 2 }),
165+
TypeError,
166+
);
167+
decoder.close();
168+
});
169+
170+
it('should throw TypeError for zero numberOfChannels', () => {
171+
const decoder = createDecoder();
172+
assert.throws(
173+
() => decoder.configure({ codec: 'opus', sampleRate: 48000, numberOfChannels: 0 }),
174+
TypeError,
175+
);
176+
decoder.close();
177+
});
178+
179+
it('should throw TypeError for negative numberOfChannels', () => {
180+
const decoder = createDecoder();
181+
assert.throws(
182+
() => decoder.configure({ codec: 'opus', sampleRate: 48000, numberOfChannels: -2 }),
183+
TypeError,
184+
);
185+
decoder.close();
186+
});
118187
});
119188
});
120189

0 commit comments

Comments
 (0)