blob: 35f9e3d8f5c81c54b7c977ebc9a3e194fd0d9f19 [file] [log] [blame]
// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "syzygy/pe/metadata.h"
#include "base/file_util.h"
#include "base/json/json_reader.h"
#include "gtest/gtest.h"
#include "syzygy/core/json_file_writer.h"
#include "syzygy/core/serialization.h"
#include "syzygy/core/unittest_util.h"
namespace pe {
typedef PEFile::AbsoluteAddress AbsoluteAddress;
using base::DictionaryValue;
using base::Value;
namespace {
void InitMetadata(Metadata* metadata) {
std::string command_line = "foo.exe --bar --baz=blarg";
base::Time creation_time;
EXPECT_TRUE(base::Time::FromString("Thu, 7 Jul 2011 13:45:00 GMT",
&creation_time));
SyzygyVersion toolchain_version(1, 2, 3, 4, "5");
PEFile::Signature module_signature;
module_signature.path = L"C:\\foo\\foo.dll";
module_signature.base_address = AbsoluteAddress(0x4001000);
module_signature.module_size = 2 * 1024 * 1024;
module_signature.module_time_date_stamp = 0xdeadbeefu;
module_signature.module_checksum = 0xbaadf00du;
metadata->set_command_line(command_line);
metadata->set_creation_time(creation_time);
metadata->set_toolchain_version(toolchain_version);
metadata->set_module_signature(module_signature);
}
bool TestJSONSerialization(bool pretty_print) {
base::FilePath temp_file_path;
FILE* temp_file = base::CreateAndOpenTemporaryFile(&temp_file_path);
if (temp_file == NULL)
return false;
bool success = true;
// Output to file.
Metadata metadata1;
InitMetadata(&metadata1);
core::JSONFileWriter json_file(temp_file, pretty_print);
EXPECT_TRUE(success = metadata1.SaveToJSON(&json_file));
fclose(temp_file);
// Read the file.
std::string file_string;
if (success)
EXPECT_TRUE(success =
base::ReadFileToString(temp_file_path, &file_string));
// Parse the JSON, extracting the root dictionary.
scoped_ptr<Value> value;
DictionaryValue* metadata_dict = NULL;
if (success) {
value.reset(base::JSONReader::Read(file_string));
EXPECT_TRUE(success =
(value.get() != NULL && value->GetType() == Value::TYPE_DICTIONARY));
if (success)
metadata_dict = static_cast<DictionaryValue*>(value.get());
}
// Parse the metadata from the Value.
Metadata metadata2;
if (success) {
DCHECK(metadata_dict != NULL);
EXPECT_TRUE(success = metadata2.LoadFromJSON(*metadata_dict));
}
// Compare the two structures.
if (success)
EXPECT_TRUE(success = (metadata1 == metadata2));
// Always delete the temporary file.
if (!base::DeleteFile(temp_file_path, false))
success = false;
return success;
}
} // namespace
TEST(MetadataTest, Equality) {
Metadata metadata1;
Metadata metadata2;
InitMetadata(&metadata1);
InitMetadata(&metadata2);
EXPECT_EQ(metadata1, metadata2);
}
TEST(MetadataTest, Inequality) {
Metadata metadata1;
Metadata metadata2;
InitMetadata(&metadata1);
EXPECT_NE(metadata1, metadata2);
}
TEST(MetadataTest, SaveToBlock) {
Metadata metadata1;
InitMetadata(&metadata1);
BlockGraph block_graph;
BlockGraph::Block* block =
block_graph.AddBlock(BlockGraph::DATA_BLOCK, 0, "Metadata");
EXPECT_TRUE(metadata1.SaveToBlock(block));
Metadata metadata2;
EXPECT_TRUE(metadata2.LoadFromBlock(block));
EXPECT_EQ(metadata1, metadata2);
}
TEST(MetadataTest, Serialization) {
Metadata metadata;
InitMetadata(&metadata);
EXPECT_TRUE(testing::TestSerialization(metadata));
}
TEST(MetadataTest, JSONSerializationNoPrettyPrint) {
EXPECT_TRUE(TestJSONSerialization(true));
}
TEST(MetadataTest, JSONSerializationPrettyPrint) {
EXPECT_TRUE(TestJSONSerialization(false));
}
} // namespace pe