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

@@ -68,6 +68,7 @@ adb push $OUT/system/bin/initialization_data_unittest /system/bin
adb push $OUT/system/bin/device_files_unittest /system/bin adb push $OUT/system/bin/device_files_unittest /system/bin
adb push $OUT/system/bin/timer_unittest /system/bin adb push $OUT/system/bin/timer_unittest /system/bin
adb push $OUT/system/bin/libwvdrmengine_test /system/bin adb push $OUT/system/bin/libwvdrmengine_test /system/bin
adb push $OUT/system/bin/buffer_reader_test /system/bin
adb install -r $OUT/system/app/MediaDrmAPITest/MediaDrmAPITest.apk adb install -r $OUT/system/app/MediaDrmAPITest/MediaDrmAPITest.apk
cd $ANDROID_BUILD_TOP/vendor/widevine/libwvdrmengine cd $ANDROID_BUILD_TOP/vendor/widevine/libwvdrmengine

View File

@@ -24,9 +24,9 @@ namespace wvcdm {
class BufferReader { class BufferReader {
public: public:
BufferReader(const uint8_t* buf, size_t size) BufferReader(const uint8_t* buf, size_t size)
: buf_(buf), size_(size), pos_(0) {} : buf_(buf), size_(buf != NULL ? size : 0), pos_(0) {}
bool HasBytes(int count) { return (pos() + count <= size()); } bool HasBytes(size_t count) { return (pos() + count <= size()); }
// Read a value from the stream, performing endian correction, // Read a value from the stream, performing endian correction,
// and advance the stream pointer. // and advance the stream pointer.
@@ -38,8 +38,8 @@ class BufferReader {
bool Read8(uint64_t* v) WARN_UNUSED_RESULT; bool Read8(uint64_t* v) WARN_UNUSED_RESULT;
bool Read8s(int64_t* v) WARN_UNUSED_RESULT; bool Read8s(int64_t* v) WARN_UNUSED_RESULT;
bool ReadString(std::string* str, int count) WARN_UNUSED_RESULT; bool ReadString(std::string* str, size_t count) WARN_UNUSED_RESULT;
bool ReadVec(std::vector<uint8_t>* t, int count) WARN_UNUSED_RESULT; bool ReadVec(std::vector<uint8_t>* t, size_t count) WARN_UNUSED_RESULT;
// These variants read a 4-byte integer of the corresponding signedness and // These variants read a 4-byte integer of the corresponding signedness and
// store it in the 8-byte return type. // store it in the 8-byte return type.
@@ -47,7 +47,7 @@ class BufferReader {
bool Read4sInto8s(int64_t* v) WARN_UNUSED_RESULT; bool Read4sInto8s(int64_t* v) WARN_UNUSED_RESULT;
// Advance the stream by this many bytes. // Advance the stream by this many bytes.
bool SkipBytes(int nbytes) WARN_UNUSED_RESULT; bool SkipBytes(size_t nbytes) WARN_UNUSED_RESULT;
const uint8_t* data() const { return buf_; } const uint8_t* data() const { return buf_; }
size_t size() const { return size_; } size_t size() const { return size_; }

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,838 @@
// Copyright 2015 Google Inc. All Rights Reserved.
#include <string>
#include <errno.h>
#include <getopt.h>
#include <gtest/gtest.h>
#include "buffer_reader.h"
namespace wvcdm {
class BufferReaderTest : public testing::Test {
public:
template <typename T>
void WriteToBuffer(uint8_t* buffer, T v) {
for (size_t i = 0; i < sizeof(T); ++i) {
size_t insertAt = (sizeof(T) - i) - 1; // reverse the order of i
size_t shiftAmount = 8 * i;
buffer[insertAt] = (uint8_t)((v >> shiftAmount) & 0xff);
}
}
// populate and validate data by cycling through the alphabet
// (lower case) so that it will work for strings and raw bytes
void PopulateData(uint8_t* dest, size_t byte_count) {
for (size_t i = 0; i < byte_count; i++) {
dest[i] = (uint8_t)(i % 26 + 'a');
}
}
bool ValidateData(const uint8_t* data, size_t byte_count) {
for (size_t i = 0; i < byte_count; i++) {
if (data[i] != (uint8_t)(i % 26 + 'a')) {
return false;
}
}
return true;
}
bool ValidateReader(const BufferReader& reader,
const uint8_t* expectedAddress, size_t expectedSize,
size_t expectedPosition) {
return reader.data() == expectedAddress && reader.size() == expectedSize &&
reader.pos() == expectedPosition;
}
bool CheckRead1(uint8_t input) {
uint8_t raw_data[sizeof(input)];
WriteToBuffer(raw_data, input);
BufferReader reader(raw_data, sizeof(raw_data));
uint8_t read;
return reader.Read1(&read) && input == read &&
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(input));
}
bool CheckRead2(uint16_t input) {
uint8_t raw_data[sizeof(input)];
WriteToBuffer(raw_data, input);
BufferReader reader(raw_data, sizeof(raw_data));
uint16_t read;
return reader.Read2(&read) && input == read &&
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(input));
}
bool CheckRead2s(int16_t input) {
uint8_t raw_data[sizeof(input)];
WriteToBuffer(raw_data, input);
BufferReader reader(raw_data, sizeof(raw_data));
int16_t read;
return reader.Read2s(&read) && input == read &&
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(input));
}
bool CheckRead4(uint32_t input) {
uint8_t raw_data[sizeof(input)];
WriteToBuffer(raw_data, input);
BufferReader reader(raw_data, sizeof(raw_data));
uint32_t read;
return reader.Read4(&read) && input == read &&
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(input));
}
bool CheckRead4s(int32_t input) {
uint8_t raw_data[sizeof(input)];
WriteToBuffer(raw_data, input);
BufferReader reader(raw_data, sizeof(raw_data));
int32_t read;
return reader.Read4s(&read) && input == read &&
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(input));
}
bool CheckRead8(uint64_t input) {
uint8_t raw_data[sizeof(input)];
WriteToBuffer(raw_data, input);
BufferReader reader(raw_data, sizeof(raw_data));
uint64_t read;
return reader.Read8(&read) && input == read &&
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(input));
}
bool CheckRead8s(int64_t input) {
uint8_t raw_data[sizeof(input)];
WriteToBuffer(raw_data, input);
BufferReader reader(raw_data, sizeof(raw_data));
int64_t read;
return reader.Read8s(&read) && input == read &&
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(input));
}
bool CheckRead4Into8(uint32_t input) {
uint8_t raw_data[sizeof(input)];
WriteToBuffer(raw_data, input);
BufferReader reader(raw_data, sizeof(raw_data));
uint64_t read;
return reader.Read4Into8(&read) && read == input &&
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(input));
}
bool CheckRead4sInto8s(int32_t input) {
uint8_t raw_data[sizeof(input)];
WriteToBuffer(raw_data, input);
BufferReader reader(raw_data, sizeof(raw_data));
int64_t read;
return reader.Read4sInto8s(&read) && read == input &&
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(input));
}
};
TEST_F(BufferReaderTest, InitializeGoodDataAndGoodSize) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, InitializeGoodDataAndNoSize) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, 0);
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, 0, 0));
}
TEST_F(BufferReaderTest, InitializeNoDataNoSize) {
BufferReader reader(NULL, 0);
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, InitializeNoDataBadSize) {
BufferReader reader(NULL, 16);
// Buffer reader should default to a size of 0 when given
// NULL data to ensure no reading of bad data
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, HasBytesWithBytes) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
// the reader should have enough bytes from 0 to the size of the buffer
for (size_t i = 0; i <= sizeof(raw_data); i++) {
ASSERT_TRUE(reader.HasBytes(i));
}
ASSERT_FALSE(reader.HasBytes(sizeof(raw_data) + 1));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, HasBytesWithEmptyBuffer) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, 0);
ASSERT_FALSE(reader.HasBytes(1));
ASSERT_TRUE(reader.HasBytes(0));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, 0, 0));
}
TEST_F(BufferReaderTest, HasBytesWithNullBuffer) {
BufferReader reader(NULL, 8);
ASSERT_FALSE(reader.HasBytes(1));
ASSERT_TRUE(reader.HasBytes(0));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, HasBytesAfterAllRead) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
for (size_t i = 0; i < sizeof(raw_data); i++) {
uint8_t read;
ASSERT_TRUE(reader.Read1(&read));
}
ASSERT_FALSE(reader.HasBytes(1));
ASSERT_TRUE(reader.HasBytes(0));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(raw_data)));
}
TEST_F(BufferReaderTest, Read1LargeNumber) { ASSERT_TRUE(CheckRead1(0xFF)); }
TEST_F(BufferReaderTest, Read1SmallNumber) { ASSERT_TRUE(CheckRead1(0x0F)); }
TEST_F(BufferReaderTest, Read1Zero) { ASSERT_TRUE(CheckRead1(0)); }
TEST_F(BufferReaderTest, Read1WithNoData) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, 0);
uint8_t read;
ASSERT_FALSE(reader.Read1(&read));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, 0, 0));
}
TEST_F(BufferReaderTest, Read1WithNullBuffer) {
BufferReader reader(NULL, 16);
uint8_t read;
ASSERT_FALSE(reader.Read1(&read));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, Read1WithNullReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.Read1(NULL));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, Read2LargeNumber) { ASSERT_TRUE(CheckRead2(30000)); }
TEST_F(BufferReaderTest, Read2SmallNumber) { ASSERT_TRUE(CheckRead2(10)); }
TEST_F(BufferReaderTest, Read2Zero) { ASSERT_TRUE(CheckRead2(0)); }
TEST_F(BufferReaderTest, Read2WithNoData) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, 0);
uint16_t read;
ASSERT_FALSE(reader.Read2(&read));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, 0, 0));
}
TEST_F(BufferReaderTest, Read2WithNullBuffer) {
BufferReader reader(NULL, 16);
uint16_t read;
ASSERT_FALSE(reader.Read2(&read));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, Read2WithNullReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.Read2(NULL));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, Read2sLargePositive) {
ASSERT_TRUE(CheckRead2s(30000));
}
TEST_F(BufferReaderTest, Read2sSmallPositive) { ASSERT_TRUE(CheckRead2s(10)); }
TEST_F(BufferReaderTest, Read2sZero) { ASSERT_TRUE(CheckRead2s(0)); }
TEST_F(BufferReaderTest, Read2sSmallNegative) { ASSERT_TRUE(CheckRead2s(-10)); }
TEST_F(BufferReaderTest, Read2sLargeNegative) {
ASSERT_TRUE(CheckRead2s(-30000));
}
TEST_F(BufferReaderTest, Read2sWithNoData) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, 0);
int16_t read;
ASSERT_FALSE(reader.Read2s(&read));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, 0, 0));
}
TEST_F(BufferReaderTest, Read2sWithNullBuffer) {
BufferReader reader(NULL, 16);
int16_t read;
ASSERT_FALSE(reader.Read2s(&read));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, Read2sWithNullReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.Read2s(NULL));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, Read4LargeNumber) {
// a number near uint32's max value
ASSERT_TRUE(CheckRead4(2000000000));
}
TEST_F(BufferReaderTest, Read4SmallNumber) { ASSERT_TRUE(CheckRead4(10)); }
TEST_F(BufferReaderTest, Read4Zero) { ASSERT_TRUE(CheckRead4(0)); }
TEST_F(BufferReaderTest, Read4WithNoData) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, 0);
uint32_t read;
ASSERT_FALSE(reader.Read4(&read));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, 0, 0));
}
TEST_F(BufferReaderTest, Read4WithNullBuffer) {
BufferReader reader(NULL, 16);
uint32_t read;
ASSERT_FALSE(reader.Read4(&read));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, Read4WithNullReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.Read4(NULL));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, Read4sLargePositive) {
// a number near int32's max value
ASSERT_TRUE(CheckRead4s(2000000000));
}
TEST_F(BufferReaderTest, Read4sSmallPositive) { ASSERT_TRUE(CheckRead4s(10)); }
TEST_F(BufferReaderTest, Read4sZero) { ASSERT_TRUE(CheckRead4s(0)); }
TEST_F(BufferReaderTest, Read4sSmallNegative) { ASSERT_TRUE(CheckRead4s(-10)); }
TEST_F(BufferReaderTest, Read4sLargeNegative) {
// a number near int32's max negative value
ASSERT_TRUE(CheckRead4s(-2000000000));
}
TEST_F(BufferReaderTest, Read4sWithNoData) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, 0);
int32_t read;
ASSERT_FALSE(reader.Read4s(&read));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, 0, 0));
}
TEST_F(BufferReaderTest, Read4sWithNullBuffer) {
BufferReader reader(NULL, 16);
int32_t read;
ASSERT_FALSE(reader.Read4s(&read));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, Read4sWithNullReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.Read4s(NULL));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, Read8LargeNumber) {
// a number near uint64's max value
ASSERT_TRUE(CheckRead8(9000000000000000000));
}
TEST_F(BufferReaderTest, Read8SmallNumber) { ASSERT_TRUE(CheckRead8(10)); }
TEST_F(BufferReaderTest, Read8Zero) { ASSERT_TRUE(CheckRead8(0)); }
TEST_F(BufferReaderTest, Read8WithNoData) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, 0);
uint64_t read;
ASSERT_FALSE(reader.Read8(&read));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, 0, 0));
}
TEST_F(BufferReaderTest, Read8WithNullBuffer) {
BufferReader reader(NULL, 16);
uint64_t read;
ASSERT_FALSE(reader.Read8(&read));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, Read8WithNullReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.Read8(NULL));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, Read8sLargePositive) {
// a number near int64's max value
ASSERT_TRUE(CheckRead8s(9000000000000000000));
}
TEST_F(BufferReaderTest, Read8sSmallPositive) { ASSERT_TRUE(CheckRead8s(10)); }
TEST_F(BufferReaderTest, Read8sZero) { ASSERT_TRUE(CheckRead8s(0)); }
TEST_F(BufferReaderTest, Read8sSmallNegative) { ASSERT_TRUE(CheckRead8s(-10)); }
TEST_F(BufferReaderTest, Read8sLargeNegative) {
// a number near int64's max negative value
ASSERT_TRUE(CheckRead8s(-9000000000000000000));
}
TEST_F(BufferReaderTest, Read8sWithNoData) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, 0);
int64_t read;
ASSERT_FALSE(reader.Read8s(&read));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, 0, 0));
}
TEST_F(BufferReaderTest, Read8sWithNullBuffer) {
BufferReader reader(NULL, 16);
int64_t read;
ASSERT_FALSE(reader.Read8s(&read));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, Read8sWithNullReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.Read8s(NULL));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, ReadString) {
uint8_t raw_data[5];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
std::string read;
ASSERT_TRUE(reader.ReadString(&read, sizeof(raw_data)));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(read.length() == sizeof(raw_data));
ASSERT_TRUE(ValidateData((const uint8_t*)read.c_str(), read.length()));
ASSERT_TRUE(
ValidateReader(reader, raw_data, sizeof(raw_data), sizeof(raw_data)));
}
TEST_F(BufferReaderTest, ReadStringNullSource) {
BufferReader reader(NULL, 5);
std::string read;
ASSERT_FALSE(reader.ReadString(&read, 5));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, ReadStringNullReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.ReadString(NULL, 5));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, ReadStringZeroCount) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
std::string read;
ASSERT_TRUE(reader.ReadString(&read, 0));
ASSERT_TRUE(0 == read.length());
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, ReadStringTooLarge) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
std::string read;
ASSERT_FALSE(reader.ReadString(&read, sizeof(raw_data) * 2));
ASSERT_TRUE(0 == read.length());
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, ReadVector) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
std::vector<uint8_t> read;
ASSERT_TRUE(reader.ReadVec(&read, 4));
ASSERT_TRUE(read.size() == 4);
for (size_t i = 0; i < 4; i++) {
ASSERT_TRUE(raw_data[i] == read[i]);
}
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 4));
}
TEST_F(BufferReaderTest, ReadVectorTooLarge) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
std::vector<uint8_t> read;
ASSERT_FALSE(reader.ReadVec(&read, sizeof(raw_data) * 2));
ASSERT_TRUE(0 == read.size());
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, ReadVectorNullSource) {
BufferReader reader(NULL, 16);
std::vector<uint8_t> read;
ASSERT_FALSE(reader.ReadVec(&read, 4));
ASSERT_TRUE(0 == read.size());
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, ReadVectorNullReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.ReadVec(NULL, 4));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, ReadVectorNone) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
std::vector<uint8_t> read;
ASSERT_TRUE(reader.ReadVec(&read, 0));
ASSERT_TRUE(0 == read.size());
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, Read4Into84Bytes) {
ASSERT_TRUE(CheckRead4Into8(0xFFFFFF));
}
TEST_F(BufferReaderTest, Read4Into83Bytes) {
ASSERT_TRUE(CheckRead4Into8(0xFFFF));
}
TEST_F(BufferReaderTest, Read4Into82Bytes) {
ASSERT_TRUE(CheckRead4Into8(0xFF));
}
TEST_F(BufferReaderTest, Read4Into8Zero) { ASSERT_TRUE(CheckRead4Into8(0)); }
TEST_F(BufferReaderTest, Read4Into8NullSource) {
BufferReader reader(NULL, 4);
uint64_t read;
ASSERT_FALSE(reader.Read4Into8(&read));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, Read4Into8TooLittleData) {
uint8_t raw_data[2];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
uint64_t read;
ASSERT_FALSE(reader.Read4Into8(&read));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, Read4Into8NoReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.Read4Into8(NULL));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, Read4sInto8s4Bytes) {
ASSERT_TRUE(CheckRead4sInto8s(0x0FFFFFFF));
}
TEST_F(BufferReaderTest, Read4sInto8s3Bytes) {
ASSERT_TRUE(CheckRead4sInto8s(0xFFFFFF));
}
TEST_F(BufferReaderTest, Read4sInto8s2Bytes) {
ASSERT_TRUE(CheckRead4sInto8s(0xFFFF));
}
TEST_F(BufferReaderTest, Read4sInto8s1Bytes) {
ASSERT_TRUE(CheckRead4sInto8s(0xFF));
}
TEST_F(BufferReaderTest, Read4sInto8sZero) {
ASSERT_TRUE(CheckRead4sInto8s(0));
}
TEST_F(BufferReaderTest, Read4sInto8sNegative) {
ASSERT_TRUE(CheckRead4sInto8s(-100));
}
TEST_F(BufferReaderTest, Read4sInto8sNullSource) {
BufferReader reader(NULL, 4);
int64_t read;
ASSERT_FALSE(reader.Read4sInto8s(&read));
ASSERT_TRUE(ValidateReader(reader, NULL, 0, 0));
}
TEST_F(BufferReaderTest, Read4sInto8sTooLittleData) {
uint8_t raw_data[2];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
int64_t read;
ASSERT_FALSE(reader.Read4sInto8s(&read));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, Read4sInto8sNoReturn) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.Read4sInto8s(NULL));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, SkipBytesNone) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_TRUE(reader.SkipBytes(0));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
TEST_F(BufferReaderTest, SkipBytes) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_TRUE(reader.SkipBytes(4));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 4));
}
TEST_F(BufferReaderTest, SkipBytesTooLarge) {
uint8_t raw_data[16];
PopulateData(raw_data, sizeof(raw_data));
BufferReader reader(raw_data, sizeof(raw_data));
ASSERT_FALSE(reader.SkipBytes(sizeof(raw_data) * 2));
ASSERT_TRUE(ValidateData(raw_data, sizeof(raw_data)));
ASSERT_TRUE(ValidateReader(reader, raw_data, sizeof(raw_data), 0));
}
} // namespace

View File

@@ -105,7 +105,7 @@ bool SocketWait(int fd, bool for_read, int timeout_in_ms) {
// static // static
bool HttpSocket::ParseUrl(const std::string& url, std::string* scheme, bool HttpSocket::ParseUrl(const std::string& url, std::string* scheme,
bool* secure_connect, std::string* domain_name, bool* secure_connect, std::string* domain_name,
int* port, std::string* path) { std::string* port, std::string* path) {
size_t offset = 0; size_t offset = 0;
if (!Tokenize(url, "://", offset, scheme, &offset)) { if (!Tokenize(url, "://", offset, scheme, &offset)) {
@@ -117,10 +117,10 @@ bool HttpSocket::ParseUrl(const std::string& url, std::string* scheme,
// Otherwise, consider the scheme unsupported and fail. // Otherwise, consider the scheme unsupported and fail.
if (*scheme == "http") { if (*scheme == "http") {
*secure_connect = false; *secure_connect = false;
*port = 80; port->assign("80");
} else if (*scheme == "https") { } else if (*scheme == "https") {
*secure_connect = true; *secure_connect = true;
*port = 443; port->assign("443");
} else { } else {
LOGE("Invalid URL, scheme not supported: %s", url.c_str()); LOGE("Invalid URL, scheme not supported: %s", url.c_str());
return false; return false;
@@ -140,8 +140,9 @@ bool HttpSocket::ParseUrl(const std::string& url, std::string* scheme,
std::string domain_name_without_port; std::string domain_name_without_port;
size_t port_offset; size_t port_offset;
if (Tokenize(*domain_name, ":", 0, &domain_name_without_port, &port_offset)) { if (Tokenize(*domain_name, ":", 0, &domain_name_without_port, &port_offset)) {
*port = atoi(domain_name->c_str() + port_offset); port->assign(domain_name->c_str() + port_offset);
if (*port <= 0 || *port >= 65536) { int port_num = atoi(port->c_str());
if (port_num <= 0 || port_num >= 65536) {
LOGE("Invalid URL, port not valid: %s", url.c_str()); LOGE("Invalid URL, port not valid: %s", url.c_str());
return false; return false;
} }
@@ -180,8 +181,24 @@ bool HttpSocket::Connect(int timeout_in_ms) {
return false; return false;
} }
// lookup the server IP
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG;
struct addrinfo* addr_info = NULL;
int ret = getaddrinfo(domain_name_.c_str(), port_.c_str(), &hints,
&addr_info);
if (ret != 0) {
LOGE("getaddrinfo failed, errno = %d", ret);
return false;
}
// get a socket // get a socket
socket_fd_ = socket(AF_INET, SOCK_STREAM, 0); socket_fd_ = socket(addr_info->ai_family, addr_info->ai_socktype,
addr_info->ai_protocol);
if (socket_fd_ < 0) { if (socket_fd_ < 0) {
LOGE("cannot open socket, errno = %d", errno); LOGE("cannot open socket, errno = %d", errno);
return false; return false;
@@ -200,24 +217,6 @@ bool HttpSocket::Connect(int timeout_in_ms) {
return false; return false;
} }
// lookup the server IP
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo* addr_info = NULL;
int ret = getaddrinfo(domain_name_.c_str(), NULL, &hints, &addr_info);
if (ret != 0) {
LOGE("getaddrinfo failed, errno = %d", ret);
return false;
}
// set the port
struct sockaddr_in* addr_ipv4 =
reinterpret_cast<struct sockaddr_in*>(addr_info->ai_addr);
addr_ipv4->sin_port = htons(port_);
// connect to the server // connect to the server
ret = connect(socket_fd_, addr_info->ai_addr, addr_info->ai_addrlen); ret = connect(socket_fd_, addr_info->ai_addr, addr_info->ai_addrlen);
freeaddrinfo(addr_info); freeaddrinfo(addr_info);

View File

@@ -3,6 +3,8 @@
#ifndef CDM_TEST_HTTP_SOCKET_H_ #ifndef CDM_TEST_HTTP_SOCKET_H_
#define CDM_TEST_HTTP_SOCKET_H_ #define CDM_TEST_HTTP_SOCKET_H_
#include <stdlib.h>
#include <string> #include <string>
#include <gtest/gtest_prod.h> #include <gtest/gtest_prod.h>
@@ -25,7 +27,7 @@ class HttpSocket {
const std::string& scheme() const { return scheme_; } const std::string& scheme() const { return scheme_; }
bool secure_connect() const { return secure_connect_; } bool secure_connect() const { return secure_connect_; }
const std::string& domain_name() const { return domain_name_; } const std::string& domain_name() const { return domain_name_; }
int port() const { return port_; } int port() const { return atoi(port_.c_str()); }
const std::string& resource_path() const { return resource_path_; } const std::string& resource_path() const { return resource_path_; }
int Read(char* data, int len, int timeout_in_ms); int Read(char* data, int len, int timeout_in_ms);
@@ -34,13 +36,13 @@ class HttpSocket {
private: private:
static bool ParseUrl(const std::string& url, std::string* scheme, static bool ParseUrl(const std::string& url, std::string* scheme,
bool* secure_connect, std::string* domain_name, bool* secure_connect, std::string* domain_name,
int* port, std::string* path); std::string* port, std::string* path);
FRIEND_TEST(HttpSocketTest, ParseUrlTest); FRIEND_TEST(HttpSocketTest, ParseUrlTest);
std::string scheme_; std::string scheme_;
bool secure_connect_; bool secure_connect_;
std::string domain_name_; std::string domain_name_;
int port_; std::string port_;
std::string resource_path_; std::string resource_path_;
bool valid_url_; bool valid_url_;

View File

@@ -98,7 +98,7 @@ struct ParseUrlTests {
const char* scheme; const char* scheme;
bool secure_connect; bool secure_connect;
const char* domain_name; const char* domain_name;
int port; const char* port;
const char* path; const char* path;
}; };
@@ -108,7 +108,7 @@ ParseUrlTests parse_url_tests[] = {
"https", // scheme "https", // scheme
true, // secure_connect true, // secure_connect
"code.google.com", // domain_name "code.google.com", // domain_name
443, // port "443", // port
"/p/googletest/wiki/Primer", // path "/p/googletest/wiki/Primer", // path
}, },
{ {
@@ -116,7 +116,7 @@ ParseUrlTests parse_url_tests[] = {
"http", // scheme "http", // scheme
false, // secure_connect false, // secure_connect
"code.google.com", // domain_name "code.google.com", // domain_name
80, // port "80", // port
"/p/googletest/wiki/Primer/", // path "/p/googletest/wiki/Primer/", // path
}, },
{ {
@@ -124,7 +124,7 @@ ParseUrlTests parse_url_tests[] = {
"http", // scheme "http", // scheme
false, // secure_connect false, // secure_connect
"code.google.com", // domain_name "code.google.com", // domain_name
80, // port "80", // port
"/", // path "/", // path
}, },
{ {
@@ -132,7 +132,7 @@ ParseUrlTests parse_url_tests[] = {
"http", // scheme "http", // scheme
false, // secure_connect false, // secure_connect
"code.google.com", // domain_name "code.google.com", // domain_name
80, // port "80", // port
"/", // path "/", // path
}, },
{ {
@@ -140,7 +140,7 @@ ParseUrlTests parse_url_tests[] = {
"http", // scheme "http", // scheme
false, // secure_connect false, // secure_connect
"10.11.12.13", // domain_name "10.11.12.13", // domain_name
8888, // port "8888", // port
"/drm", // path "/drm", // path
}, },
{ {
@@ -148,7 +148,7 @@ ParseUrlTests parse_url_tests[] = {
"http", // scheme "http", // scheme
false, // secure_connect false, // secure_connect
"10.11.12.13", // domain_name "10.11.12.13", // domain_name
8888, // port "8888", // port
"/", // path "/", // path
}, },
{ {
@@ -156,7 +156,7 @@ ParseUrlTests parse_url_tests[] = {
"https", // scheme "https", // scheme
true, // secure_connect true, // secure_connect
"10.11.12.13", // domain_name "10.11.12.13", // domain_name
8888, // port "8888", // port
"/", // path "/", // path
}, },
{NULL, NULL, false, NULL, 0, NULL} // list terminator {NULL, NULL, false, NULL, 0, NULL} // list terminator
@@ -166,7 +166,7 @@ TEST_F(HttpSocketTest, ParseUrlTest) {
std::string scheme; std::string scheme;
bool secure_connect; bool secure_connect;
std::string domain_name; std::string domain_name;
int port; std::string port;
std::string path; std::string path;
ParseUrlTests* test = NULL; ParseUrlTests* test = NULL;
@@ -205,6 +205,7 @@ TEST_F(HttpSocketTest, RoundTripTest) {
int main(int argc, char** argv) { int main(int argc, char** argv) {
using namespace wvcdm; using namespace wvcdm;
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
std::string temp; std::string temp;

View File

@@ -22,6 +22,13 @@
#include "log.h" #include "log.h"
#include <utils/Log.h> #include <utils/Log.h>
/*
* Uncomment the line below if you want to have the LOGV messages to print
* IMPORTANT : this will affect all of CDM
*/
// #define LOG_NDEBUG 0
namespace wvcdm { namespace wvcdm {
LogPriority g_cutoff = LOG_VERBOSE; LogPriority g_cutoff = LOG_VERBOSE;

View File

@@ -7,6 +7,10 @@ test_name := base64_test
test_src_dir := ../core/test test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk include $(LOCAL_PATH)/unit-test.mk
test_name := buffer_reader_test
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_name := cdm_engine_test test_name := cdm_engine_test
test_src_dir := ../core/test test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk include $(LOCAL_PATH)/unit-test.mk

View File

@@ -53,6 +53,7 @@ adb_shell_run /system/bin/license_unittest
adb_shell_run /system/bin/initialization_data_unittest adb_shell_run /system/bin/initialization_data_unittest
adb_shell_run /system/bin/device_files_unittest adb_shell_run /system/bin/device_files_unittest
adb_shell_run /system/bin/timer_unittest adb_shell_run /system/bin/timer_unittest
adb_shell_run /system/bin/buffer_reader_test
library_path="/system/vendor/lib/mediadrm/ " library_path="/system/vendor/lib/mediadrm/ "
adb_shell_run LD_LIBRARY_PATH=$library_path /system/bin/libwvdrmengine_test adb_shell_run LD_LIBRARY_PATH=$library_path /system/bin/libwvdrmengine_test