Skip to content

Commit

Permalink
add emsg validation and malformed box test
Browse files Browse the repository at this point in the history
  • Loading branch information
adrums86 committed Feb 9, 2023
1 parent 54d9645 commit e786dc1
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 18 deletions.
58 changes: 44 additions & 14 deletions lib/mp4/emsg.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ var parseEmsgBox = function(boxData) {
var offset = 4;
var version = boxData[0];
var scheme_id_uri,
value, timescale,
value,
timescale,
presentation_time,
presentation_time_delta,
event_duration,
id;
id,
message_data;
if (version === 0) {
scheme_id_uri = uint8ToCString(boxData.subarray(offset));
offset += scheme_id_uri.length;
Expand Down Expand Up @@ -48,26 +50,54 @@ var parseEmsgBox = function(boxData) {
offset += scheme_id_uri.length;
value = uint8ToCString(boxData.subarray(offset));
offset += value.length;
} else {
// Invalid EMSG box.
return;
}

var message_data = new Uint8Array(boxData.subarray(offset, boxData.byteLength));
return { scheme_id_uri,
value,
timescale,
presentation_time,
presentation_time_delta,
event_duration,
id,
message_data };
message_data = new Uint8Array(boxData.subarray(offset, boxData.byteLength));
var emsgBox = {
scheme_id_uri,
value,
// if timescale is undefined or 0 set to 1
timescale: timescale ? timescale : 1,
presentation_time,
presentation_time_delta,
event_duration,
id,
message_data };

return isValidEmsgBox(version, emsgBox) ? emsgBox : undefined;
};

/**
* Scales a presentation time or time delta with an offset with a provided timescale
* @param {number} presentationTime
* @param {number} timescale
* @param {number} timeDelta
* @param {number} offset
* @returns the scaled time as a number
*/
var scaleTime = function(presentationTime, timescale, timeDelta, offset) {
return presentationTime || presentationTime === 0 ? presentationTime / timescale : offset + timeDelta / timescale;
};

/**
* Checks the emsg box data for validity based on the version
* @param {number} version of the emsg box to validate
* @param {Object} emsg the emsg data to validate
* @returns if the box is valid as a boolean
*/
var isValidEmsgBox = function(version, emsg) {
var hasScheme = emsg.scheme_id_uri !== '\0'
var isValidV0Box = version === 0 && isDefined(emsg.presentation_time_delta) && hasScheme;
var isValidV1Box = version === 1 && isDefined(emsg.presentation_time) && hasScheme;
// Only valid versions of emsg are 0 and 1
return !(version > 1) && isValidV0Box || isValidV1Box;
};

// Utility function to check if an object is defined
var isDefined = function(data) {
return data !== undefined || data !== null;
};

module.exports = {
parseEmsgBox: parseEmsgBox,
scaleTime: scaleTime
Expand Down
10 changes: 8 additions & 2 deletions test/mp4-emsg.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,14 @@ QUnit.test('Can parse a v1 emsg box', function(assert) {
assert.deepEqual(parsedBox.message_data, messageData, 'v1 box has expected data');
});

QUnit.test('Will return undefined if the emsg box is invalid', function(assert) {
var badBoxData = generateEmsgBoxData(3, messageData);
QUnit.test('Will return undefined if the emsg version is invalid', function(assert) {
var badBoxData = generateEmsgBoxData(2, messageData);
var parsedBox = emsg.parseEmsgBox(badBoxData);
assert.equal(parsedBox, undefined, 'parsed box is undefined');
});

QUnit.test('Will return undefined if the emsg data is malformed', function(assert) {
var badBoxData = generateEmsgBoxData(3, messageData);
var parsedBox = emsg.parseEmsgBox(badBoxData);
assert.equal(parsedBox, undefined, 'malformed box is undefined');
});
14 changes: 12 additions & 2 deletions test/utils/mp4-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ var generateEmsgBoxData = function(version, messageData) {
0x75, 0x72, 0x6E, 0x3A, 0x66, 0x6F, 0x6F, 0x3A, 0x62, 0x61, 0x72, 0x3A, 0x32, 0x30, 0x32, 0x33, 0x00, // urn:foo:bar:2023\0
0x66, 0x6F, 0x6F, 0x2E, 0x62, 0x61, 0x72, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x00 // foo.bar.value\0
]);
} else {
// Invalid EMSG box
} else if (version === 2) {
// Invalid version only
emsgProps = new Uint8Array([
0x02, // version
0x00, 0x00, 0x00, //flags
Expand All @@ -352,6 +352,16 @@ var generateEmsgBoxData = function(version, messageData) {
0x75, 0x72, 0x6E, 0x3A, 0x66, 0x6F, 0x6F, 0x3A, 0x62, 0x61, 0x72, 0x3A, 0x32, 0x30, 0x32, 0x33, 0x00, // urn:foo:bar:2023\0
0x66, 0x6F, 0x6F, 0x2E, 0x62, 0x61, 0x72, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x00 // foo.bar.value\0
]);
} else {
emsgProps = new Uint8Array([
// malformed emsg data
0x00, 0x00, 0x00, 0x64, // timescale = 100
// no presentation_time
0x00, 0x00, 0x00, 0x01, // event_duration = 1
// no id
0x75, 0x72, 0x6E, 0x3A, 0x66, 0x6F, 0x6F, 0x3A, 0x62, 0x61, 0x72, 0x3A, 0x32, 0x30, 0x32, 0x33, 0x00, // urn:foo:bar:2023\0
0x66, 0x6F, 0x6F, 0x2E, 0x62, 0x61, 0x72, 0x2E, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x00 // foo.bar.value\0
]);
}

// concat the props and messageData
Expand Down

0 comments on commit e786dc1

Please sign in to comment.