• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 <cstdio>  // fclose
18 #include <memory>
19 #include <string>
20 
21 #include "TestHelpers.h"
22 #include "androidfw/AssetsProvider.h"
23 #include "gtest/gtest.h"
24 #include "idmap2/XmlParser.h"
25 
26 namespace android::idmap2 {
27 
CreateTestParser(const std::string & test_file)28 Result<XmlParser> CreateTestParser(const std::string& test_file) {
29   auto zip = ZipAssetsProvider::Create(GetTestDataPath() + "/target/target.apk", 0 /* flags */);
30   if (zip == nullptr) {
31     return Error("Failed to open zip file");
32   }
33 
34   auto data = zip->Open(test_file);
35   if (data == nullptr) {
36     return Error("Failed to open xml file");
37   }
38 
39   return XmlParser::Create(data->getBuffer(true /* aligned*/), data->getLength(),
40                            /* copy_data */ true);
41 }
42 
TEST(XmlParserTests,Create)43 TEST(XmlParserTests, Create) {
44   auto xml = CreateTestParser("AndroidManifest.xml");
45   ASSERT_TRUE(xml) << xml.GetErrorMessage();
46 
47   fclose(stderr);  // silence expected warnings from libandroidfw
48   const char* not_xml = "foo";
49   auto fail = XmlParser::Create(reinterpret_cast<const uint8_t*>(not_xml), strlen(not_xml));
50   ASSERT_FALSE(fail);
51 }
52 
TEST(XmlParserTests,NextChild)53 TEST(XmlParserTests, NextChild) {
54   auto xml = CreateTestParser("res/xml/test.xml");
55   ASSERT_TRUE(xml) << xml.GetErrorMessage();
56 
57   auto root_iter = xml->tree_iterator();
58   ASSERT_EQ(root_iter->event(), XmlParser::Event::START_TAG);
59   ASSERT_EQ(root_iter->name(), "a");
60 
61   auto a_iter = root_iter.begin();
62   ASSERT_EQ(a_iter->event(), XmlParser::Event::START_TAG);
63   ASSERT_EQ(a_iter->name(), "b");
64 
65   auto c_iter = a_iter.begin();
66   ASSERT_EQ(c_iter->event(), XmlParser::Event::START_TAG);
67   ASSERT_EQ(c_iter->name(), "c");
68 
69   ++c_iter;
70   ASSERT_EQ(c_iter->event(), XmlParser::Event::END_TAG);
71   ASSERT_EQ(c_iter, a_iter.end());
72 
73   ++a_iter;
74   ASSERT_EQ(a_iter->event(), XmlParser::Event::START_TAG);
75   ASSERT_EQ(a_iter->name(), "d");
76 
77   // Skip the <e> tag.
78   ++a_iter;
79   ASSERT_EQ(a_iter->event(), XmlParser::Event::END_TAG);
80   ASSERT_EQ(a_iter, root_iter.end());
81 }
82 
TEST(XmlParserTests,AttributeValues)83 TEST(XmlParserTests, AttributeValues) {
84   auto xml = CreateTestParser("res/xml/test.xml");
85   ASSERT_TRUE(xml) << xml.GetErrorMessage();
86 
87   // Start at the <a> tag.
88   auto root_iter = xml->tree_iterator();
89 
90   // Start at the <b> tag.
91   auto a_iter = root_iter.begin();
92   auto attribute_str = a_iter->GetAttributeStringValue("type_string");
93   ASSERT_TRUE(attribute_str);
94   ASSERT_EQ(*attribute_str, "fortytwo");
95 
96   auto attribute_value = a_iter->GetAttributeValue("type_int_dec");
97   ASSERT_TRUE(attribute_value);
98   ASSERT_EQ(attribute_value->data, 42);
99 
100   attribute_value = a_iter->GetAttributeValue("type_int_hex");
101   ASSERT_TRUE(attribute_value);
102   ASSERT_EQ(attribute_value->data, 42);
103 
104   attribute_value = a_iter->GetAttributeValue("type_int_boolean");
105   ASSERT_TRUE(attribute_value);
106   ASSERT_EQ(attribute_value->data, 0xffffffff);
107 }
108 
TEST(XmlParserTests,IteratorEquality)109 TEST(XmlParserTests, IteratorEquality) {
110   auto xml = CreateTestParser("res/xml/test.xml");
111   ASSERT_TRUE(xml) << xml.GetErrorMessage();
112 
113   // Start at the <a> tag.
114   auto root_iter_1 = xml->tree_iterator();
115   auto root_iter_2 = xml->tree_iterator();
116   ASSERT_EQ(root_iter_1, root_iter_2);
117   ASSERT_EQ(*root_iter_1, *root_iter_2);
118 
119   // Start at the <b> tag.
120   auto a_iter_1 = root_iter_1.begin();
121   auto a_iter_2 = root_iter_2.begin();
122   ASSERT_NE(a_iter_1, root_iter_1.end());
123   ASSERT_NE(a_iter_2, root_iter_2.end());
124   ASSERT_EQ(a_iter_1, a_iter_2);
125   ASSERT_EQ(*a_iter_1, *a_iter_2);
126 
127   // Move to the <d> tag.
128   ++a_iter_1;
129   ++a_iter_2;
130   ASSERT_NE(a_iter_1, root_iter_1.end());
131   ASSERT_NE(a_iter_2, root_iter_2.end());
132   ASSERT_EQ(a_iter_1, a_iter_2);
133   ASSERT_EQ(*a_iter_1, *a_iter_2);
134 
135   // Move to the end of the <a> tag.
136   ++a_iter_1;
137   ++a_iter_2;
138   ASSERT_EQ(a_iter_1, root_iter_1.end());
139   ASSERT_EQ(a_iter_2, root_iter_2.end());
140   ASSERT_EQ(a_iter_1, a_iter_2);
141   ASSERT_EQ(*a_iter_1, *a_iter_2);
142 }
143 
TEST(XmlParserTests,Backtracking)144 TEST(XmlParserTests, Backtracking) {
145   auto xml = CreateTestParser("res/xml/test.xml");
146   ASSERT_TRUE(xml) << xml.GetErrorMessage();
147 
148   // Start at the <a> tag.
149   auto root_iter_1 = xml->tree_iterator();
150 
151   // Start at the <b> tag.
152   auto a_iter_1 = root_iter_1.begin();
153 
154   // Start a second iterator at the <a> tag.
155   auto root_iter_2 = root_iter_1;
156   ASSERT_EQ(root_iter_1, root_iter_2);
157   ASSERT_EQ(*root_iter_1, *root_iter_2);
158 
159   // Move the first iterator to the end of the <a> tag.
160   auto root_iter_end_1 = root_iter_1.end();
161   ++root_iter_1;
162   ASSERT_NE(root_iter_1, root_iter_2);
163   ASSERT_NE(*root_iter_1, *root_iter_2);
164 
165   // Move to the <d> tag.
166   ++a_iter_1;
167   ASSERT_NE(a_iter_1, root_iter_end_1);
168 
169   // Move to the end of the <a> tag.
170   ++a_iter_1;
171   ASSERT_EQ(a_iter_1, root_iter_end_1);
172 }
173 
174 }  // namespace android::idmap2
175