blob: ecab0e0372da304df91dfe9b68f6ec68838af206 [file] [log] [blame]
Amin Hassani7fca2862019-03-28 16:09:22 -07001//
2// Copyright (C) 2019 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "update_engine/omaha_request_builder_xml.h"
18
19#include <string>
Jae Hoon Kimb7ee3872019-06-06 14:59:03 -070020#include <utility>
21#include <vector>
Amin Hassani7fca2862019-03-28 16:09:22 -070022
Jae Hoon Kim6ada5912019-06-14 10:11:34 -070023#include <base/guid.h>
Amin Hassani7fca2862019-03-28 16:09:22 -070024#include <gtest/gtest.h>
25
Jae Hoon Kim6ada5912019-06-14 10:11:34 -070026#include "update_engine/fake_system_state.h"
27
Jae Hoon Kimb7ee3872019-06-06 14:59:03 -070028using std::pair;
Amin Hassani7fca2862019-03-28 16:09:22 -070029using std::string;
Jae Hoon Kimb7ee3872019-06-06 14:59:03 -070030using std::vector;
Amin Hassani7fca2862019-03-28 16:09:22 -070031
32namespace chromeos_update_engine {
33
Jae Hoon Kim6ada5912019-06-14 10:11:34 -070034namespace {
35// Helper to find key and extract value from the given string |xml|, instead
36// of using a full parser. The attribute key will be followed by "=\"" as xml
37// attribute values must be within double quotes (not single quotes).
38static string FindAttributeKeyValueInXml(const string& xml,
39 const string& key,
40 const size_t val_size) {
41 string key_with_quotes = key + "=\"";
42 const size_t val_start_pos = xml.find(key);
43 if (val_start_pos == string::npos)
44 return "";
45 return xml.substr(val_start_pos + key_with_quotes.size(), val_size);
46}
47} // namespace
48
49class OmahaRequestBuilderXmlTest : public ::testing::Test {
50 protected:
51 void SetUp() override {}
52 void TearDown() override {}
53
54 FakeSystemState fake_system_state_;
55 static constexpr size_t kGuidSize = 36;
56};
Amin Hassani7fca2862019-03-28 16:09:22 -070057
58TEST_F(OmahaRequestBuilderXmlTest, XmlEncodeTest) {
59 string output;
Jae Hoon Kimb7ee3872019-06-06 14:59:03 -070060 vector<pair<string, string>> xml_encode_pairs = {
61 {"ab", "ab"},
62 {"a<b", "a&lt;b"},
63 {"<&>\"\'\\", "&lt;&amp;&gt;&quot;&apos;\\"},
64 {"&lt;&amp;&gt;", "&amp;lt;&amp;amp;&amp;gt;"}};
65 for (const auto& xml_encode_pair : xml_encode_pairs) {
66 const auto& before_encoding = xml_encode_pair.first;
67 const auto& after_encoding = xml_encode_pair.second;
68 EXPECT_TRUE(XmlEncode(before_encoding, &output));
69 EXPECT_EQ(after_encoding, output);
70 }
Amin Hassani7fca2862019-03-28 16:09:22 -070071 // Check that unterminated UTF-8 strings are handled properly.
72 EXPECT_FALSE(XmlEncode("\xc2", &output));
73 // Fail with invalid ASCII-7 chars.
74 EXPECT_FALSE(XmlEncode("This is an 'n' with a tilde: \xc3\xb1", &output));
75}
76
77TEST_F(OmahaRequestBuilderXmlTest, XmlEncodeWithDefaultTest) {
Jae Hoon Kimb7ee3872019-06-06 14:59:03 -070078 EXPECT_EQ("", XmlEncodeWithDefault(""));
Amin Hassani7fca2862019-03-28 16:09:22 -070079 EXPECT_EQ("&lt;&amp;&gt;", XmlEncodeWithDefault("<&>", "something else"));
80 EXPECT_EQ("<not escaped>", XmlEncodeWithDefault("\xc2", "<not escaped>"));
81}
82
Jae Hoon Kim37d15372020-01-08 18:11:26 -080083TEST_F(OmahaRequestBuilderXmlTest, PlatformGetAppTest) {
84 OmahaRequestParams omaha_request_params{&fake_system_state_};
85 omaha_request_params.set_device_requisition("device requisition");
86 OmahaRequestBuilderXml omaha_request{nullptr,
87 &omaha_request_params,
88 false,
89 false,
90 0,
91 0,
92 0,
93 fake_system_state_.prefs(),
94 ""};
95 OmahaAppData dlc_module_app = {.id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
96 .version = "",
97 .skip_update = false,
98 .is_dlc = false};
99
100 // Verify that the attributes that shouldn't be missing for Platform AppID are
101 // in fact present in the <app ...></app>.
102 const string app = omaha_request.GetApp(dlc_module_app);
103 EXPECT_NE(string::npos, app.find("lang="));
104 EXPECT_NE(string::npos, app.find("fw_version="));
105 EXPECT_NE(string::npos, app.find("ec_version="));
106 EXPECT_NE(string::npos, app.find("requisition="));
107}
108
109TEST_F(OmahaRequestBuilderXmlTest, DlcGetAppTest) {
110 OmahaRequestParams omaha_request_params{&fake_system_state_};
111 omaha_request_params.set_device_requisition("device requisition");
112 OmahaRequestBuilderXml omaha_request{nullptr,
113 &omaha_request_params,
114 false,
115 false,
116 0,
117 0,
118 0,
119 fake_system_state_.prefs(),
120 ""};
121 OmahaAppData dlc_module_app = {
122 .id = "_dlc_id", .version = "", .skip_update = false, .is_dlc = true};
123
124 // Verify that the attributes that should be missing for DLC AppIDs are in
125 // fact not present in the <app ...></app>.
126 const string app = omaha_request.GetApp(dlc_module_app);
127 EXPECT_EQ(string::npos, app.find("lang="));
128 EXPECT_EQ(string::npos, app.find("fw_version="));
129 EXPECT_EQ(string::npos, app.find("ec_version="));
130 EXPECT_EQ(string::npos, app.find("requisition="));
131}
132
Jae Hoon Kim6ada5912019-06-14 10:11:34 -0700133TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlRequestIdTest) {
134 OmahaEvent omaha_event;
135 OmahaRequestParams omaha_request_params{&fake_system_state_};
136 OmahaRequestBuilderXml omaha_request{&omaha_event,
137 &omaha_request_params,
138 false,
139 false,
140 0,
141 0,
142 0,
Jae Hoon Kimedb65502019-06-14 11:52:17 -0700143 fake_system_state_.prefs(),
144 ""};
Jae Hoon Kim6ada5912019-06-14 10:11:34 -0700145 const string request_xml = omaha_request.GetRequest();
146 const string key = "requestid";
147 const string request_id =
148 FindAttributeKeyValueInXml(request_xml, key, kGuidSize);
149 // A valid |request_id| is either a GUID version 4 or empty string.
150 if (!request_id.empty())
151 EXPECT_TRUE(base::IsValidGUID(request_id));
152}
153
Jae Hoon Kimedb65502019-06-14 11:52:17 -0700154TEST_F(OmahaRequestBuilderXmlTest, GetRequestXmlSessionIdTest) {
155 const string gen_session_id = base::GenerateGUID();
156 OmahaEvent omaha_event;
157 OmahaRequestParams omaha_request_params{&fake_system_state_};
158 OmahaRequestBuilderXml omaha_request{&omaha_event,
159 &omaha_request_params,
160 false,
161 false,
162 0,
163 0,
164 0,
165 fake_system_state_.prefs(),
166 gen_session_id};
167 const string request_xml = omaha_request.GetRequest();
168 const string key = "sessionid";
169 const string session_id =
170 FindAttributeKeyValueInXml(request_xml, key, kGuidSize);
171 // A valid |session_id| is either a GUID version 4 or empty string.
172 if (!session_id.empty()) {
173 EXPECT_TRUE(base::IsValidGUID(session_id));
174 }
175 EXPECT_EQ(gen_session_id, session_id);
176}
177
Amin Hassani7fca2862019-03-28 16:09:22 -0700178} // namespace chromeos_update_engine