• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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