Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add strict type checking for Uint8Array/ArrayBuffer #5849

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc.js
Expand Up @@ -79,6 +79,9 @@ module.exports = {
},
overrides: [
{
parserOptions: {
project: ['./tsconfig.json'],
},
files: ['*.ts'],
rules: {
'no-unused-vars': 0,
Expand Down
2 changes: 1 addition & 1 deletion src/controller/audio-stream-controller.ts
Expand Up @@ -205,7 +205,7 @@ class AudioStreamController
this.waitingData = null;
this.waitingVideoCC = -1;
this.state = State.FRAG_LOADING;
const payload = cache.flush();
const payload = cache.flush().buffer;
const data: FragLoadedData = {
frag,
part,
Expand Down
14 changes: 8 additions & 6 deletions src/controller/eme-controller.ts
Expand Up @@ -347,7 +347,7 @@ class EMEController implements ComponentAPI {
this.generateRequestWithPreferredKeySession(
keySessionContext,
scheme,
decryptdata.pssh,
decryptdata.pssh.buffer,
'expired',
);
} else {
Expand Down Expand Up @@ -444,10 +444,13 @@ class EMEController implements ComponentAPI {
decryptdata,
});
const scheme = 'cenc';
const initData = decryptdata.pssh
? decryptdata.pssh?.buffer
: null;
return this.generateRequestWithPreferredKeySession(
keySessionContext,
scheme,
decryptdata.pssh,
initData,
'playlist-key',
);
});
Expand Down Expand Up @@ -541,7 +544,7 @@ class EMEController implements ComponentAPI {
const json = bin2str(new Uint8Array(initData));
try {
const sinf = base64Decode(JSON.parse(json).sinf);
const tenc = parseSinf(new Uint8Array(sinf));
const tenc = parseSinf(sinf);
if (!tenc) {
return;
}
Expand Down Expand Up @@ -692,9 +695,8 @@ class EMEController implements ComponentAPI {
);
}
initDataType = mappedInitData.initDataType;
initData = context.decryptdata.pssh = mappedInitData.initData
? new Uint8Array(mappedInitData.initData)
: null;
initData = mappedInitData.initData ? mappedInitData.initData : null;
context.decryptdata.pssh = initData ? new Uint8Array(initData) : null;
} catch (error) {
this.warn(error.message);
if (this.hls?.config.debug) {
Expand Down
2 changes: 1 addition & 1 deletion src/controller/timeline-controller.ts
Expand Up @@ -560,7 +560,7 @@ export class TimelineController implements ComponentAPI {
const hls = this.hls;
// Parse the WebVTT file contents.
const payloadWebVTT = frag.initSegment?.data
? appendUint8Array(frag.initSegment.data, new Uint8Array(payload))
? appendUint8Array(frag.initSegment.data, new Uint8Array(payload)).buffer
: payload;
parseWebVTT(
payloadWebVTT,
Expand Down
3 changes: 2 additions & 1 deletion src/crypt/decrypter.ts
Expand Up @@ -85,7 +85,8 @@ export default class Decrypter {
): Promise<ArrayBuffer> {
if (this.useSoftware) {
return new Promise((resolve, reject) => {
this.softwareDecrypt(new Uint8Array(data), key, iv);
const dataView = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
this.softwareDecrypt(dataView, key, iv);
const decryptResult = this.flush();
if (decryptResult) {
resolve(decryptResult.buffer);
Expand Down
2 changes: 1 addition & 1 deletion src/demux/chunk-cache.ts
Expand Up @@ -9,7 +9,7 @@ export default class ChunkCache {

flush(): Uint8Array {
const { chunks, dataLength } = this;
let result;
let result: Uint8Array;
if (!chunks.length) {
return new Uint8Array(0);
} else if (chunks.length === 1) {
Expand Down
5 changes: 3 additions & 2 deletions src/demux/transmuxer.ts
Expand Up @@ -127,7 +127,8 @@ export default class Transmuxer {
// For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress
const loadingParts = chunkMeta.part > -1;
if (loadingParts) {
decryptedData = decrypter.flush();
const data = decrypter.flush();
decryptedData = data ? data.buffer : data;
}
if (!decryptedData) {
stats.executeEnd = now();
Expand Down Expand Up @@ -231,7 +232,7 @@ export default class Transmuxer {
if (decryptedData) {
// Push always returns a TransmuxerResult if decryptdata is null
transmuxResults.push(
this.push(decryptedData, null, chunkMeta) as TransmuxerResult,
this.push(decryptedData.buffer, null, chunkMeta) as TransmuxerResult,
);
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/types/buffer.ts
@@ -1,3 +1,12 @@
declare global {
interface ArrayBuffer {
' buffer_kind'?: 'array';
}
interface Uint8Array {
' buffer_kind'?: 'uint8';
}
}

export type SourceBufferName = 'video' | 'audio' | 'audiovideo';

// eslint-disable-next-line no-restricted-globals
Expand Down
6 changes: 3 additions & 3 deletions src/utils/fetch-loader.ts
Expand Up @@ -233,7 +233,7 @@ class FetchLoader implements Loader<LoaderContext> {
.then((data) => {
if (data.done) {
if (chunkCache.dataLength) {
onProgress(stats, context, chunkCache.flush(), response);
onProgress(stats, context, chunkCache.flush().buffer, response);
}

return Promise.resolve(new ArrayBuffer(0));
Expand All @@ -247,12 +247,12 @@ class FetchLoader implements Loader<LoaderContext> {
chunkCache.push(chunk);
if (chunkCache.dataLength >= highWaterMark) {
// flush in order to join the typed arrays
onProgress(stats, context, chunkCache.flush(), response);
onProgress(stats, context, chunkCache.flush().buffer, response);
}
} else {
// If there's nothing cached already, and the chache is large enough
// just emit the progress event
onProgress(stats, context, chunk, response);
onProgress(stats, context, chunk.buffer, response);
}
return pump();
})
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/demuxer/transmuxer.ts
Expand Up @@ -218,7 +218,7 @@ describe('TransmuxerInterface tests', function () {
newFrag.level = 2;
newFrag.start = 1000;
const part = null;
const data = new Uint8Array(new ArrayBuffer(8));
const data = new ArrayBuffer(8);
const initSegmentData = new Uint8Array(0);
const audioCodec = '';
const videoCodec = '';
Expand Down