mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-14 15:56:38 +03:00
849bff1db3
Make cloning buffers (or not) explicit in readBytes. When we use a range of bytes temporarily for further parsing, we pass clone=false and get a view on the existing memory buffer. When we want to store the range of bytes, we pass clone=true and avoid holding a reference to an entire segment in memory. The call for the EMSG parser in MediaSourceEngine had an explicit clone, but now uses the new clone parameter. This is not a functional change, though. The only readBytes call that changed in this audit was in the UI seek bar. The rest all appear to be values for temporary usage, and so are not being cloned. The new `clone` parameter will require future callers of `readBytes()` to think about their purpose and make a choice.
255 lines
7.2 KiB
JavaScript
255 lines
7.2 KiB
JavaScript
/*! @license
|
|
* Shaka Player
|
|
* Copyright 2016 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
describe('DataViewReader', () => {
|
|
const Util = shaka.test.Util;
|
|
|
|
// |data| as interpreted as a 64 bit integer must not be larger than 2^53-1.
|
|
// decimal digits.
|
|
const data = new Uint8Array([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]);
|
|
// |data2| is small enough in little-endian to be read as a 64-bit number,
|
|
// and has the sign bit set on the first 6 bytes to prove that we don't
|
|
// return negative values.
|
|
const data2 =
|
|
new Uint8Array([0xde, 0xad, 0xbe, 0xef, 0xff, 0xff, 0x01, 0x00]);
|
|
|
|
/** @type {!shaka.util.DataViewReader} */
|
|
let bigEndianReader;
|
|
/** @type {!shaka.util.DataViewReader} */
|
|
let littleEndianReader;
|
|
/** @type {!shaka.util.DataViewReader} */
|
|
let bigEndianReader2;
|
|
/** @type {!shaka.util.DataViewReader} */
|
|
let littleEndianReader2;
|
|
|
|
beforeEach(() => {
|
|
bigEndianReader = new shaka.util.DataViewReader(
|
|
data, shaka.util.DataViewReader.Endianness.BIG_ENDIAN);
|
|
bigEndianReader2 = new shaka.util.DataViewReader(
|
|
data2, shaka.util.DataViewReader.Endianness.BIG_ENDIAN);
|
|
littleEndianReader = new shaka.util.DataViewReader(
|
|
data, shaka.util.DataViewReader.Endianness.LITTLE_ENDIAN);
|
|
littleEndianReader2 = new shaka.util.DataViewReader(
|
|
data2, shaka.util.DataViewReader.Endianness.LITTLE_ENDIAN);
|
|
});
|
|
|
|
it('reads a uint8 in big endian', () => {
|
|
const value1 = bigEndianReader.readUint8();
|
|
expect(value1).toBe(0x00);
|
|
|
|
const value2 = bigEndianReader.readUint8();
|
|
expect(value2).toBe(0x01);
|
|
|
|
const value3 = bigEndianReader2.readUint8();
|
|
expect(value3).toBe(0xde);
|
|
|
|
const value4 = bigEndianReader2.readUint8();
|
|
expect(value4).toBe(0xad);
|
|
});
|
|
|
|
it('reads a uint16 in big endian', () => {
|
|
const value1 = bigEndianReader.readUint16();
|
|
expect(value1).toBe(0x0001);
|
|
|
|
const value2 = bigEndianReader.readUint16();
|
|
expect(value2).toBe(0x0203);
|
|
|
|
const value3 = bigEndianReader2.readUint16();
|
|
expect(value3).toBe(0xdead);
|
|
|
|
const value4 = bigEndianReader2.readUint16();
|
|
expect(value4).toBe(0xbeef);
|
|
});
|
|
|
|
it('reads a uint32 in big endian', () => {
|
|
const value1 = bigEndianReader.readUint32();
|
|
expect(value1).toBe(0x00010203);
|
|
|
|
const value2 = bigEndianReader.readUint32();
|
|
expect(value2).toBe(0x04050607);
|
|
|
|
const value3 = bigEndianReader2.readUint32();
|
|
expect(value3).toBe(0xdeadbeef);
|
|
|
|
const value4 = bigEndianReader2.readUint32();
|
|
expect(value4).toBe(0xffff0100);
|
|
});
|
|
|
|
it('reads an int32 in big endian', () => {
|
|
const value1 = bigEndianReader.readInt32();
|
|
expect(value1).toBe(66051);
|
|
|
|
const value2 = bigEndianReader.readInt32();
|
|
expect(value2).toBe(67438087);
|
|
|
|
const value3 = bigEndianReader2.readInt32();
|
|
expect(value3).toBe(-559038737);
|
|
|
|
const value4 = bigEndianReader2.readInt32();
|
|
expect(value4).toBe(-65280);
|
|
});
|
|
|
|
it('reads a uint64 in big endian', () => {
|
|
const value = bigEndianReader.readUint64();
|
|
expect(value).toBe(0x0001020304050607);
|
|
});
|
|
|
|
it('reads a uint8 in little endian', () => {
|
|
const value1 = littleEndianReader.readUint8();
|
|
expect(value1).toBe(0x00);
|
|
|
|
const value2 = littleEndianReader.readUint8();
|
|
expect(value2).toBe(0x01);
|
|
|
|
const value3 = littleEndianReader2.readUint8();
|
|
expect(value3).toBe(0xde);
|
|
|
|
const value4 = littleEndianReader2.readUint8();
|
|
expect(value4).toBe(0xad);
|
|
});
|
|
|
|
it('reads a uint16 in little endian', () => {
|
|
const value1 = littleEndianReader.readUint16();
|
|
expect(value1).toBe(0x0100);
|
|
|
|
const value2 = littleEndianReader.readUint16();
|
|
expect(value2).toBe(0x0302);
|
|
|
|
const value3 = littleEndianReader2.readUint16();
|
|
expect(value3).toBe(0xadde);
|
|
|
|
const value4 = littleEndianReader2.readUint16();
|
|
expect(value4).toBe(0xefbe);
|
|
});
|
|
|
|
it('reads a uint32 in little endian', () => {
|
|
const value1 = littleEndianReader.readUint32();
|
|
expect(value1).toBe(0x03020100);
|
|
|
|
const value2 = littleEndianReader.readUint32();
|
|
expect(value2).toBe(0x07060504);
|
|
|
|
const value3 = littleEndianReader2.readUint32();
|
|
expect(value3).toBe(0xefbeadde);
|
|
|
|
const value4 = littleEndianReader2.readUint32();
|
|
expect(value4).toBe(0x0001ffff);
|
|
});
|
|
|
|
it('reads an int32 in little endian', () => {
|
|
const value1 = littleEndianReader.readInt32();
|
|
expect(value1).toBe(50462976);
|
|
|
|
const value2 = littleEndianReader.readInt32();
|
|
expect(value2).toBe(117835012);
|
|
|
|
const value3 = littleEndianReader2.readInt32();
|
|
expect(value3).toBe(-272716322);
|
|
|
|
const value4 = littleEndianReader2.readInt32();
|
|
expect(value4).toBe(131071);
|
|
});
|
|
|
|
it('reads a uint64 in little endian', () => {
|
|
const value = littleEndianReader2.readUint64();
|
|
expect(value).toBe(0x0001ffffefbeadde);
|
|
});
|
|
|
|
it('skips bytes', () => {
|
|
bigEndianReader.skip(1);
|
|
const value = bigEndianReader.readUint8();
|
|
expect(value).toBe(0x01);
|
|
});
|
|
|
|
it('determines the end of the data view', () => {
|
|
bigEndianReader.skip(7);
|
|
expect(bigEndianReader.hasMoreData()).toBe(true);
|
|
|
|
bigEndianReader.skip(1);
|
|
expect(bigEndianReader.hasMoreData()).toBe(false);
|
|
});
|
|
|
|
it('gets the byte position', () => {
|
|
expect(bigEndianReader.getPosition()).toBe(0);
|
|
|
|
bigEndianReader.skip(1);
|
|
expect(bigEndianReader.getPosition()).toBe(1);
|
|
|
|
bigEndianReader.skip(7);
|
|
expect(bigEndianReader.getPosition()).toBe(8);
|
|
});
|
|
|
|
describe('end-of-stream', () => {
|
|
it('detects when reading a uint8', () => {
|
|
bigEndianReader.skip(7);
|
|
bigEndianReader.readUint8();
|
|
runTest(() => {
|
|
bigEndianReader.readUint8();
|
|
});
|
|
});
|
|
|
|
it('detects when reading a uint16', () => {
|
|
bigEndianReader.skip(7);
|
|
runTest(() => {
|
|
bigEndianReader.readUint16();
|
|
});
|
|
});
|
|
|
|
it('detects when reading a uint32', () => {
|
|
bigEndianReader.skip(5);
|
|
runTest(() => {
|
|
bigEndianReader.readUint32();
|
|
});
|
|
});
|
|
|
|
it('detects when reading a int32', () => {
|
|
bigEndianReader.skip(5);
|
|
runTest(() => {
|
|
bigEndianReader.readInt32();
|
|
});
|
|
});
|
|
|
|
it('detects when reading a uint64', () => {
|
|
bigEndianReader.skip(3);
|
|
runTest(() => {
|
|
bigEndianReader.readUint64();
|
|
});
|
|
});
|
|
|
|
it('detects when skipping bytes', () => {
|
|
bigEndianReader.skip(8);
|
|
runTest(() => {
|
|
bigEndianReader.skip(1);
|
|
});
|
|
});
|
|
|
|
it('detects when reading bytes', () => {
|
|
bigEndianReader.skip(8);
|
|
runTest(() => {
|
|
bigEndianReader.readBytes(1, /* clone= */ false);
|
|
});
|
|
});
|
|
|
|
function runTest(test) {
|
|
const expected = Util.jasmineError(new shaka.util.Error(
|
|
shaka.util.Error.Severity.CRITICAL,
|
|
shaka.util.Error.Category.MEDIA,
|
|
shaka.util.Error.Code.BUFFER_READ_OUT_OF_BOUNDS));
|
|
expect(test).toThrow(expected);
|
|
}
|
|
});
|
|
|
|
it('detects uint64s too large for JavaScript', () => {
|
|
const expected = Util.jasmineError(new shaka.util.Error(
|
|
shaka.util.Error.Severity.CRITICAL,
|
|
shaka.util.Error.Category.MEDIA,
|
|
shaka.util.Error.Code.JS_INTEGER_OVERFLOW));
|
|
|
|
expect(() => littleEndianReader.readUint64()).toThrow(expected);
|
|
expect(() => bigEndianReader2.readUint64()).toThrow(expected);
|
|
});
|
|
});
|