diff options
author | Christopher Ferris | 2017-05-31 16:40:15 -0500 |
---|---|---|
committer | Christopher Ferris | 2017-05-31 19:54:19 -0500 |
commit | 15d2e42cebeedca47ed9add363bbf70df56d1e2c (patch) | |
tree | 779d32e2283f80d5fbc8f1c9f00e930f41229992 /demangle | |
parent | b46fd68653131d276ccb23ba7790640c6a9c1c7d (diff) | |
download | platform-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.mk | 32 | ||||
-rw-r--r-- | demangle/DemangleTest.cpp | 9 | ||||
-rw-r--r-- | demangle/Demangler.cpp | 6 | ||||
-rw-r--r-- | demangle/demangle_fuzzer.cpp | 36 |
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 | |||
17 | LOCAL_PATH := $(call my-dir) | ||
18 | |||
19 | include $(CLEAR_VARS) | ||
20 | |||
21 | LOCAL_MODULE := demangle_fuzzer | ||
22 | LOCAL_MODULE_TAGS := optional | ||
23 | LOCAL_SRC_FILES := \ | ||
24 | Demangler.cpp \ | ||
25 | demangle_fuzzer.cpp \ | ||
26 | |||
27 | LOCAL_CFLAGS := \ | ||
28 | -Wall \ | ||
29 | -Werror \ | ||
30 | -Wextra \ | ||
31 | |||
32 | include $(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 | ||
25 | TEST(DemangleTest, VoidArgumentTest) { | 25 | TEST(DemangleTest, IllegalArgumentModifiers) { |
26 | Demangler demangler; | ||
27 | |||
28 | ASSERT_EQ("_Zpp4FUNKK", demangler.Parse("_Zpp4FUNKK")); | ||
29 | ASSERT_EQ("_Zpp4FUNVV", demangler.Parse("_Zpp4FUNVV")); | ||
30 | } | ||
31 | |||
32 | TEST(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 | |||
26 | extern "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 | } | ||