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