Version 18.1
Updates to OEMCrypto API, OPK, ODK, and unit tests. See the file CHANGELOG.md for details.
This commit is contained in:
committed by
John "Juce" Bruce
parent
5232c51e33
commit
562f64f292
11
util/include/error_string_util.h
Normal file
11
util/include/error_string_util.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef ERROR_STRING_UTIL_H_
|
||||
#define ERROR_STRING_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace wvutil {
|
||||
|
||||
const std::string OEMCryptoResultToString(int oemcrypto_result);
|
||||
|
||||
} // namespace wvutil
|
||||
#endif // ERROR_STRING_UTIL_H_
|
||||
@@ -28,7 +28,7 @@ static const std::string kOemCertificateFileName = "oemcert.bin";
|
||||
static const std::string kOemCertificateFileNamePrefix = "oemcert_";
|
||||
|
||||
// File class. The implementation is platform dependent.
|
||||
class CORE_UTIL_EXPORT File {
|
||||
class File {
|
||||
public:
|
||||
File() {}
|
||||
virtual ~File() {}
|
||||
@@ -39,7 +39,7 @@ class CORE_UTIL_EXPORT File {
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(File);
|
||||
};
|
||||
|
||||
class CORE_UTIL_EXPORT FileSystem {
|
||||
class FileSystem {
|
||||
public:
|
||||
FileSystem();
|
||||
FileSystem(const std::string& origin, void* extra_data);
|
||||
|
||||
@@ -77,31 +77,34 @@ struct LoggingUidSetter {
|
||||
// This function is supplied for cases where the system layer does not
|
||||
// initialize logging. This is also needed to initialize logging in
|
||||
// unit tests.
|
||||
CORE_UTIL_EXPORT void InitLogging();
|
||||
void InitLogging();
|
||||
|
||||
#ifdef __GNUC__
|
||||
[[gnu::format(printf, 5, 6)]] CORE_UTIL_EXPORT void Log(const char* file,
|
||||
const char* function,
|
||||
int line,
|
||||
LogPriority level,
|
||||
const char* fmt, ...);
|
||||
#else
|
||||
CORE_UTIL_EXPORT void Log(const char* file, const char* function, int line,
|
||||
LogPriority level, const char* fmt, ...);
|
||||
[[gnu::format(printf, 5, 6)]]
|
||||
#endif
|
||||
void Log(const char* file, const char* function, int line,
|
||||
LogPriority level, const char* fmt, ...);
|
||||
|
||||
// Log APIs
|
||||
#ifndef LOGE
|
||||
# define LOGE(...) \
|
||||
#ifdef CDM_DISABLE_LOGGING
|
||||
# define LOGE(...) (void)0
|
||||
# define LOGW(...) (void)0
|
||||
# define LOGI(...) (void)0
|
||||
# define LOGD(...) (void)0
|
||||
# define LOGV(...) (void)0
|
||||
#else
|
||||
# ifndef LOGE
|
||||
# define LOGE(...) \
|
||||
Log(__FILE__, __func__, __LINE__, wvutil::CDM_LOG_ERROR, __VA_ARGS__)
|
||||
# define LOGW(...) \
|
||||
# define LOGW(...) \
|
||||
Log(__FILE__, __func__, __LINE__, wvutil::CDM_LOG_WARN, __VA_ARGS__)
|
||||
# define LOGI(...) \
|
||||
# define LOGI(...) \
|
||||
Log(__FILE__, __func__, __LINE__, wvutil::CDM_LOG_INFO, __VA_ARGS__)
|
||||
# define LOGD(...) \
|
||||
# define LOGD(...) \
|
||||
Log(__FILE__, __func__, __LINE__, wvutil::CDM_LOG_DEBUG, __VA_ARGS__)
|
||||
# define LOGV(...) \
|
||||
# define LOGV(...) \
|
||||
Log(__FILE__, __func__, __LINE__, wvutil::CDM_LOG_VERBOSE, __VA_ARGS__)
|
||||
# endif
|
||||
#endif
|
||||
} // namespace wvutil
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
using ssize_t = SSIZE_T;
|
||||
|
||||
inline void sleep(int seconds) { Sleep(seconds * 1000); }
|
||||
CORE_UTIL_EXPORT int setenv(const char* key, const char* value, int overwrite);
|
||||
int setenv(const char* key, const char* value, int overwrite);
|
||||
#else
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/types.h>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
namespace wvutil {
|
||||
|
||||
// A simple reader-writer mutex implementation that mimics the one from C++17
|
||||
class CORE_UTIL_EXPORT shared_mutex {
|
||||
class shared_mutex {
|
||||
public:
|
||||
shared_mutex() : reader_count_(0), has_writer_(false) {}
|
||||
~shared_mutex();
|
||||
|
||||
@@ -15,53 +15,46 @@
|
||||
namespace wvutil {
|
||||
|
||||
// ASCII hex to Binary conversion.
|
||||
CORE_UTIL_EXPORT std::vector<uint8_t> a2b_hex(const std::string& b);
|
||||
CORE_UTIL_EXPORT std::vector<uint8_t> a2b_hex(const std::string& label,
|
||||
const std::string& b);
|
||||
CORE_UTIL_EXPORT std::string a2bs_hex(const std::string& b);
|
||||
std::vector<uint8_t> a2b_hex(const std::string& b);
|
||||
std::vector<uint8_t> a2b_hex(const std::string& label,
|
||||
const std::string& b);
|
||||
std::string a2bs_hex(const std::string& b);
|
||||
|
||||
// Binary to ASCII hex conversion. The default versions limit output to 2k to
|
||||
// protect us from log spam. The unlimited version has no length limit.
|
||||
CORE_UTIL_EXPORT std::string b2a_hex(const std::vector<uint8_t>& b);
|
||||
CORE_UTIL_EXPORT std::string unlimited_b2a_hex(const std::vector<uint8_t>& b);
|
||||
CORE_UTIL_EXPORT std::string b2a_hex(const std::string& b);
|
||||
CORE_UTIL_EXPORT std::string unlimited_b2a_hex(const std::string& b);
|
||||
CORE_UTIL_EXPORT std::string HexEncode(const uint8_t* bytes, size_t size);
|
||||
CORE_UTIL_EXPORT std::string UnlimitedHexEncode(const uint8_t* bytes,
|
||||
size_t size);
|
||||
std::string b2a_hex(const std::vector<uint8_t>& b);
|
||||
std::string unlimited_b2a_hex(const std::vector<uint8_t>& b);
|
||||
std::string b2a_hex(const std::string& b);
|
||||
std::string unlimited_b2a_hex(const std::string& b);
|
||||
std::string HexEncode(const uint8_t* bytes, size_t size);
|
||||
std::string UnlimitedHexEncode(const uint8_t* bytes, size_t size);
|
||||
|
||||
// Base64 encoding/decoding.
|
||||
// Converts binary data into the ASCII Base64 character set and vice
|
||||
// versa using the encoding rules defined in RFC4648 section 4.
|
||||
CORE_UTIL_EXPORT std::string Base64Encode(
|
||||
const std::vector<uint8_t>& bin_input);
|
||||
CORE_UTIL_EXPORT std::string Base64Encode(const std::string& bin_input);
|
||||
CORE_UTIL_EXPORT std::vector<uint8_t> Base64Decode(
|
||||
const std::string& bin_input);
|
||||
std::string Base64Encode(const std::vector<uint8_t>& bin_input);
|
||||
std::string Base64Encode(const std::string& bin_input);
|
||||
std::vector<uint8_t> Base64Decode(const std::string& bin_input);
|
||||
|
||||
// URL-Safe Base64 encoding/decoding.
|
||||
// Converts binary data into the URL/Filename safe ASCII Base64
|
||||
// character set and vice versa using the encoding rules defined in
|
||||
// RFC4648 section 5.
|
||||
CORE_UTIL_EXPORT std::string Base64SafeEncode(
|
||||
const std::vector<uint8_t>& bin_input);
|
||||
CORE_UTIL_EXPORT std::string Base64SafeEncode(const std::string& bin_input);
|
||||
CORE_UTIL_EXPORT std::vector<uint8_t> Base64SafeDecode(
|
||||
const std::string& bin_input);
|
||||
std::string Base64SafeEncode(const std::vector<uint8_t>& bin_input);
|
||||
std::string Base64SafeEncode(const std::string& bin_input);
|
||||
std::vector<uint8_t> Base64SafeDecode(const std::string& bin_input);
|
||||
// URL-Safe Base64 encoding without padding.
|
||||
// Similar to Base64SafeEncode(), without any padding character '='
|
||||
// at the end.
|
||||
CORE_UTIL_EXPORT std::string Base64SafeEncodeNoPad(
|
||||
const std::vector<uint8_t>& bin_input);
|
||||
CORE_UTIL_EXPORT std::string Base64SafeEncodeNoPad(
|
||||
const std::string& bin_input);
|
||||
std::string Base64SafeEncodeNoPad(const std::vector<uint8_t>& bin_input);
|
||||
std::string Base64SafeEncodeNoPad(const std::string& bin_input);
|
||||
|
||||
// Host to Network/Network to Host conversion.
|
||||
CORE_UTIL_EXPORT int64_t htonll64(int64_t x);
|
||||
CORE_UTIL_EXPORT inline int64_t ntohll64(int64_t x) { return htonll64(x); }
|
||||
int64_t htonll64(int64_t x);
|
||||
inline int64_t ntohll64(int64_t x) { return htonll64(x); }
|
||||
|
||||
// Encode unsigned integer into a big endian formatted string.
|
||||
CORE_UTIL_EXPORT std::string EncodeUint32(uint32_t u);
|
||||
std::string EncodeUint32(uint32_t u);
|
||||
|
||||
} // namespace wvutil
|
||||
|
||||
|
||||
18
util/include/string_format.h
Normal file
18
util/include/string_format.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
#ifndef WVCDM_UTIL_STRING_FORMAT_H_
|
||||
#define WVCDM_UTIL_STRING_FORMAT_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace wvutil {
|
||||
|
||||
#ifdef __GNUC__
|
||||
[[gnu::format(printf, 2, 3)]]
|
||||
#endif
|
||||
bool FormatString(std::string* out, const char* fmt, ...);
|
||||
|
||||
} // namespace wvutil
|
||||
|
||||
#endif // WVCDM_UTIL_STRING_FORMAT_H_
|
||||
@@ -9,23 +9,11 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
# ifdef CORE_UTIL_IMPLEMENTATION
|
||||
# define CORE_UTIL_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define CORE_UTIL_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
|
||||
# define CORE_UTIL_IGNORE_DEPRECATED
|
||||
# define CORE_UTIL_RESTORE_WARNINGS
|
||||
|
||||
#else
|
||||
|
||||
# ifdef CORE_UTIL_IMPLEMENTATION
|
||||
# define CORE_UTIL_EXPORT __attribute__((visibility("default")))
|
||||
# else
|
||||
# define CORE_UTIL_EXPORT
|
||||
# endif
|
||||
|
||||
# ifdef __GNUC__
|
||||
# define CORE_UTIL_IGNORE_DEPRECATED \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
|
||||
@@ -3,17 +3,15 @@
|
||||
# Agreement.
|
||||
{
|
||||
'conditions': [
|
||||
[
|
||||
'privacy_crypto_impl=="openssl"', {
|
||||
'libraries': [
|
||||
'-lcrypto',
|
||||
],
|
||||
}, # privacy_crypto_impl=="openssl"
|
||||
'privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"', {
|
||||
'dependencies': [
|
||||
'<(boringssl_libcrypto_path)',
|
||||
], # dependencies
|
||||
}, # privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"
|
||||
],
|
||||
['privacy_crypto_impl=="openssl"', {
|
||||
'libraries': [
|
||||
'-lcrypto',
|
||||
],
|
||||
}],
|
||||
['privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"', {
|
||||
'dependencies': [
|
||||
'<(boringssl_libcrypto_path)',
|
||||
], # dependencies
|
||||
}],
|
||||
], # conditions
|
||||
}
|
||||
|
||||
@@ -3,18 +3,16 @@
|
||||
# Agreement.
|
||||
{
|
||||
'conditions': [
|
||||
[
|
||||
'privacy_crypto_impl=="openssl"', {
|
||||
'libraries': [
|
||||
'-lcrypto',
|
||||
'-lssl',
|
||||
],
|
||||
}, # privacy_crypto_impl=="openssl"
|
||||
'privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"', {
|
||||
'dependencies': [
|
||||
'<(boringssl_libssl_path)',
|
||||
], # dependencies
|
||||
}, # privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"
|
||||
],
|
||||
['privacy_crypto_impl=="openssl"', {
|
||||
'libraries': [
|
||||
'-lcrypto',
|
||||
'-lssl',
|
||||
],
|
||||
}],
|
||||
['privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"', {
|
||||
'dependencies': [
|
||||
'<(boringssl_libssl_path)',
|
||||
], # dependencies
|
||||
}],
|
||||
], # conditions
|
||||
}
|
||||
|
||||
171
util/src/error_string_util.cpp
Normal file
171
util/src/error_string_util.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
|
||||
#include "error_string_util.h"
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvutil {
|
||||
const std::string OEMCryptoResultToString(int oemcrypto_result) {
|
||||
switch (oemcrypto_result) {
|
||||
case OEMCrypto_SUCCESS:
|
||||
return "SUCCESS";
|
||||
case OEMCrypto_ERROR_INIT_FAILED:
|
||||
return "INIT_FAILED";
|
||||
case OEMCrypto_ERROR_TERMINATE_FAILED:
|
||||
return "TERMINATE_FAILED";
|
||||
case OEMCrypto_ERROR_OPEN_FAILURE:
|
||||
return "OPEN_FAILURE";
|
||||
case OEMCrypto_ERROR_CLOSE_FAILURE:
|
||||
return "CLOSE_FAILURE";
|
||||
case OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED:
|
||||
return "ENTER_SECURE_PLAYBACK_FAILED";
|
||||
case OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED:
|
||||
return "EXIT_SECURE_PLAYBACK_FAILED";
|
||||
case OEMCrypto_ERROR_SHORT_BUFFER:
|
||||
return "SHORT_BUFFER";
|
||||
case OEMCrypto_ERROR_NO_DEVICE_KEY:
|
||||
return "NO_DEVICE_KEY";
|
||||
case OEMCrypto_ERROR_NO_ASSET_KEY:
|
||||
return "NO_ASSET_KEY";
|
||||
case OEMCrypto_ERROR_KEYBOX_INVALID:
|
||||
return "KEYBOX_INVALID";
|
||||
case OEMCrypto_ERROR_NO_KEYDATA:
|
||||
return "NO_KEYDATA";
|
||||
case OEMCrypto_ERROR_NO_CW:
|
||||
return "NO_CW";
|
||||
case OEMCrypto_ERROR_DECRYPT_FAILED:
|
||||
return "DECRYPT_FAILED";
|
||||
case OEMCrypto_ERROR_WRITE_KEYBOX:
|
||||
return "WRITE_KEYBOX";
|
||||
case OEMCrypto_ERROR_WRAP_KEYBOX:
|
||||
return "WRAP_KEYBOX";
|
||||
case OEMCrypto_ERROR_BAD_MAGIC:
|
||||
return "BAD_MAGIC";
|
||||
case OEMCrypto_ERROR_BAD_CRC:
|
||||
return "BAD_CRC";
|
||||
case OEMCrypto_ERROR_NO_DEVICEID:
|
||||
return "NO_DEVICEID";
|
||||
case OEMCrypto_ERROR_RNG_FAILED:
|
||||
return "RNG_FAILED";
|
||||
case OEMCrypto_ERROR_RNG_NOT_SUPPORTED:
|
||||
return "RNG_NOT_SUPPORTED";
|
||||
case OEMCrypto_ERROR_SETUP:
|
||||
return "SETUP";
|
||||
case OEMCrypto_ERROR_OPEN_SESSION_FAILED:
|
||||
return "OPEN_SESSION_FAILED";
|
||||
case OEMCrypto_ERROR_CLOSE_SESSION_FAILED:
|
||||
return "CLOSE_SESSION_FAILED";
|
||||
case OEMCrypto_ERROR_INVALID_SESSION:
|
||||
return "INVALID_SESSION";
|
||||
case OEMCrypto_ERROR_NOT_IMPLEMENTED:
|
||||
return "NOT_IMPLEMENTED";
|
||||
case OEMCrypto_ERROR_NO_CONTENT_KEY:
|
||||
return "NO_CONTENT_KEY";
|
||||
case OEMCrypto_ERROR_CONTROL_INVALID:
|
||||
return "CONTROL_INVALID";
|
||||
case OEMCrypto_ERROR_UNKNOWN_FAILURE:
|
||||
return "UNKNOWN_FAILURE";
|
||||
case OEMCrypto_ERROR_INVALID_CONTEXT:
|
||||
return "INVALID_CONTEXT";
|
||||
case OEMCrypto_ERROR_SIGNATURE_FAILURE:
|
||||
return "SIGNATURE_FAILURE";
|
||||
case OEMCrypto_ERROR_TOO_MANY_SESSIONS:
|
||||
return "TOO_MANY_SESSIONS";
|
||||
case OEMCrypto_ERROR_INVALID_NONCE:
|
||||
return "INVALID_NONCE";
|
||||
case OEMCrypto_ERROR_TOO_MANY_KEYS:
|
||||
return "TOO_MANY_KEYS";
|
||||
case OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED:
|
||||
return "DEVICE_NOT_RSA_PROVISIONED";
|
||||
case OEMCrypto_ERROR_INVALID_RSA_KEY:
|
||||
return "INVALID_RSA_KEY";
|
||||
case OEMCrypto_ERROR_KEY_EXPIRED:
|
||||
return "KEY_EXPIRED";
|
||||
case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES:
|
||||
return "INSUFFICIENT_RESOURCES";
|
||||
case OEMCrypto_ERROR_INSUFFICIENT_HDCP:
|
||||
return "INSUFFICIENT_HDCP";
|
||||
case OEMCrypto_ERROR_BUFFER_TOO_LARGE:
|
||||
return "BUFFER_TOO_LARGE";
|
||||
case OEMCrypto_WARNING_GENERATION_SKEW:
|
||||
return "OEMCrypto_WARNING_GENERATION_SKEW";
|
||||
case OEMCrypto_ERROR_GENERATION_SKEW:
|
||||
return "GENERATION_SKEW";
|
||||
case OEMCrypto_LOCAL_DISPLAY_ONLY:
|
||||
return "OEMCrypto_LOCAL_DISPLAY_ONLY";
|
||||
case OEMCrypto_ERROR_ANALOG_OUTPUT:
|
||||
return "ANALOG_OUTPUT";
|
||||
case OEMCrypto_ERROR_WRONG_PST:
|
||||
return "WRONG_PST";
|
||||
case OEMCrypto_ERROR_WRONG_KEYS:
|
||||
return "WRONG_KEYS";
|
||||
case OEMCrypto_ERROR_MISSING_MASTER:
|
||||
return "MISSING_MASTER";
|
||||
case OEMCrypto_ERROR_LICENSE_INACTIVE:
|
||||
return "LICENSE_INACTIVE";
|
||||
case OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE:
|
||||
return "ENTRY_NEEDS_UPDATE";
|
||||
case OEMCrypto_ERROR_ENTRY_IN_USE:
|
||||
return "ENTRY_IN_USE";
|
||||
case OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE:
|
||||
return "USAGE_TABLE_UNRECOVERABLE";
|
||||
case OEMCrypto_KEY_NOT_LOADED:
|
||||
return "OEMCrypto_KEY_NOT_LOADED";
|
||||
case OEMCrypto_KEY_NOT_ENTITLED:
|
||||
return "OEMCrypto_KEY_NOT_ENTITLED";
|
||||
case OEMCrypto_ERROR_BAD_HASH:
|
||||
return "BAD_HASH";
|
||||
case OEMCrypto_ERROR_OUTPUT_TOO_LARGE:
|
||||
return "OUTPUT_TOO_LARGE";
|
||||
case OEMCrypto_ERROR_SESSION_LOST_STATE:
|
||||
return "SESSION_LOST_STATE";
|
||||
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
|
||||
return "SYSTEM_INVALIDATED";
|
||||
case OEMCrypto_ERROR_LICENSE_RELOAD:
|
||||
return "LICENSE_RELOAD";
|
||||
case OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES:
|
||||
return "MULTIPLE_USAGE_ENTRIES";
|
||||
case OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION:
|
||||
return "MIXED_OUTPUT_PROTECTION";
|
||||
case OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION:
|
||||
return "INVALID_ENTITLED_KEY_SESSION";
|
||||
case OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING:
|
||||
return "NEEDS_KEYBOX_PROVISIONING";
|
||||
case OEMCrypto_ERROR_UNSUPPORTED_CIPHER:
|
||||
return "OEMCrypto_ERROR_UNSUPPORTED_CIPHER";
|
||||
case OEMCrypto_ERROR_DVR_FORBIDDEN:
|
||||
return "OEMCrypto_ERROR_DVR_FORBIDDEN";
|
||||
case OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE:
|
||||
return "OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE";
|
||||
case OEMCrypto_ERROR_INVALID_KEY:
|
||||
return "INVALID_KEY";
|
||||
// ODK Values.
|
||||
case ODK_ERROR_CORE_MESSAGE:
|
||||
return "CORE_MESSAGE";
|
||||
case ODK_SET_TIMER:
|
||||
return "SET_TIMER";
|
||||
case ODK_DISABLE_TIMER:
|
||||
return "DISABLE_TIMER";
|
||||
case ODK_TIMER_EXPIRED:
|
||||
return "TIMER_EXPIRED";
|
||||
case ODK_UNSUPPORTED_API:
|
||||
return "UNSUPPORTED_API";
|
||||
case ODK_STALE_RENEWAL:
|
||||
return "STALE_RENEWAL";
|
||||
// OPK Values.
|
||||
case OPK_ERROR_INCOMPATIBLE_VERSION:
|
||||
return "INCOMPATIBLE_VERSION";
|
||||
case OPK_ERROR_REMOTE_CALL:
|
||||
return "REMOTE_CALL";
|
||||
case OPK_ERROR_NO_PERSISTENT_DATA:
|
||||
return "NO_PERSISTENT_DATA";
|
||||
default:
|
||||
return "Invalid OEMCrypto error.";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wvutil
|
||||
40
util/src/string_format.cpp
Normal file
40
util/src/string_format.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#include "string_format.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace wvutil {
|
||||
|
||||
bool FormatString(std::string* out, const char* fmt, ...) {
|
||||
if (out == nullptr || fmt == nullptr) return false;
|
||||
|
||||
va_list ap1;
|
||||
va_start(ap1, fmt);
|
||||
const int desired_size = vsnprintf(nullptr, 0, fmt, ap1);
|
||||
va_end(ap1);
|
||||
|
||||
if (desired_size < 0) return false;
|
||||
const size_t buffer_size =
|
||||
static_cast<size_t>(desired_size) + 1; // +1 for null
|
||||
std::unique_ptr<char[]> buffer(new char[buffer_size]);
|
||||
|
||||
va_list ap2;
|
||||
va_start(ap2, fmt);
|
||||
const int actual_size = vsnprintf(buffer.get(), buffer_size, fmt, ap2);
|
||||
va_end(ap2);
|
||||
|
||||
if (actual_size != desired_size) return false;
|
||||
|
||||
out->assign(buffer.get(), actual_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace wvutil
|
||||
64
util/test/string_format_unittest.cpp
Normal file
64
util/test/string_format_unittest.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
|
||||
#include "string_format.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace wvutil {
|
||||
|
||||
TEST(StringFormatTest, SignedInteger) {
|
||||
constexpr char kFormat[] = "Version %d";
|
||||
constexpr char kResult[] = "Version -123";
|
||||
std::string result;
|
||||
EXPECT_TRUE(FormatString(&result, kFormat, -123));
|
||||
EXPECT_EQ(result, kResult);
|
||||
}
|
||||
|
||||
TEST(StringFormatTest, UnsignedInteger) {
|
||||
constexpr char kFormat[] = "Version %u";
|
||||
constexpr char kResult[] = "Version 27";
|
||||
std::string result;
|
||||
EXPECT_TRUE(FormatString(&result, kFormat, 27));
|
||||
EXPECT_EQ(result, kResult);
|
||||
}
|
||||
|
||||
TEST(StringFormatTest, HexInteger) {
|
||||
constexpr char kFormat[] = "Version %X";
|
||||
constexpr char kResult[] = "Version FF";
|
||||
std::string result;
|
||||
EXPECT_TRUE(FormatString(&result, kFormat, 0xFF));
|
||||
EXPECT_EQ(result, kResult);
|
||||
}
|
||||
|
||||
TEST(StringFormatTest, Strings) {
|
||||
constexpr char kFormat[] = "Hello, %s.";
|
||||
constexpr char kResult[] = "Hello, DRM.";
|
||||
std::string result;
|
||||
EXPECT_TRUE(FormatString(&result, kFormat, "DRM"));
|
||||
EXPECT_EQ(result, kResult);
|
||||
}
|
||||
|
||||
TEST(StringFormatTest, Nothing) {
|
||||
constexpr char kString[] = "No format fields.";
|
||||
std::string result;
|
||||
EXPECT_TRUE(FormatString(&result, kString));
|
||||
EXPECT_EQ(result, kString);
|
||||
}
|
||||
|
||||
TEST(StringFormatTest, NullOutput) {
|
||||
constexpr char kString[] = "This will never be referenced.";
|
||||
EXPECT_FALSE(FormatString(nullptr, kString));
|
||||
}
|
||||
|
||||
TEST(StringFormatTest, NullFormat) {
|
||||
std::string result;
|
||||
EXPECT_FALSE(FormatString(&result, nullptr));
|
||||
EXPECT_TRUE(result.empty());
|
||||
}
|
||||
|
||||
} // namespace wvutil
|
||||
@@ -2,7 +2,9 @@
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// Clock - A fake clock just for running tests.
|
||||
// Clock - A fake clock just for running tests. This is used when running
|
||||
// OEMCrypto unit tests. It is not used when tests include the CE CDM source
|
||||
// code because that uses the clock in cdm/test_host.cpp instead.
|
||||
|
||||
#include <chrono>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user