summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Ferris2017-05-31 16:40:15 -0500
committerChristopher Ferris2017-05-31 19:54:19 -0500
commit15d2e42cebeedca47ed9add363bbf70df56d1e2c (patch)
tree779d32e2283f80d5fbc8f1c9f00e930f41229992 /demangle
parentb46fd68653131d276ccb23ba7790640c6a9c1c7d (diff)
downloadplatform-system-core-15d2e42cebeedca47ed9add363bbf70df56d1e2c.tar.gz
platform-system-core-15d2e42cebeedca47ed9add363bbf70df56d1e2c.tar.xz
platform-system-core-15d2e42cebeedca47ed9add363bbf70df56d1e2c.zip
Fix bug found by fuzzer.
Also, add the demangle fuzzer code. Test: Ran fuzzer, ran new unit tests. Change-Id: If3e15e10af88b81602a8a0f0bfe071a015f6000b
Diffstat (limited to 'demangle')
-rw-r--r--demangle/Android.mk32
-rw-r--r--demangle/DemangleTest.cpp9
-rw-r--r--demangle/Demangler.cpp6
-rw-r--r--demangle/demangle_fuzzer.cpp36
4 files changed, 79 insertions, 4 deletions
diff --git a/demangle/Android.mk b/demangle/Android.mk
new file mode 100644
index 000000000..e3cfc2aa3
--- /dev/null
+++ b/demangle/Android.mk
@@ -0,0 +1,32 @@
1#
2# Copyright (C) 2017 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
17LOCAL_PATH := $(call my-dir)
18
19include $(CLEAR_VARS)
20
21LOCAL_MODULE := demangle_fuzzer
22LOCAL_MODULE_TAGS := optional
23LOCAL_SRC_FILES := \
24 Demangler.cpp \
25 demangle_fuzzer.cpp \
26
27LOCAL_CFLAGS := \
28 -Wall \
29 -Werror \
30 -Wextra \
31
32include $(BUILD_FUZZ_TEST)
diff --git a/demangle/DemangleTest.cpp b/demangle/DemangleTest.cpp
index fb6811947..5e17362d9 100644
--- a/demangle/DemangleTest.cpp
+++ b/demangle/DemangleTest.cpp
@@ -22,7 +22,14 @@
22 22
23#include "Demangler.h" 23#include "Demangler.h"
24 24
25TEST(DemangleTest, VoidArgumentTest) { 25TEST(DemangleTest, IllegalArgumentModifiers) {
26 Demangler demangler;
27
28 ASSERT_EQ("_Zpp4FUNKK", demangler.Parse("_Zpp4FUNKK"));
29 ASSERT_EQ("_Zpp4FUNVV", demangler.Parse("_Zpp4FUNVV"));
30}
31
32TEST(DemangleTest, VoidArgument) {
26 Demangler demangler; 33 Demangler demangler;
27 34
28 ASSERT_EQ("func()", demangler.Parse("_ZN4funcEv")); 35 ASSERT_EQ("func()", demangler.Parse("_ZN4funcEv"));
diff --git a/demangle/Demangler.cpp b/demangle/Demangler.cpp
index 77cfd3be6..1b7406dd3 100644
--- a/demangle/Demangler.cpp
+++ b/demangle/Demangler.cpp
@@ -542,9 +542,8 @@ const char* Demangler::ParseArguments(const char* name) {
542 } else { 542 } else {
543 suffix = " volatile"; 543 suffix = " volatile";
544 } 544 }
545 if (name[-1] == 'K' || name[-1] == 'V') { 545 if (!cur_state_.suffixes.empty() && (name[-1] == 'K' || name[-1] == 'V')) {
546 // Special case, const/volatile apply as a single entity. 546 // Special case, const/volatile apply as a single entity.
547 assert(!cur_state_.suffixes.empty());
548 size_t index = cur_state_.suffixes.size(); 547 size_t index = cur_state_.suffixes.size();
549 cur_state_.suffixes[index-1].insert(0, suffix); 548 cur_state_.suffixes[index-1].insert(0, suffix);
550 } else { 549 } else {
@@ -723,7 +722,8 @@ std::string Demangler::Parse(const char* name, size_t max_length) {
723 && static_cast<size_t>(cur_name - name) < max_length) { 722 && static_cast<size_t>(cur_name - name) < max_length) {
724 cur_name = (this->*parse_func_)(cur_name); 723 cur_name = (this->*parse_func_)(cur_name);
725 } 724 }
726 if (cur_name == nullptr || *cur_name != '\0' || function_name_.empty()) { 725 if (cur_name == nullptr || *cur_name != '\0' || function_name_.empty() ||
726 !cur_state_.suffixes.empty()) {
727 return name; 727 return name;
728 } 728 }
729 729
diff --git a/demangle/demangle_fuzzer.cpp b/demangle/demangle_fuzzer.cpp
new file mode 100644
index 000000000..83fafc212
--- /dev/null
+++ b/demangle/demangle_fuzzer.cpp
@@ -0,0 +1,36 @@
1/*
2 * Copyright (C) 2017 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 <stddef.h>
18#include <stdint.h>
19#include <stdlib.h>
20#include <string.h>
21
22#include <string>
23
24#include "Demangler.h"
25
26extern "C" void LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
27 std::vector<char> data_str(size + 1);
28 memcpy(data_str.data(), data, size);
29 data_str[size] = '\0';
30
31 Demangler demangler;
32 std::string demangled_name = demangler.Parse(data_str.data());
33 if (size != 0 && data_str[0] != '\0' && demangled_name.empty()) {
34 abort();
35 }
36}