1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/trace/parse/parse_utils.h"
16 :
17 : #include <vector>
18 :
19 : #include "gmock/gmock.h"
20 : #include "gtest/gtest.h"
21 : #include "syzygy/common/buffer_writer.h"
22 :
23 : namespace trace {
24 : namespace parser {
25 :
26 : namespace {
27 :
28 : class ParseTraceFileHeaderBlobTest : public ::testing::Test {
29 : public:
30 E : virtual void SetUp() {
31 : // Ensure the buffer is big enough for the header but no blob.
32 E : buffer_.resize(offsetof(TraceFileHeader, blob_data));
33 :
34 : // We don't actually care about the initial values of the header, as the
35 : // blob parser only cares about header_size.
36 E : SetHeaderSize();
37 E : }
38 :
39 E : TraceFileHeader* GetHeader() {
40 E : return reinterpret_cast<TraceFileHeader*>(&buffer_[0]);
41 E : }
42 :
43 E : void SetHeaderSize() { GetHeader()->header_size = buffer_.size(); }
44 :
45 E : bool TestParseTraceFileHeaderBlob(const TraceFileHeader& header) {
46 E : SetHeaderSize();
47 E : return ParseTraceFileHeaderBlob(header, NULL, NULL, NULL);
48 E : }
49 :
50 : std::vector<uint8> buffer_;
51 : };
52 :
53 : } // namespace
54 :
55 E : TEST(ParseEnvironmentStringsTest, Succeeds) {
56 E : wchar_t kEnvString[] = L"KEY0=value0\0KEY1=value1\0";
57 E : TraceEnvironmentStrings env_strings;
58 E : EXPECT_TRUE(ParseEnvironmentStrings(kEnvString, &env_strings));
59 :
60 E : TraceEnvironmentStrings expected_env_strings;
61 : expected_env_strings.push_back(std::make_pair(std::wstring(L"KEY0"),
62 E : std::wstring(L"value0")));
63 : expected_env_strings.push_back(std::make_pair(std::wstring(L"KEY1"),
64 E : std::wstring(L"value1")));
65 E : EXPECT_THAT(env_strings, ::testing::ContainerEq(expected_env_strings));
66 E : }
67 :
68 E : TEST_F(ParseTraceFileHeaderBlobTest, FailsOnTruncatedHeader) {
69 : // Make the header too small.
70 E : GetHeader()->header_size--;
71 :
72 E : EXPECT_FALSE(TestParseTraceFileHeaderBlob(*GetHeader()));
73 E : }
74 :
75 E : TEST_F(ParseTraceFileHeaderBlobTest, FailsOnShortData) {
76 E : common::VectorBufferWriter writer(&buffer_);
77 E : ASSERT_TRUE(writer.Consume(buffer_.size()));
78 :
79 E : for (size_t i = 0; i < 8; ++i) {
80 E : EXPECT_FALSE(TestParseTraceFileHeaderBlob(*GetHeader()));
81 E : ASSERT_TRUE(writer.Write<uint8>(0));
82 E : SetHeaderSize();
83 E : }
84 :
85 E : EXPECT_TRUE(TestParseTraceFileHeaderBlob(*GetHeader()));
86 E : }
87 :
88 E : TEST_F(ParseTraceFileHeaderBlobTest, FailsOnExtraData) {
89 E : common::VectorBufferWriter writer(&buffer_);
90 E : ASSERT_TRUE(writer.Consume(buffer_.size()));
91 :
92 : // We get a trailing zero for free simply from the string literal.
93 E : const wchar_t kData[] = L"a string\0another string\0env1\0env2\0";
94 E : ASSERT_TRUE(writer.Write(arraysize(kData), kData));
95 :
96 E : EXPECT_TRUE(TestParseTraceFileHeaderBlob(*GetHeader()));
97 :
98 E : const wchar_t kExtraData[] = L"extra data";
99 E : ASSERT_TRUE(writer.WriteString(kExtraData));
100 E : EXPECT_FALSE(TestParseTraceFileHeaderBlob(*GetHeader()));
101 E : }
102 :
103 E : TEST_F(ParseTraceFileHeaderBlobTest, SucceedsOnGoodData) {
104 E : common::VectorBufferWriter writer(&buffer_);
105 E : ASSERT_TRUE(writer.Consume(buffer_.size()));
106 :
107 E : const wchar_t kModulePath[] = L"C:\\path\\to\\some\\module.dll";
108 E : const wchar_t kCommandLine[] = L"module.exe --foo --bar=bar";
109 : // The second trailing zero comes for free.
110 E : const wchar_t kEnvironment[] = L"=foobar\0KEY1=value1\0KEY2=value2\0";
111 :
112 E : ASSERT_TRUE(writer.WriteString(kModulePath));
113 E : ASSERT_TRUE(writer.WriteString(kCommandLine));
114 E : ASSERT_TRUE(writer.Write(arraysize(kEnvironment), kEnvironment));
115 :
116 E : SetHeaderSize();
117 :
118 E : std::wstring module_path;
119 E : std::wstring command_line;
120 E : TraceEnvironmentStrings env_strings;
121 : EXPECT_TRUE(ParseTraceFileHeaderBlob(*GetHeader(), &module_path,
122 E : &command_line, &env_strings));
123 :
124 E : EXPECT_EQ(std::wstring(kModulePath), module_path);
125 E : EXPECT_EQ(std::wstring(kCommandLine), command_line);
126 :
127 E : TraceEnvironmentStrings expected_env_strings;
128 : expected_env_strings.push_back(std::make_pair(std::wstring(L""),
129 E : std::wstring(L"foobar")));
130 : expected_env_strings.push_back(std::make_pair(std::wstring(L"KEY1"),
131 E : std::wstring(L"value1")));
132 : expected_env_strings.push_back(std::make_pair(std::wstring(L"KEY2"),
133 E : std::wstring(L"value2")));
134 E : EXPECT_THAT(env_strings, ::testing::ContainerEq(expected_env_strings));
135 E : }
136 :
137 : } // namespace parser
138 : } // namespace trace
|