1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "verification/public_internal.h"
17 #include "verification/verification_options.h"
18 #include "verification/config/process/config_process.h"
19 #include "verification/util/parser/parser.h"
20 #include "verification/util/struct_field.h"
21
22 #include "literal_parser.h"
23
24 #include "verifier_messages.h"
25
26 #include "runtime/include/method.h"
27 #include "runtime/include/runtime.h"
28 #include "runtime/include/mem/panda_containers.h"
29 #include "runtime/include/mem/panda_string.h"
30
31 #include "utils/logger.h"
32
33 #include <cstring>
34 #include <cstdint>
35 #include <string>
36 #include <unordered_map>
37
38 namespace panda::verifier::debug {
39
40 namespace {
41
42 template <typename M>
GetKeys(const M & map)43 PandaString GetKeys(const M &map)
44 {
45 PandaString keys;
46 for (const auto &p : map) {
47 if (keys.empty()) {
48 keys += "'";
49 keys += p.first;
50 keys += "'";
51 } else {
52 keys += ", '";
53 keys += p.first;
54 keys += "'";
55 }
56 }
57 return keys;
58 }
59
60 } // namespace
61
62 using panda::verifier::config::Section;
63
RegisterConfigHandlerOptions(Config * dcfg)64 void RegisterConfigHandlerOptions(Config *dcfg)
65 {
66 static const auto configDebugOptionsVerifier = [](Config *config, const Section §ion) {
67 using BoolField = StructField<VerificationOptions, bool>;
68 using Flags = PandaUnorderedMap<PandaString, BoolField>;
69 using FlagsSection = PandaUnorderedMap<PandaString, Flags>;
70
71 const FlagsSection flags = {
72 {"show",
73 {{"context", BoolField {offsetof(VerificationOptions, debug.show.context)}},
74 {"reg-changes", BoolField {offsetof(VerificationOptions, debug.show.regChanges)}},
75 {"typesystem", BoolField {offsetof(VerificationOptions, debug.show.typeSystem)}},
76 {"status", BoolField {offsetof(VerificationOptions, show.status)}}}},
77 {"allow",
78 {{"undefined-class", BoolField {offsetof(VerificationOptions, debug.allow.undefinedClass)}},
79 {"undefined-method", BoolField {offsetof(VerificationOptions, debug.allow.undefinedMethod)}},
80 {"undefined-field", BoolField {offsetof(VerificationOptions, debug.allow.undefinedField)}},
81 {"undefined-type", BoolField {offsetof(VerificationOptions, debug.allow.undefinedType)}},
82 {"undefined-string", BoolField {offsetof(VerificationOptions, debug.allow.undefinedString)}},
83 {"method-access-violation", BoolField {offsetof(VerificationOptions, debug.allow.methodAccessViolation)}},
84 {"field-access-violation", BoolField {offsetof(VerificationOptions, debug.allow.fieldAccessViolation)}},
85 {"wrong-subclassing-in-method-args",
86 BoolField {offsetof(VerificationOptions, debug.allow.wrongSubclassingInMethodArgs)}},
87 {"error-in-exception-handler",
88 BoolField {offsetof(VerificationOptions, debug.allow.errorInExceptionHandler)}},
89 {"permanent-runtime-exception",
90 BoolField {offsetof(VerificationOptions, debug.allow.permanentRuntimeException)}}}}};
91
92 auto &verifOpts = config->opts;
93 for (const auto &s : section.sections) {
94 if (flags.count(s.name) == 0) {
95 LOG_VERIFIER_DEBUG_CONFIG_WRONG_OPTIONS_SECTION(s.name, GetKeys(flags));
96 return false;
97 }
98 const auto §ionFlags = flags.at(s.name);
99 for (const auto &i : s.items) {
100 PandaVector<PandaString> c;
101 const char *start = i.c_str();
102 const char *end = i.c_str() + i.length(); // NOLINT
103 if (!LiteralsParser()(c, start, end)) {
104 LOG_VERIFIER_DEBUG_CONFIG_WRONG_OPTIONS_LINE(i);
105 return false;
106 }
107 if (!c.empty()) {
108 for (const auto &l : c) {
109 if (sectionFlags.count(l) == 0) {
110 LOG_VERIFIER_DEBUG_CONFIG_WRONG_OPTION_FOR_SECTION(l, s.name, GetKeys(sectionFlags));
111 return false;
112 }
113 sectionFlags.at(l).Of(verifOpts) = true;
114 LOG_VERIFIER_DEBUG_CONFIG_OPTION_IS_ACTIVE_INFO(s.name, l);
115 }
116 }
117 }
118 }
119 return true;
120 };
121
122 config::RegisterConfigHandler(dcfg, "config.debug.options.verifier", configDebugOptionsVerifier);
123 }
124
125 } // namespace panda::verifier::debug
126