Skip to content
Snippets Groups Projects
Commit 1532fa75 authored by Hamzeh Zawawy's avatar Hamzeh Zawawy
Browse files

Adding fuzzer ResXMLTree

Bug: 328272470
Test: m resxmlparser_fuzzer and then run binary
Change-Id: I389abf4f8cfb534c354b9846293c5b583987f4e2
parent b632fda9
No related branches found
No related tags found
No related merge requests found
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
// all of the 'license_kinds' from "frameworks_base_libs_androidfw_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["frameworks_base_libs_androidfw_license"],
}
cc_fuzz {
name: "resxmlparser_fuzzer",
srcs: [
"resxmlparser_fuzzer.cpp",
],
host_supported: true,
static_libs: ["libgmock"],
target: {
android: {
shared_libs: [
"libandroidfw",
"libbase",
"libbinder",
"libcutils",
"liblog",
"libutils",
],
},
host: {
static_libs: [
"libandroidfw",
"libbase",
"libbinder",
"libcutils",
"liblog",
"libutils",
],
},
darwin: {
// libbinder is not supported on mac
enabled: false,
},
},
include_dirs: [
"system/incremental_delivery/incfs/util/include/",
],
corpus: ["testdata/*"],
dictionary: "xmlparser_fuzzer.dict",
}
/*
* Copyright (C) 2024 The Android Open Source Project
*
* 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 <memory>
#include <cstdint>
#include <cstddef>
#include <fuzzer/FuzzedDataProvider.h>
#include "androidfw/ResourceTypes.h"
static void populateDynamicRefTableWithFuzzedData(
android::DynamicRefTable& table,
FuzzedDataProvider& fuzzedDataProvider) {
const size_t numMappings = fuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, 5);
for (size_t i = 0; i < numMappings; ++i) {
const uint8_t packageId = fuzzedDataProvider.ConsumeIntegralInRange<uint8_t>(0x02, 0x7F);
// Generate a package name
std::string packageName;
size_t packageNameLength = fuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, 128);
for (size_t j = 0; j < packageNameLength; ++j) {
// Consume characters only in the ASCII range (0x20 to 0x7E) to ensure valid UTF-8
char ch = fuzzedDataProvider.ConsumeIntegralInRange<char>(0x20, 0x7E);
packageName.push_back(ch);
}
// Convert std::string to String16 for compatibility
android::String16 androidPackageName(packageName.c_str(), packageName.length());
// Add the mapping to the table
table.addMapping(androidPackageName, packageId);
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FuzzedDataProvider fuzzedDataProvider(data, size);
auto dynamic_ref_table = std::make_shared<android::DynamicRefTable>();
// Populate the DynamicRefTable with fuzzed data
populateDynamicRefTableWithFuzzedData(*dynamic_ref_table, fuzzedDataProvider);
auto tree = android::ResXMLTree(std::move(dynamic_ref_table));
std::vector<uint8_t> xmlData = fuzzedDataProvider.ConsumeRemainingBytes<uint8_t>();
if (tree.setTo(xmlData.data(), xmlData.size()) != android::NO_ERROR) {
return 0; // Exit early if unable to parse XML data
}
tree.restart();
size_t len = 0;
auto code = tree.next();
if (code == android::ResXMLParser::START_TAG) {
// Access element name
auto name = tree.getElementName(&len);
// Access attributes of the current element
for (size_t i = 0; i < tree.getAttributeCount(); i++) {
// Access attribute name
auto attrName = tree.getAttributeName(i, &len);
}
} else if (code == android::ResXMLParser::TEXT) {
const auto text = tree.getText(&len);
}
return 0; // Non-zero return values are reserved for future use.
}
<?xml version="1.0" encoding="UTF-8"?>
<root>
<child id="1">
<subchild type="A">Content A</subchild>
<subchild type="B">Content B</subchild>
</child>
<child id="2" extra="data">
<subchild type="C">Content C</subchild>
</child>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<child1>Value 1</child1>
<child2>Value 2</child2>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!-- Example with special characters and CDATA -->
<data><![CDATA[Some <encoded> data & other "special" characters]]></data>
<message>Hello &amp; Welcome!</message>
</root>
root_tag=<root>
child_tag=<child>
end_child_tag=</child>
id_attr=id="
type_attr=type="
cdata_start=<![CDATA[
cdata_end=]]>
ampersand_entity=&amp;
xml_header=<?xml version="1.0" encoding="UTF-8"?>
comment_start=<!--
comment_end= -->
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment