From 5f0d9b56cd480d192d819b61c8a8a7e18fe285d9 Mon Sep 17 00:00:00 2001 From: dsilhavy Date: Sat, 23 May 2020 11:00:11 +0200 Subject: [PATCH] Fix pssh parsing (#3262) * Update version number to 3.1.2 * Remove newlines and whitespaces from pssh string * Add unit tests for CommonEncryption class --- package.json | 2 +- src/core/Version.js | 2 +- src/streaming/protection/CommonEncryption.js | 4 ++ .../streaming.protection.CommonEncryption.js | 68 +++++++++++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 test/unit/streaming.protection.CommonEncryption.js diff --git a/package.json b/package.json index e7b2c65905..fffc2b755a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dashjs", - "version": "3.1.1", + "version": "3.1.2", "description": "A reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.", "main": "build/es5/index.js", "types": "build/typings/index.d.ts", diff --git a/src/core/Version.js b/src/core/Version.js index 966b6598fd..343aaa28db 100644 --- a/src/core/Version.js +++ b/src/core/Version.js @@ -1,4 +1,4 @@ -const VERSION = '3.1.1'; +const VERSION = '3.1.2'; export function getVersionString() { return VERSION; } diff --git a/src/streaming/protection/CommonEncryption.js b/src/streaming/protection/CommonEncryption.js index 9efa46660f..c76ebb6f56 100644 --- a/src/streaming/protection/CommonEncryption.js +++ b/src/streaming/protection/CommonEncryption.js @@ -104,6 +104,10 @@ class CommonEncryption { */ static parseInitDataFromContentProtection(cpData, BASE64) { if ('pssh' in cpData) { + + // Remove whitespaces and newlines from pssh text + cpData.pssh.__text = cpData.pssh.__text.replace(/\r?\n|\r/g,'').replace(/\s+/g,''); + return BASE64.decodeArray(cpData.pssh.__text).buffer; } return null; diff --git a/test/unit/streaming.protection.CommonEncryption.js b/test/unit/streaming.protection.CommonEncryption.js new file mode 100644 index 0000000000..cf5c5871ce --- /dev/null +++ b/test/unit/streaming.protection.CommonEncryption.js @@ -0,0 +1,68 @@ +import CommonEncryption from '../../src/streaming/protection/CommonEncryption'; +import Base64 from '../../externals/base64'; + +const expect = require('chai').expect; +let cpData; + +describe('CommonEncryption', () => { + + beforeEach(() => { + cpData = { + 'pssh': { + '__text': 'AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARABGgZlbHV2aW8iBmVsdXZpbw==' + }, + 'value': 'Widevine', + 'schemeIdUri': 'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed', + 'KID': null + }; + }); + + describe('parseInitDataFromContentProtection', () => { + + it('should return null if no init data is available in the ContentProtection element', () => { + cpData = {}; + const result = CommonEncryption.parseInitDataFromContentProtection(cpData,Base64); + + expect(result).to.be.null; // jshint ignore:line + }); + + it('should return base64 decoded string if init data is available in the ContentProtection element', () => { + const result = CommonEncryption.parseInitDataFromContentProtection(cpData,Base64); + const expectedByteLength = Base64.decodeArray(cpData.pssh.__text).buffer.byteLength; + + expect(result.byteLength).to.equal(expectedByteLength); + }); + + it('should remove newlines and return base64 decoded string if init data is available in the ContentProtection element', () => { + const expectedByteLength = Base64.decodeArray(cpData.pssh.__text).buffer.byteLength; + cpData.pssh.__text = '\nAAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARABGgZlbHV2aW8iBmVsdXZpbw==\n'; + const originalByteLength = Base64.decodeArray(cpData.pssh.__text).buffer.byteLength; + const result = CommonEncryption.parseInitDataFromContentProtection(cpData,Base64); + + expect(originalByteLength).to.not.equal(result.byteLength); + expect(result.byteLength).to.equal(expectedByteLength); + }); + + it('should remove whitespaces and return base64 decoded string if init data is available in the ContentProtection element', () => { + const expectedByteLength = Base64.decodeArray(cpData.pssh.__text).buffer.byteLength; + cpData.pssh.__text = 'AAAANHBzc2gAAAAA7e+LqXnWSs6jy Cfc1R0h7QAAABQIARABGgZlbHV2aW8iBmVsdXZpbw=='; + const originalByteLength = Base64.decodeArray(cpData.pssh.__text).buffer.byteLength; + const result = CommonEncryption.parseInitDataFromContentProtection(cpData,Base64); + + expect(originalByteLength).to.not.equal(result.byteLength); + expect(result.byteLength).to.equal(expectedByteLength); + }); + + it('should remove whitespaces and newlines and return base64 decoded string if init data is available in the ContentProtection element', () => { + const expectedByteLength = Base64.decodeArray(cpData.pssh.__text).buffer.byteLength; + cpData.pssh.__text = '\n\n\nAAAANHBzc2gAAAAA7e+LqXnWSs6jy Cfc1R0h7QAAABQIARABGgZlbHV2aW8iBmVsdXZpbw==\n\n'; + const originalByteLength = Base64.decodeArray(cpData.pssh.__text).buffer.byteLength; + const result = CommonEncryption.parseInitDataFromContentProtection(cpData,Base64); + + expect(originalByteLength).to.not.equal(result.byteLength); + expect(result.byteLength).to.equal(expectedByteLength); + }); + + }); + +});