/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include <algorithm>
#include <stdint.h>
#include <vector>
#include "psshparser/PsshParser.h"
#include "mozilla/ArrayUtils.h"
using namespace std;
// This is the CENC initData from Google's web-platform tests.
// https://github.com/w3c/web-platform-tests/blob/master/encrypted-media/Google/encrypted-media-utils.js#L50
const uint8_t gGoogleWPTCencInitData[] = {
// clang-format off
0 x00,
0 x00,
0 x00,
0 x00,
// size = 0
0 x70,
0 x73,
0 x73,
0 x68,
// 'pssh'
0 x01,
// version = 1
0 x00,
0 x00,
0 x00,
// flags
0 x10,
0 x77,
0 xEF,
0 xEC,
0 xC0,
0 xB2,
0 x4D,
0 x02,
// Common SystemID
0 xAC,
0 xE3,
0 x3C,
0 x1E,
0 x52,
0 xE2,
0 xFB,
0 x4B,
0 x00,
0 x00,
0 x00,
0 x01,
// key count
0 x00,
0 x01,
0 x02,
0 x03,
0 x04,
0 x05,
0 x06,
0 x07,
// key
0 x08,
0 x09,
0 x0A,
0 x0B,
0 x0C,
0 x0D,
0 x0E,
0 x0F,
0 x00,
0 x00,
0 x00,
0 x00
// datasize
// clang-format on
};
// Example CENC initData from the EME spec format registry:
// https://w3c.github.io/encrypted-media/format-registry/initdata/cenc.html
const uint8_t gW3SpecExampleCencInitData[] = {
// clang-format off
0 x00,
0 x00,
0 x00,
0 x44,
0 x70,
0 x73,
0 x73,
0 x68,
// BMFF box header (68 bytes, 'pssh')
0 x01,
0 x00,
0 x00,
0 x00,
// Full box header (version = 1, flags = 0)
0 x10,
0 x77,
0 xef,
0 xec,
0 xc0,
0 xb2,
0 x4d,
0 x02,
// SystemID
0 xac,
0 xe3,
0 x3c,
0 x1e,
0 x52,
0 xe2,
0 xfb,
0 x4b,
0 x00,
0 x00,
0 x00,
0 x02,
// KID_count (2)
0 x30,
0 x31,
0 x32,
0 x33,
0 x34,
0 x35,
0 x36,
0 x37,
// First KID ("0123456789012345")
0 x38,
0 x39,
0 x30,
0 x31,
0 x32,
0 x33,
0 x34,
0 x35,
0 x41,
0 x42,
0 x43,
0 x44,
0 x45,
0 x46,
0 x47,
0 x48,
// Second KID ("ABCDEFGHIJKLMNOP")
0 x49,
0 x4a,
0 x4b,
0 x4c,
0 x4d,
0 x4e,
0 x4f,
0 x50,
0 x00,
0 x00,
0 x00,
0 x00
// Size of Data (0)
// clang-format on
};
// Invalid box size, would overflow if used.
const uint8_t gOverflowBoxSize[] = {
0 xff,
0 xff,
0 xff,
0 xff,
// size = UINT32_MAX
};
// Valid box size, but key count too large.
const uint8_t gTooLargeKeyCountInitData[] = {
// clang-format off
0 x00,
0 x00,
0 x00,
0 x34,
// size = too big a number
0 x70,
0 x73,
0 x73,
0 x68,
// 'pssh'
0 x01,
// version = 1
0 xff,
0 xff,
0 xff,
// flags
0 x10,
0 x77,
0 xEF,
0 xEC,
0 xC0,
0 xB2,
0 x4D,
0 x02,
// Common SystemID
0 xAC,
0 xE3,
0 x3C,
0 x1E,
0 x52,
0 xE2,
0 xFB,
0 x4B,
0 xff,
0 xff,
0 xff,
0 xff,
// key count = UINT32_MAX
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
// key
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff
// datasize
// clang-format on
};
// Non common SystemID PSSH.
// No keys Ids can be extracted, but don't consider the box invalid.
const uint8_t gNonCencInitData[] = {
// clang-format off
0 x00,
0 x00,
0 x00,
0 x5c,
// size = 92
0 x70,
0 x73,
0 x73,
0 x68,
// 'pssh'
0 x01,
// version = 1
0 x00,
0 x00,
0 x00,
// flags
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
// Invalid SystemID
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
// Some data to pad out the box.
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
0 xff,
// clang-format on
};
const uint8_t gNonPSSHBoxZeroSize[] = {
// clang-format off
0 x00,
0 x00,
0 x00,
0 x00,
// size = 0
0 xff,
0 xff,
0 xff,
0 xff,
// something other than 'pssh'
// clang-format on
};
// Two lots of the google init data. To ensure we handle
// multiple boxes with size 0.
const uint8_t g2xGoogleWPTCencInitData[] = {
// clang-format off
0 x00,
0 x00,
0 x00,
0 x00,
// size = 0
0 x70,
0 x73,
0 x73,
0 x68,
// 'pssh'
0 x01,
// version = 1
0 x00,
0 x00,
0 x00,
// flags
0 x10,
0 x77,
0 xEF,
0 xEC,
0 xC0,
0 xB2,
0 x4D,
0 x02,
// Common SystemID
0 xAC,
0 xE3,
0 x3C,
0 x1E,
0 x52,
0 xE2,
0 xFB,
0 x4B,
0 x00,
0 x00,
0 x00,
0 x01,
// key count
0 x00,
0 x01,
0 x02,
0 x03,
0 x04,
0 x05,
0 x06,
0 x07,
// key
0 x08,
0 x09,
0 x0A,
0 x0B,
0 x0C,
0 x0D,
0 x0E,
0 x0F,
0 x00,
0 x00,
0 x00,
0 x00,
// datasize
0 x00,
0 x00,
0 x00,
0 x00,
// size = 0
0 x70,
0 x73,
0 x73,
0 x68,
// 'pssh'
0 x01,
// version = 1
0 x00,
0 x00,
0 x00,
// flags
0 x10,
0 x77,
0 xEF,
0 xEC,
0 xC0,
0 xB2,
0 x4D,
0 x02,
// Common SystemID
0 xAC,
0 xE3,
0 x3C,
0 x1E,
0 x52,
0 xE2,
0 xFB,
0 x4B,
0 x00,
0 x00,
0 x00,
0 x01,
// key count
0 x00,
0 x01,
0 x02,
0 x03,
0 x04,
0 x05,
0 x06,
0 x07,
// key
0 x08,
0 x09,
0 x0A,
0 x0B,
0 x0C,
0 x0D,
0 x0E,
0 x0F,
0 x00,
0 x00,
0 x00,
0 x00
// datasize
// clang-format on
};
TEST(PsshParser, ParseCencInitData)
{
std::vector<std::vector<uint8_t>> keyIds;
bool rv;
rv = ParseCENCInitData(gGoogleWPTCencInitData,
std::size(gGoogleWPTCencInitData), keyIds);
EXPECT_TRUE(rv);
EXPECT_EQ(
1 u, keyIds.size());
EXPECT_EQ(
16 u, keyIds[
0 ].size());
EXPECT_EQ(
0 , memcmp(&keyIds[
0 ].front(), &gGoogleWPTCencInitData[
32 ],
16 ));
rv = ParseCENCInitData(gW3SpecExampleCencInitData,
std::size(gW3SpecExampleCencInitData), keyIds);
EXPECT_TRUE(rv);
EXPECT_EQ(
2 u, keyIds.size());
EXPECT_EQ(
16 u, keyIds[
0 ].size());
EXPECT_EQ(
0 , memcmp(&keyIds[
0 ].front(), &gW3SpecExampleCencInitData[
32 ],
16 ));
EXPECT_EQ(
0 , memcmp(&keyIds[
1 ].front(), &gW3SpecExampleCencInitData[
48 ],
16 ));
rv = ParseCENCInitData(gOverflowBoxSize, std::size(gOverflowBoxSize), keyIds);
EXPECT_FALSE(rv);
EXPECT_EQ(
0 u, keyIds.size());
rv = ParseCENCInitData(gTooLargeKeyCountInitData,
std::size(gTooLargeKeyCountInitData), keyIds);
EXPECT_FALSE(rv);
EXPECT_EQ(
0 u, keyIds.size());
rv = ParseCENCInitData(gNonCencInitData, std::size(gNonCencInitData), keyIds);
EXPECT_TRUE(rv);
EXPECT_EQ(
0 u, keyIds.size());
rv = ParseCENCInitData(gNonPSSHBoxZeroSize, std::size(gNonPSSHBoxZeroSize),
keyIds);
EXPECT_FALSE(rv);
EXPECT_EQ(
0 u, keyIds.size());
rv = ParseCENCInitData(g2xGoogleWPTCencInitData,
std::size(g2xGoogleWPTCencInitData), keyIds);
EXPECT_TRUE(rv);
EXPECT_EQ(
2 u, keyIds.size());
EXPECT_EQ(
16 u, keyIds[
0 ].size());
EXPECT_EQ(
16 u, keyIds[
1 ].size());
EXPECT_EQ(
0 , memcmp(&keyIds[
0 ].front(), &g2xGoogleWPTCencInitData[
32 ],
16 ));
EXPECT_EQ(
0 , memcmp(&keyIds[
1 ].front(), &g2xGoogleWPTCencInitData[
84 ],
16 ));
}
Messung V0.5 in Prozent C=87 H=92 G=89
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-05)
¤
*© Formatika GbR, Deutschland