Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/flat-laws-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'mp4box': patch
---

fix short tkhd atom range error
4 changes: 2 additions & 2 deletions src/box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { MultiBufferStream } from '#/buffer';
import { MAX_UINT32 } from '#/constants';
import { ErrorCode, MAX_UINT32 } from '#/constants';
import { DataStream } from '#/DataStream';
import { Log } from '#/log';
import type { BoxFourCC, Output, Reference } from '@types';
Expand Down Expand Up @@ -152,7 +152,7 @@ export class Box {
}

/** @bundle box-parse.js */
parse(stream: MultiBufferStream) {
parse(stream: MultiBufferStream): ErrorCode | ReturnType<() => void> {
if (this.type !== 'mdat') {
this.data = stream.readUint8Array(this.size - this.hdr_size);
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/boxes/dref.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Box, FullBox } from '#/box';
import type { MultiBufferStream } from '#/buffer';
import { OK } from '#/constants';
import { ErrorCode } from '#/constants';
import { Log } from '#/log';
import { parseOneBox } from '#/parser';

Expand All @@ -16,7 +16,7 @@ export class drefBox extends FullBox {
const entry_count = stream.readUint32();
for (let i = 0; i < entry_count; i++) {
const ret = parseOneBox(stream, false, this.size - (stream.getPosition() - this.start));
if (ret.code === OK) {
if (ret.code === ErrorCode.OK) {
const box = ret.box;
this.entries.push(box);
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/boxes/iinf.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FullBox } from '#/box';
import { infeBox } from '#/boxes/infe';
import type { MultiBufferStream } from '#/buffer';
import { OK } from '#/constants';
import { ErrorCode } from '#/constants';
import { Log } from '#/log';
import { parseOneBox } from '#/parser';
import type { BoxKind } from '@types';
Expand All @@ -26,7 +26,7 @@ export class iinfBox extends FullBox {

for (let i = 0; i < this.entry_count; i++) {
const ret = parseOneBox(stream, false, this.size - (stream.getPosition() - this.start));
if (ret.code === OK) {
if (ret.code === ErrorCode.OK) {
const box = ret.box as BoxKind;
if (box.type === 'infe') {
this.item_infos[i] = box as infeBox;
Expand Down
4 changes: 2 additions & 2 deletions src/boxes/iref.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Box, FullBox, SingleItemTypeReferenceBox, SingleItemTypeReferenceBoxLarge } from '#/box';
import type { MultiBufferStream } from '#/buffer';
import { OK } from '#/constants';
import { ErrorCode } from '#/constants';
import { Log } from '#/log';
import { parseOneBox } from '#/parser';

Expand Down Expand Up @@ -59,7 +59,7 @@ export class irefBox extends FullBox {

while (stream.getPosition() < this.start + this.size) {
const ret = parseOneBox(stream, true, this.size - (stream.getPosition() - this.start));
if (ret.code === OK) {
if (ret.code === ErrorCode.OK) {
let name = 'Unknown item reference';
if (!irefBox.allowed_types.includes(ret.type as (typeof irefBox.allowed_types)[number])) {
Log.warn('BoxParser', `Unknown item reference type: '${ret.type}'`);
Expand Down
4 changes: 2 additions & 2 deletions src/boxes/qt/ilst.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Box } from '#/box';
import { OK } from '#/constants';
import { ErrorCode } from '#/constants';
import { parseOneBox } from '#/parser';
import type { MultiBufferStream } from '#/buffer';

Expand All @@ -25,7 +25,7 @@ export class ilstBox extends Box {
const index = stream.readUint32();

const res = parseOneBox(stream, false, size - 8);
if (res.code === OK) this.list[index] = res.box;
if (res.code === ErrorCode.OK) this.list[index] = res.box;
total -= size;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/boxes/stsd.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FullBox } from '#/box';
import type { MultiBufferStream } from '#/buffer';
import { OK } from '#/constants';
import { ErrorCode } from '#/constants';
import { Log } from '#/log';
import { BoxRegistry } from '#/registry';
import type { BoxFourCC } from '@types';
Expand All @@ -22,7 +22,7 @@ export class stsdBox extends FullBox {
for (let i = 1; i <= entryCount; i++) {
const ret = parseOneBox(stream, true, this.size - (stream.getPosition() - this.start));

if (ret.code === OK) {
if (ret.code === ErrorCode.OK) {
let box: SampleEntry;
if (ret.type in BoxRegistry.sampleEntry) {
box = new BoxRegistry.sampleEntry[ret.type](ret.size);
Expand Down
4 changes: 2 additions & 2 deletions src/boxes/stvi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FullBox } from '#/box';
import type { MultiBufferStream } from '#/buffer';
import { OK } from '#/constants';
import { ErrorCode } from '#/constants';
import { parseOneBox } from '#/parser';
import type { BoxKind } from '@types';

Expand All @@ -22,7 +22,7 @@ export class stviBox extends FullBox {
this.boxes = [];
while (stream.getPosition() < this.start + this.size) {
const ret = parseOneBox(stream, false, this.size - (stream.getPosition() - this.start));
if (ret.code === OK) {
if (ret.code === ErrorCode.OK) {
const box = ret.box as BoxKind;
this.boxes.push(box);
this[box.type] = box;
Expand Down
13 changes: 12 additions & 1 deletion src/boxes/tkhd.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FullBox } from '#/box';
import type { MultiBufferStream } from '#/buffer';
import { MAX_UINT32 } from '#/constants';
import { ErrorCode, MAX_UINT32 } from '#/constants';
import type { Matrix } from '@types';

export class tkhdBox extends FullBox {
Expand All @@ -19,7 +19,18 @@ export class tkhdBox extends FullBox {
height: number;

parse(stream: MultiBufferStream) {
// A complete declared box with too few fields is malformed, not incomplete input.
if (this.size - this.hdr_size < 4) {
return ErrorCode.ERR_INVALID_DATA;
}
this.parseFullHeader(stream);
if (this.version !== 0 && this.version !== 1) {
return ErrorCode.ERR_INVALID_DATA;
}
const minimumFieldBytes = this.version === 1 ? 92 : 80;
if (this.size - this.hdr_size < minimumFieldBytes) {
return ErrorCode.ERR_INVALID_DATA;
}
if (this.version === 1) {
this.creation_time = stream.readUint64();
this.modification_time = stream.readUint64();
Expand Down
4 changes: 2 additions & 2 deletions src/boxes/tref.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { OK } from '#//constants';
import { ErrorCode } from '#/constants';
import { Box, TrackReferenceTypeBox } from '#/box';
import type { MultiBufferStream } from '#/buffer';
import { Log } from '#/log';
Expand Down Expand Up @@ -28,7 +28,7 @@ export class trefBox extends Box {
parse(stream: MultiBufferStream) {
while (stream.getPosition() < this.start + this.size) {
const ret = parseOneBox(stream, true, this.size - (stream.getPosition() - this.start));
if (ret.code === OK) {
if (ret.code === ErrorCode.OK) {
if (!trefBox.allowed_types.includes(ret.type as (typeof trefBox.allowed_types)[number])) {
Log.warn('BoxParser', `Unknown track reference type: '${ret.type}'`);
}
Expand Down
4 changes: 2 additions & 2 deletions src/boxes/trep.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FullBox } from '#/box';
import type { MultiBufferStream } from '#/buffer';
import { OK } from '#/constants';
import { ErrorCode } from '#/constants';
import { parseOneBox } from '#/parser';

export class trepBox extends FullBox {
Expand All @@ -15,7 +15,7 @@ export class trepBox extends FullBox {
this.boxes = [];
while (stream.getPosition() < this.start + this.size) {
const ret = parseOneBox(stream, false, this.size - (stream.getPosition() - this.start));
if (ret.code === OK) {
if (ret.code === ErrorCode.OK) {
const box = ret.box;
this.boxes.push(box);
} else {
Expand Down
31 changes: 31 additions & 0 deletions src/buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,37 @@ export class MultiBufferStream extends DataStream {
}
}

/**
* Removes a range of bytes from the buffers
* @param {number} start start position of the range to remove
* @param {number} [end] end position of the range to remove (optional)
*/
removeRange(start: number, end?: number) {
if (end !== undefined && end <= start) return;
for (let i = 0; i < this.buffers.length; i++) {
const buffer = this.buffers[i];
const bufferEnd = buffer.fileStart + buffer.byteLength;
if (start >= bufferEnd) continue;
if (end !== undefined && end <= buffer.fileStart) break;

if (start <= buffer.fileStart && (end === undefined || end >= bufferEnd)) {
this.buffers.splice(i, 1);
i--;
} else {
const offset = Math.max(start - buffer.fileStart, 0);
const adjustedEnd = Math.min(end ?? bufferEnd, bufferEnd);
const newLength = adjustedEnd - buffer.fileStart - offset;
if (newLength > 0) {
const newBuffer = this.reduceBuffer(buffer, offset, newLength);
this.buffers[i] = newBuffer;
} else {
this.buffers.splice(i, 1);
i--;
}
}
}
}

/**
* Displays the status of the buffers (number and used bytes)
* @param {Object} info callback method for display
Expand Down
8 changes: 5 additions & 3 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ export const TRUN_FLAGS_SIZE = 0x200;
export const TRUN_FLAGS_FLAGS = 0x400;
export const TRUN_FLAGS_CTS_OFFSET = 0x800;

export const ERR_INVALID_DATA = -1;
export const ERR_NOT_ENOUGH_DATA = 0;
export const OK = 1;
export enum ErrorCode {
ERR_INVALID_DATA = -1,
ERR_NOT_ENOUGH_DATA = 0,
OK = 1,
}

// Constants
export const SAMPLE_ENTRY_TYPE_VISUAL = 'Visual';
Expand Down
6 changes: 4 additions & 2 deletions src/containerBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { MultiBufferStream } from '#/buffer';
import type { DataStream } from '#/DataStream';
import { Box } from '#/box';
import { Log } from '#/log';
import { OK } from '#/constants';
import { ErrorCode } from '#/constants';
import { parseOneBox } from '#/parser';

export class ContainerBox extends Box {
Expand Down Expand Up @@ -44,7 +44,7 @@ export class ContainerBox extends Box {
let ret: ReturnType<typeof parseOneBox>;
while (stream.getPosition() < this.start + this.size) {
ret = parseOneBox(stream, false, this.size - (stream.getPosition() - this.start));
if (ret.code === OK) {
if (ret.code === ErrorCode.OK) {
const box = ret.box as BoxKind;
if (!this.boxes) {
this.boxes = [];
Expand All @@ -66,6 +66,8 @@ export class ContainerBox extends Box {
this[box_type] = box;
}
}
} else if (ret.code === ErrorCode.ERR_INVALID_DATA) {
return ErrorCode.ERR_INVALID_DATA;
} else {
return;
}
Expand Down
12 changes: 5 additions & 7 deletions src/isofile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ import { urlBox } from '#/boxes/url';
import { vmhdBox } from '#/boxes/vmhd';
import { MultiBufferStream } from '#/buffer';
import {
ERR_INVALID_DATA,
ERR_NOT_ENOUGH_DATA,
OK,
ErrorCode,
TFHD_FLAG_BASE_DATA_OFFSET,
TFHD_FLAG_DEFAULT_BASE_IS_MOOF,
TFHD_FLAG_SAMPLE_DESC,
Expand Down Expand Up @@ -388,7 +386,7 @@ export class ISOFile<TSegmentUser = unknown, TSampleUser = unknown> {
this.saveParsePosition();
}
const ret = parseOneBox(this.stream, parseBoxHeadersOnly);
if (ret.code === ERR_NOT_ENOUGH_DATA) {
if (ret.code === ErrorCode.ERR_NOT_ENOUGH_DATA) {
if (this.processIncompleteBox) {
if (this.processIncompleteBox(ret)) {
continue;
Expand All @@ -398,7 +396,7 @@ export class ISOFile<TSegmentUser = unknown, TSampleUser = unknown> {
} else {
return;
}
} else if (ret.code === OK) {
} else if (ret.code === ErrorCode.OK) {
/* the box is entirely parsed */
const box = ret.box as BoxKind;
/* store the box in the 'boxes' array to preserve box order (for file rewrite if needed) */
Expand Down Expand Up @@ -458,10 +456,10 @@ export class ISOFile<TSegmentUser = unknown, TSampleUser = unknown> {
if (this.updateUsedBytes) {
this.updateUsedBytes(box, ret);
}
} else if (ret.code === ERR_INVALID_DATA) {
} else if (ret.code === ErrorCode.ERR_INVALID_DATA) {
Log.error(
'ISOFile',
`Invalid data found while parsing box of type '${ret.type}' at position ${ret.start}. Aborting parsing.`,
`Invalid data found while parsing box of type '${ret.type}' at position ${ret.start}. Discarded bytes from ${ret.start} until the end of the stream.`,
this,
);
break;
Expand Down
Loading
Loading