• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 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 ark::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 ark::verifier::config::Section;
63 
RegisterConfigHandlerOptionsVerifierOptionLine(const struct Section & s,const PandaUnorderedMap<PandaString,StructField<VerificationOptions,bool>> & sectionFlags,VerificationOptions & verifOpts,PandaVector<PandaString> & c)64 static bool RegisterConfigHandlerOptionsVerifierOptionLine(
65     const struct Section &s, const PandaUnorderedMap<PandaString, StructField<VerificationOptions, bool>> &sectionFlags,
66     VerificationOptions &verifOpts, PandaVector<PandaString> &c)
67 {
68     if (!c.empty()) {
69         for (const auto &l : c) {
70             if (sectionFlags.count(l) == 0) {
71                 LOG_VERIFIER_DEBUG_CONFIG_WRONG_OPTION_FOR_SECTION(l, s.name, GetKeys(sectionFlags));
72                 return false;
73             }
74             sectionFlags.at(l).Of(verifOpts) = true;
75             LOG_VERIFIER_DEBUG_CONFIG_OPTION_IS_ACTIVE_INFO(s.name, l);
76         }
77     }
78     return true;
79 }
80 
RegisterConfigHandlerOptionsVerifierForSection(const PandaUnorderedMap<PandaString,StructField<VerificationOptions,bool>> & sectionFlags,VerificationOptions & verifOpts,const struct Section & s)81 static bool RegisterConfigHandlerOptionsVerifierForSection(
82     const PandaUnorderedMap<PandaString, StructField<VerificationOptions, bool>> &sectionFlags,
83     VerificationOptions &verifOpts, const struct Section &s)
84 {
85     for (const auto &i : s.items) {
86         PandaVector<PandaString> c;
87         const char *start = i.c_str();
88         const char *end = i.c_str() + i.length();  // NOLINT
89         if (!LiteralsParser()(c, start, end)) {
90             LOG_VERIFIER_DEBUG_CONFIG_WRONG_OPTIONS_LINE(i);
91             return false;
92         }
93         if (!RegisterConfigHandlerOptionsVerifierOptionLine(s, sectionFlags, verifOpts, c)) {
94             return false;
95         }
96     }
97     return true;
98 }
99 
RegisterConfigHandlerOptions(Config * dcfg)100 void RegisterConfigHandlerOptions(Config *dcfg)
101 {
102     static const auto CONFIG_DEBUG_OPTIONS_VERIFIER = [](Config *config, const Section &section) {
103         using BoolField = StructField<VerificationOptions, bool>;
104         using Flags = PandaUnorderedMap<PandaString, BoolField>;
105         using FlagsSection = PandaUnorderedMap<PandaString, Flags>;
106 
107         const FlagsSection flags = {
108             {"show",
109              {{"context", BoolField {offsetof(VerificationOptions, debug.show.context)}},
110               {"reg-changes", BoolField {offsetof(VerificationOptions, debug.show.regChanges)}},
111               {"typesystem", BoolField {offsetof(VerificationOptions, debug.show.typeSystem)}},
112               {"status", BoolField {offsetof(VerificationOptions, show.status)}}}},
113             {"allow",
114              {{"undefined-class", BoolField {offsetof(VerificationOptions, debug.allow.undefinedClass)}},
115               {"undefined-method", BoolField {offsetof(VerificationOptions, debug.allow.undefinedMethod)}},
116               {"undefined-field", BoolField {offsetof(VerificationOptions, debug.allow.undefinedField)}},
117               {"undefined-type", BoolField {offsetof(VerificationOptions, debug.allow.undefinedType)}},
118               {"undefined-string", BoolField {offsetof(VerificationOptions, debug.allow.undefinedString)}},
119               {"method-access-violation", BoolField {offsetof(VerificationOptions, debug.allow.methodAccessViolation)}},
120               {"field-access-violation", BoolField {offsetof(VerificationOptions, debug.allow.fieldAccessViolation)}},
121               {"wrong-subclassing-in-method-args",
122                BoolField {offsetof(VerificationOptions, debug.allow.wrongSubclassingInMethodArgs)}},
123               {"error-in-exception-handler",
124                BoolField {offsetof(VerificationOptions, debug.allow.errorInExceptionHandler)}},
125               {"permanent-runtime-exception",
126                BoolField {offsetof(VerificationOptions, debug.allow.permanentRuntimeException)}}}}};
127 
128         auto &verifOpts = config->opts;
129         for (const auto &s : section.sections) {
130             if (flags.count(s.name) == 0) {
131                 LOG_VERIFIER_DEBUG_CONFIG_WRONG_OPTIONS_SECTION(s.name, GetKeys(flags));
132                 return false;
133             }
134             const auto &sectionFlags = flags.at(s.name);
135             if (!RegisterConfigHandlerOptionsVerifierForSection(sectionFlags, verifOpts, s)) {
136                 return false;
137             }
138         }
139         return true;
140     };
141 
142     config::RegisterConfigHandler(dcfg, "config.debug.options.verifier", CONFIG_DEBUG_OPTIONS_VERIFIER);
143 }
144 
145 }  // namespace ark::verifier::debug
146