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 "hiappevent_verify.h"
17
18 #include <iterator>
19 #include <regex>
20
21 #include "hiappevent_base.h"
22 #include "hiappevent_config.h"
23 #include "hilog/log.h"
24
25 using namespace OHOS::HiviewDFX::ErrorCode;
26
27 namespace OHOS {
28 namespace HiviewDFX {
29 namespace {
30 static constexpr HiLogLabel LABEL = { LOG_CORE, HIAPPEVENT_DOMAIN, "HiAppEvent_verify" };
31
32 constexpr size_t MAX_LEN_OF_WATCHER = 32;
33 constexpr size_t MAX_LEN_OF_DOMAIN = 16;
34 static constexpr int MAX_LENGTH_OF_EVENT_NAME = 48;
35 static constexpr int MAX_LENGTH_OF_PARAM_NAME = 16;
36 static constexpr unsigned int MAX_NUM_OF_PARAMS = 32;
37 static constexpr int MAX_LENGTH_OF_STR_PARAM = 8 * 1024;
38 static constexpr int MAX_SIZE_OF_LIST_PARAM = 100;
39
CheckEventName(const std::string & eventName)40 bool CheckEventName(const std::string& eventName)
41 {
42 if (eventName.empty() || eventName.length() > MAX_LENGTH_OF_EVENT_NAME) {
43 return false;
44 }
45
46 /* custom and preset events */
47 if (!std::regex_match(eventName, std::regex("^[a-z][a-z0-9_]*[a-z0-9]$|^hiappevent\\.[a-z][a-z0-9_]*[a-z0-9]$"))) {
48 return false;
49 }
50
51 return true;
52 }
53
CheckParamName(const std::string & paramName)54 bool CheckParamName(const std::string& paramName)
55 {
56 if (paramName.empty() || paramName.length() > MAX_LENGTH_OF_PARAM_NAME) {
57 return false;
58 }
59
60 if (!std::regex_match(paramName, std::regex("^[a-z][a-z0-9_]*[a-z0-9]$"))) {
61 return false;
62 }
63
64 return true;
65 }
66
EscapeStringValue(std::string & value)67 void EscapeStringValue(std::string &value)
68 {
69 std::string escapeValue;
70 for (auto it = value.begin(); it != value.end(); it++) {
71 switch (*it) {
72 case '\\':
73 escapeValue.append("\\\\");
74 break;
75 case '\"':
76 escapeValue.append("\\\"");
77 break;
78 case '\b':
79 escapeValue.append("\\b");
80 break;
81 case '\f':
82 escapeValue.append("\\f");
83 break;
84 case '\n':
85 escapeValue.append("\\n");
86 break;
87 case '\r':
88 escapeValue.append("\\r");
89 break;
90 case '\t':
91 escapeValue.append("\\t");
92 break;
93 default:
94 escapeValue.push_back(*it);
95 break;
96 }
97 }
98 value = escapeValue;
99 }
100
CheckStrParamLength(std::string & strParamValue)101 bool CheckStrParamLength(std::string& strParamValue)
102 {
103 if (strParamValue.empty()) {
104 HiLog::Warn(LABEL, "str param value is empty.");
105 return true;
106 }
107
108 if (strParamValue.length() > MAX_LENGTH_OF_STR_PARAM) {
109 return false;
110 }
111
112 EscapeStringValue(strParamValue);
113 return true;
114 }
115
CheckListValueSize(AppEventParamType type,AppEventParamValue::ValueUnion & vu)116 bool CheckListValueSize(AppEventParamType type, AppEventParamValue::ValueUnion& vu)
117 {
118 if (type == AppEventParamType::BVECTOR && vu.bs_.size() > MAX_SIZE_OF_LIST_PARAM) {
119 vu.bs_.resize(MAX_SIZE_OF_LIST_PARAM);
120 } else if (type == AppEventParamType::CVECTOR && vu.cs_.size() > MAX_SIZE_OF_LIST_PARAM) {
121 vu.cs_.resize(MAX_SIZE_OF_LIST_PARAM);
122 } else if (type == AppEventParamType::SHVECTOR && vu.shs_.size() > MAX_SIZE_OF_LIST_PARAM) {
123 vu.shs_.resize(MAX_SIZE_OF_LIST_PARAM);
124 } else if (type == AppEventParamType::IVECTOR && vu.is_.size() > MAX_SIZE_OF_LIST_PARAM) {
125 vu.is_.resize(MAX_SIZE_OF_LIST_PARAM);
126 } else if (type == AppEventParamType::LLVECTOR && vu.lls_.size() > MAX_SIZE_OF_LIST_PARAM) {
127 vu.lls_.resize(MAX_SIZE_OF_LIST_PARAM);
128 } else if (type == AppEventParamType::FVECTOR && vu.fs_.size() > MAX_SIZE_OF_LIST_PARAM) {
129 vu.fs_.resize(MAX_SIZE_OF_LIST_PARAM);
130 } else if (type == AppEventParamType::DVECTOR && vu.ds_.size() > MAX_SIZE_OF_LIST_PARAM) {
131 vu.ds_.resize(MAX_SIZE_OF_LIST_PARAM);
132 } else if (type == AppEventParamType::STRVECTOR && vu.strs_.size() > MAX_SIZE_OF_LIST_PARAM) {
133 vu.strs_.resize(MAX_SIZE_OF_LIST_PARAM);
134 } else {
135 return true;
136 }
137
138 return false;
139 }
140
CheckStringLengthOfList(std::vector<std::string> & strs)141 bool CheckStringLengthOfList(std::vector<std::string>& strs)
142 {
143 if (strs.empty()) {
144 return true;
145 }
146
147 for (auto it = strs.begin(); it != strs.end(); it++) {
148 if (!CheckStrParamLength(*it)) {
149 return false;
150 }
151 }
152
153 return true;
154 }
155
CheckParamsNum(std::list<AppEventParam> & baseParams)156 bool CheckParamsNum(std::list<AppEventParam>& baseParams)
157 {
158 if (baseParams.size() == 0) {
159 return true;
160 }
161
162 auto listSize = baseParams.size();
163 if (listSize > MAX_NUM_OF_PARAMS) {
164 auto delStartPtr = baseParams.begin();
165 std::advance(delStartPtr, MAX_NUM_OF_PARAMS);
166 baseParams.erase(delStartPtr, baseParams.end());
167 return false;
168 }
169
170 return true;
171 }
172 }
173
IsValidDomain(const std::string & eventDomain)174 bool IsValidDomain(const std::string& eventDomain)
175 {
176 if (eventDomain.empty() || eventDomain.length() > MAX_LEN_OF_DOMAIN) {
177 return false;
178 }
179 if (!std::regex_match(eventDomain, std::regex("^[a-z][a-z0-9_]*[a-z0-9]$"))) {
180 return false;
181 }
182 return true;
183 }
184
IsValidWatcherName(const std::string & watcherName)185 bool IsValidWatcherName(const std::string& watcherName)
186 {
187 if (watcherName.empty() || watcherName.length() > MAX_LEN_OF_WATCHER) {
188 return false;
189 }
190 return std::regex_match(watcherName, std::regex("^[a-z][a-z0-9_]*[a-z0-9]$"));
191 }
192
IsValidEventType(int eventType)193 bool IsValidEventType(int eventType)
194 {
195 return eventType >= 1 && eventType <= 4; // 1-4: value range of event type
196 }
197
VerifyAppEvent(std::shared_ptr<AppEventPack> & appEventPack)198 int VerifyAppEvent(std::shared_ptr<AppEventPack>& appEventPack)
199 {
200 if (HiAppEventConfig::GetInstance().GetDisable()) {
201 HiLog::Error(LABEL, "the HiAppEvent function is disabled.");
202 return ERROR_HIAPPEVENT_DISABLE;
203 }
204 if (!IsValidDomain(appEventPack->GetEventDomain())) {
205 HiLog::Error(LABEL, "eventDomain=%{public}s is invalid.", appEventPack->GetEventDomain().c_str());
206 return ERROR_INVALID_EVENT_DOMAIN;
207 }
208 if (!CheckEventName(appEventPack->GetEventName())) {
209 HiLog::Error(LABEL, "eventName=%{public}s is invalid.", appEventPack->GetEventName().c_str());
210 return ERROR_INVALID_EVENT_NAME;
211 }
212
213 int verifyRes = HIAPPEVENT_VERIFY_SUCCESSFUL;
214 std::list<AppEventParam>& baseParams = appEventPack->baseParams_;
215 if (!CheckParamsNum(baseParams)) {
216 HiLog::Warn(LABEL, "params that exceed 32 are discarded because the number of params cannot exceed 32.");
217 verifyRes = ERROR_INVALID_PARAM_NUM;
218 }
219
220 for (auto it = baseParams.begin(); it != baseParams.end();) {
221 if (!CheckParamName(it->name)) {
222 HiLog::Warn(LABEL, "param=%{public}s is discarded because the paramName is invalid.", it->name.c_str());
223 verifyRes = ERROR_INVALID_PARAM_NAME;
224 baseParams.erase(it++);
225 continue;
226 }
227
228 if (it->type == AppEventParamType::STRING && !CheckStrParamLength(it->value.valueUnion.str_)) {
229 HiLog::Warn(LABEL, "param=%{public}s is discarded because the string length exceeds 8192.",
230 it->name.c_str());
231 verifyRes = ERROR_INVALID_PARAM_VALUE_LENGTH;
232 baseParams.erase(it++);
233 continue;
234 }
235
236 if (it->type > AppEventParamType::STRING && !CheckListValueSize(it->type, it->value.valueUnion)) {
237 HiLog::Warn(LABEL, "list param=%{public}s is truncated because the list size exceeds 100.",
238 it->name.c_str());
239 verifyRes = ERROR_INVALID_LIST_PARAM_SIZE;
240 continue;
241 }
242
243 if (it->type == AppEventParamType::STRVECTOR && !CheckStringLengthOfList(it->value.valueUnion.strs_)) {
244 HiLog::Warn(LABEL, "param=%{public}s is discarded because the string length of list exceeds 8192.",
245 it->name.c_str());
246 verifyRes = ERROR_INVALID_PARAM_VALUE_LENGTH;
247 baseParams.erase(it++);
248 continue;
249 }
250 it++;
251 }
252
253 return verifyRes;
254 }
255 } // namespace HiviewDFX
256 } // namespace OHOS
257