Support for IPv6 in HTTP socket and BufferReader unittests

* Add Apple MD5 support in DeviceFiles

  [ Merge of http://go/wvgerrit/15544 ]

  Patch courtesy of Spotify.

* Changing vague BufferReader log message

  [ Merge of http://go/wvgerrit/15515 ]

  Amending the buffer reader log message for null parameters in the
  read function to say the type of parameter to help tell the
  difference between Read2, Read2s, Read4, Read4s, Read8, and
  Read8s.

  Bug: 23619044

* Fix HTTP socket tests

  [ Merge of http://go/wvgerrit/15521 ]

  This fixes the build on Jenkins. I missed these when I updated HTTP
  socket because they are not part of the CE CDM test suite.

* Update HttpSocket for IPv6

  [ Merge of http://go/wvgerrit/15517 ]

  Previously, HttpSocket made assumptions about IPv4.
  This CL updates this utility to be agnostic to IPv4 vs IPv6.
  If our servers start resolving to IPv6 addresses in future,
  our tests can now handle this transparently.

* Removed low level warnings from PSSH

  [ Merge of http://go/wvgerrit/15489 ]

  Unneeded warnings in parsing PSSH and in buffer reader
  were appearing in the logs. LOGW commands were replaced
  with LOGV.

  Bug: 23419359

* BufferReader unit tests and hardening.

  [ Merge of http://go/wvgerrit/15449 ]

  Added unit tests for public-facing functions.
  Added protection against null or negative parameters.

  Bug: 23419008

Change-Id: Ia44100a2d1bafe68986ae9a0793214885b21e61e
This commit is contained in:
Rahul Frias
2015-10-01 13:44:32 -07:00
parent 85da7bdb98
commit 9d0c8256a2
12 changed files with 962 additions and 70 deletions

View File

@@ -7,8 +7,15 @@
namespace wvcdm {
bool BufferReader::Read1(uint8_t* v) {
if (v == NULL) {
LOGE("BufferReader::Read1 : Failure during parse: Null output parameter "
"when expecting non-null");
return false;
}
if (!HasBytes(1)) {
LOGW("BufferReader::Read1 : Failure while parsing: Not enough bytes (1)");
LOGV("BufferReader::Read1 : Failure while parsing: "
"Not enough bytes (1)");
return false;
}
@@ -19,9 +26,15 @@ bool BufferReader::Read1(uint8_t* v) {
// Internal implementation of multi-byte reads
template <typename T>
bool BufferReader::Read(T* v) {
if (v == NULL) {
LOGE("BufferReader::Read<T> : Failure during parse: Null output parameter "
"when expecting non-null (%s)", __PRETTY_FUNCTION__);
return false;
}
if (!HasBytes(sizeof(T))) {
LOGW("BufferReader::Read<T> : Failure during parse: Not enough bytes (%u)",
sizeof(T));
LOGV("BufferReader::Read<T> : Failure during parse: "
"Not enough bytes (%u)", sizeof(T));
return false;
}
@@ -41,10 +54,16 @@ bool BufferReader::Read4s(int32_t* v) { return Read(v); }
bool BufferReader::Read8(uint64_t* v) { return Read(v); }
bool BufferReader::Read8s(int64_t* v) { return Read(v); }
bool BufferReader::ReadString(std::string* str, int count) {
bool BufferReader::ReadString(std::string* str, size_t count) {
if (str == NULL) {
LOGE("BufferReader::ReadString : Failure during parse: Null output "
"parameter when expecting non-null");
return false;
}
if (!HasBytes(count)) {
LOGW("BufferReader::ReadString : Parse Failure: Not enough bytes (%d)",
count);
LOGV("BufferReader::ReadString : Parse Failure: "
"Not enough bytes (%d)", count);
return false;
}
@@ -53,9 +72,16 @@ bool BufferReader::ReadString(std::string* str, int count) {
return true;
}
bool BufferReader::ReadVec(std::vector<uint8_t>* vec, int count) {
bool BufferReader::ReadVec(std::vector<uint8_t>* vec, size_t count) {
if (vec == NULL) {
LOGE("BufferReader::ReadVec : Failure during parse: Null output parameter "
"when expecting non-null");
return false;
}
if (!HasBytes(count)) {
LOGW("BufferReader::ReadVec : Parse Failure: Not enough bytes (%d)", count);
LOGV("BufferReader::ReadVec : Parse Failure: "
"Not enough bytes (%d)", count);
return false;
}
@@ -65,10 +91,10 @@ bool BufferReader::ReadVec(std::vector<uint8_t>* vec, int count) {
return true;
}
bool BufferReader::SkipBytes(int bytes) {
bool BufferReader::SkipBytes(size_t bytes) {
if (!HasBytes(bytes)) {
LOGW("BufferReader::SkipBytes : Parse Failure: Not enough bytes (%d)",
bytes);
LOGV("BufferReader::SkipBytes : Parse Failure: "
"Not enough bytes (%d)", bytes);
return false;
}
@@ -77,6 +103,12 @@ bool BufferReader::SkipBytes(int bytes) {
}
bool BufferReader::Read4Into8(uint64_t* v) {
if (v == NULL) {
LOGE("BufferReader::Read4Into8 : Failure during parse: Null output "
"parameter when expecting non-null");
return false;
}
uint32_t tmp;
if (!Read4(&tmp)) {
return false;
@@ -86,6 +118,12 @@ bool BufferReader::Read4Into8(uint64_t* v) {
}
bool BufferReader::Read4sInto8s(int64_t* v) {
if (v == NULL) {
LOGE("BufferReader::Read4sInto8s : Failure during parse: Null output "
"parameter when expecting non-null");
return false;
}
// Beware of the need for sign extension.
int32_t tmp;
if (!Read4s(&tmp)) {
@@ -94,5 +132,4 @@ bool BufferReader::Read4sInto8s(int64_t* v) {
*v = tmp;
return true;
}
} // namespace wvcdm

View File

@@ -16,6 +16,8 @@
#include <CommonCrypto/CommonDigest.h>
#define SHA256 CC_SHA256
#define SHA256_DIGEST_LENGTH CC_SHA256_DIGEST_LENGTH
#define MD5 CC_MD5
#define MD5_DIGEST_LENGTH CC_MD5_DIGEST_LENGTH
#else
#include <openssl/sha.h>
#include <openssl/md5.h>

View File

@@ -61,18 +61,18 @@ bool InitializationData::ExtractWidevinePssh(const CdmInitData& init_data,
// atom size, used for skipping.
uint64_t size;
if (!reader.Read4Into8(&size)) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to read atom size.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to read atom size.");
return false;
}
std::vector<uint8_t> atom_type;
if (!reader.ReadVec(&atom_type, 4)) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to read atom type.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to read atom type.");
return false;
}
if (size == 1) {
if (!reader.Read8(&size)) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to read 64-bit atom "
LOGV("CdmEngine::ExtractWidevinePssh: Unable to read 64-bit atom "
"size.");
return false;
}
@@ -82,10 +82,10 @@ bool InitializationData::ExtractWidevinePssh(const CdmInitData& init_data,
// "pssh"
if (memcmp(&atom_type[0], "pssh", 4)) {
LOGW("CdmEngine::ExtractWidevinePssh: PSSH literal not present.");
LOGV("CdmEngine::ExtractWidevinePssh: PSSH literal not present.");
if (!reader.SkipBytes(size - (reader.pos() - start_pos))) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to skip the rest of the "
"atom.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to skip the rest of "
"the atom.");
return false;
}
continue;
@@ -94,15 +94,15 @@ bool InitializationData::ExtractWidevinePssh(const CdmInitData& init_data,
// version
uint8_t version;
if (!reader.Read1(&version)) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to read PSSH version.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to read PSSH version.");
return false;
}
if (version > 1) {
// unrecognized version - skip.
if (!reader.SkipBytes(size - (reader.pos() - start_pos))) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to skip the rest of the "
"atom.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to skip the rest of "
"the atom.");
return false;
}
continue;
@@ -110,22 +110,22 @@ bool InitializationData::ExtractWidevinePssh(const CdmInitData& init_data,
// flags
if (!reader.SkipBytes(3)) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to skip the PSSH flags.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to skip the PSSH flags.");
return false;
}
// system id
std::vector<uint8_t> system_id;
if (!reader.ReadVec(&system_id, sizeof(kWidevineSystemId))) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to read system ID.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to read system ID.");
return false;
}
if (memcmp(&system_id[0], kWidevineSystemId, sizeof(kWidevineSystemId))) {
// skip non-Widevine PSSH boxes.
if (!reader.SkipBytes(size - (reader.pos() - start_pos))) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to skip the rest of the "
"atom.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to skip the rest of "
"the atom.");
return false;
}
continue;
@@ -135,11 +135,11 @@ bool InitializationData::ExtractWidevinePssh(const CdmInitData& init_data,
// v1 has additional fields for key IDs. We can skip them.
uint32_t num_key_ids;
if (!reader.Read4(&num_key_ids)) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to read num key IDs.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to read num key IDs.");
return false;
}
if (!reader.SkipBytes(num_key_ids * 16)) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to skip key IDs.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to skip key IDs.");
return false;
}
}
@@ -147,13 +147,13 @@ bool InitializationData::ExtractWidevinePssh(const CdmInitData& init_data,
// size of PSSH data
uint32_t data_length;
if (!reader.Read4(&data_length)) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to read PSSH data size.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to read PSSH data size.");
return false;
}
output->clear();
if (!reader.ReadString(output, data_length)) {
LOGW("CdmEngine::ExtractWidevinePssh: Unable to read PSSH data.");
LOGV("CdmEngine::ExtractWidevinePssh: Unable to read PSSH data.");
return false;
}