mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 10:53:50 +02:00
fix
This commit is contained in:
+3
-2
@@ -154,10 +154,11 @@ export class MatroskaInputFormat extends InputFormat {
|
||||
return false;
|
||||
}
|
||||
|
||||
const dataSize = readElementSize(headerSlice);
|
||||
if (dataSize === null) {
|
||||
const dataSizeResult = readElementSize(headerSlice);
|
||||
if (dataSizeResult === null || dataSizeResult.size === null) {
|
||||
return false; // Miss me with that shit
|
||||
}
|
||||
const dataSize = dataSizeResult.size;
|
||||
|
||||
let dataSlice = input._reader.requestSlice(headerSlice.filePos, dataSize);
|
||||
if (dataSlice instanceof Promise) dataSlice = await dataSlice;
|
||||
|
||||
+81
-27
@@ -470,6 +470,11 @@ export const MIN_HEADER_SIZE = 2; // 1-byte ID and 1-byte size
|
||||
export const MAX_HEADER_SIZE = 2 * MAX_VAR_INT_SIZE; // 8-byte ID and 8-byte size
|
||||
|
||||
export const readVarIntSize = (slice: FileSlice) => {
|
||||
// Check if we have at least one byte to read
|
||||
if (slice.remainingLength < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const firstByte = readU8(slice);
|
||||
slice.skip(-1);
|
||||
|
||||
@@ -484,10 +489,20 @@ export const readVarIntSize = (slice: FileSlice) => {
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
// Check if we have enough bytes to read the full varint
|
||||
if (slice.remainingLength < width) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return width;
|
||||
};
|
||||
|
||||
export const readVarInt = (slice: FileSlice) => {
|
||||
// Check if we have at least one byte
|
||||
if (slice.remainingLength < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Read the first byte to determine the width of the variable-length integer
|
||||
const firstByte = readU8(slice);
|
||||
|
||||
@@ -503,6 +518,13 @@ export const readVarInt = (slice: FileSlice) => {
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
// Check if we have enough bytes remaining for the full varint
|
||||
if (slice.remainingLength < width - 1) {
|
||||
// Not enough bytes, rewind and return null
|
||||
slice.skip(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
// First byte's value needs the marker bit cleared
|
||||
let value = firstByte & (mask - 1);
|
||||
|
||||
@@ -567,37 +589,69 @@ export const readElementId = (slice: FileSlice) => {
|
||||
return id;
|
||||
};
|
||||
|
||||
export const readElementSize = (slice: FileSlice) => {
|
||||
let size: number | null = readU8(slice);
|
||||
|
||||
if (size === 0xff) {
|
||||
size = null;
|
||||
} else {
|
||||
slice.skip(-1);
|
||||
size = readVarInt(slice);
|
||||
|
||||
// In some (livestreamed) files, this is the value of the size field. While this technically is just a very
|
||||
// large number, it is intended to behave like the reserved size 0xFF, meaning the size is undefined. We
|
||||
// catch the number here. Note that it cannot be perfectly represented as a double, but the comparison works
|
||||
// nonetheless.
|
||||
// eslint-disable-next-line no-loss-of-precision
|
||||
if (size === 0x00ffffffffffffff) {
|
||||
size = null;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
};
|
||||
|
||||
export const readElementHeader = (slice: FileSlice) => {
|
||||
const id = readElementId(slice);
|
||||
if (id === null) {
|
||||
/**
|
||||
* Reads the size field of an EBML element.
|
||||
*
|
||||
* @returns
|
||||
* - `{ size: number }` - Successfully read a definite size
|
||||
* - `{ size: null }` - Successfully read an undefined size (0xFF marker, used in streaming)
|
||||
* - `null` - Couldn't read (insufficient bytes or invalid data)
|
||||
*/
|
||||
export const readElementSize = (slice: FileSlice): { size: number | null } | null => {
|
||||
// Need at least 1 byte to read the size
|
||||
if (slice.remainingLength < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const size = readElementSize(slice);
|
||||
const firstByte = readU8(slice);
|
||||
|
||||
return { id, size };
|
||||
if (firstByte === 0xff) {
|
||||
// Legitimate undefined size marker
|
||||
return { size: null };
|
||||
}
|
||||
|
||||
slice.skip(-1);
|
||||
const size = readVarInt(slice);
|
||||
|
||||
if (size === null) {
|
||||
// Couldn't read the varint (insufficient bytes or invalid)
|
||||
return null;
|
||||
}
|
||||
|
||||
// In some (livestreamed) files, this is the value of the size field. While this technically is just a very
|
||||
// large number, it is intended to behave like the reserved size 0xFF, meaning the size is undefined. We
|
||||
// catch the number here. Note that it cannot be perfectly represented as a double, but the comparison works
|
||||
// nonetheless.
|
||||
// eslint-disable-next-line no-loss-of-precision
|
||||
if (size === 0x00ffffffffffffff) {
|
||||
return { size: null };
|
||||
}
|
||||
|
||||
return { size };
|
||||
};
|
||||
|
||||
export const readElementHeader = (slice: FileSlice) => {
|
||||
// We need at least MIN_HEADER_SIZE bytes to read a header
|
||||
if (slice.remainingLength < MIN_HEADER_SIZE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const startPos = slice.filePos;
|
||||
|
||||
const id = readElementId(slice);
|
||||
if (id === null) {
|
||||
slice.filePos = startPos;
|
||||
return null;
|
||||
}
|
||||
|
||||
const sizeResult = readElementSize(slice);
|
||||
if (sizeResult === null) {
|
||||
// Couldn't read size - rewind to start
|
||||
slice.filePos = startPos;
|
||||
return null;
|
||||
}
|
||||
|
||||
return { id, size: sizeResult.size };
|
||||
};
|
||||
|
||||
export const readAsciiString = (slice: FileSlice, length: number) => {
|
||||
|
||||
@@ -908,9 +908,7 @@ export class MatroskaDemuxer extends Demuxer {
|
||||
}
|
||||
|
||||
readContiguousElements(slice: FileSlice, stopIds?: number[]) {
|
||||
const startIndex = slice.filePos;
|
||||
|
||||
while (slice.filePos - startIndex <= slice.length - MIN_HEADER_SIZE) {
|
||||
while (slice.remainingLength >= MIN_HEADER_SIZE) {
|
||||
const startPos = slice.filePos;
|
||||
const foundElement = this.traverseElement(slice, stopIds);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user