• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 static constexpr int MAX_LENGTH_OF_EVENT_NAME = 48;
33 static constexpr int MAX_LENGTH_OF_PARAM_NAME = 16;
34 static constexpr unsigned int MAX_NUM_OF_PARAMS = 32;
35 static constexpr int MAX_LENGTH_OF_STR_PARAM = 8 * 1024;
36 static constexpr int MAX_SIZE_OF_LIST_PARAM = 100;
37 
CheckEventName(const std::string & eventName)38 bool CheckEventName(const std::string& eventName)
39 {
40     if (eventName.empty() || eventName.length() > MAX_LENGTH_OF_EVENT_NAME) {
41         return false;
42     }
43 
44     /* custom and preset events */
45     if (!std::regex_match(eventName, std::regex("^[a-z][a-z0-9_]*$|^hiappevent\\.[a-z][a-z0-9_]*$"))) {
46         return false;
47     }
48 
49     return true;
50 }
51 
CheckParamName(const std::string & paramName)52 bool CheckParamName(const std::string& paramName)
53 {
54     if (paramName.empty() || paramName.length() > MAX_LENGTH_OF_PARAM_NAME) {
55         return false;
56     }
57 
58     if (!std::regex_match(paramName, std::regex("^[a-z][a-z0-9_]*[a-z0-9]$"))) {
59         return false;
60     }
61 
62     return true;
63 }
64 
EscapeStringValue(std::string & value)65 void EscapeStringValue(std::string &value)
66 {
67     std::string escapeValue;
68     for (auto it = value.begin(); it != value.end(); it++) {
69         switch (*it) {
70             case '\\':
71                 escapeValue.append("\\\\");
72                 break;
73             case '\"':
74                 escapeValue.append("\\\"");
75                 break;
76             case '\b':
77                 escapeValue.append("\\b");
78                 break;
79             case '\f':
80                 escapeValue.append("\\f");
81                 break;
82             case '\n':
83                 escapeValue.append("\\n");
84                 break;
85             case '\r':
86                 escapeValue.append("\\r");
87                 break;
88             case '\t':
89                 escapeValue.append("\\t");
90                 break;
91             default:
92                 escapeValue.push_back(*it);
93                 break;
94         }
95     }
96     value = escapeValue;
97 }
98 
CheckStrParamLength(std::string & strParamValue)99 bool CheckStrParamLength(std::string& strParamValue)
100 {
101     if (strParamValue.empty()) {
102         HiLog::Warn(LABEL, "str param value is empty.");
103         return true;
104     }
105 
106     if (strParamValue.length() > MAX_LENGTH_OF_STR_PARAM) {
107         return false;
108     }
109 
110     EscapeStringValue(strParamValue);
111     return true;
112 }
113 
CheckListValueSize(AppEventParamType type,AppEventParamValue::ValueUnion & vu)114 bool CheckListValueSize(AppEventParamType type, AppEventParamValue::ValueUnion& vu)
115 {
116     if (type == AppEventParamType::BVECTOR && vu.bs_.size() > MAX_SIZE_OF_LIST_PARAM) {
117         vu.bs_.resize(MAX_SIZE_OF_LIST_PARAM);
118     } else if (type == AppEventParamType::CVECTOR && vu.cs_.size() > MAX_SIZE_OF_LIST_PARAM) {
119         vu.cs_.resize(MAX_SIZE_OF_LIST_PARAM);
120     } else if (type == AppEventParamType::SHVECTOR && vu.shs_.size() > MAX_SIZE_OF_LIST_PARAM) {
121         vu.shs_.resize(MAX_SIZE_OF_LIST_PARAM);
122     } else if (type == AppEventParamType::IVECTOR && vu.is_.size() > MAX_SIZE_OF_LIST_PARAM) {
123         vu.is_.resize(MAX_SIZE_OF_LIST_PARAM);
124     } else if (type == AppEventParamType::LVECTOR && vu.ls_.size() > MAX_SIZE_OF_LIST_PARAM) {
125         vu.ls_.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 
VerifyAppEvent(std::shared_ptr<AppEventPack> & appEventPack)174 int VerifyAppEvent(std::shared_ptr<AppEventPack>& appEventPack)
175 {
176     if (HiAppEventConfig::GetInstance().GetDisable()) {
177         HiLog::Error(LABEL, "the HiAppEvent function is disabled.");
178         return ERROR_HIAPPEVENT_DISABLE;
179     }
180 
181     if (!CheckEventName(appEventPack->GetEventName())) {
182         HiLog::Error(LABEL, "eventName=%{public}s is invalid.", appEventPack->GetEventName().c_str());
183         return ERROR_INVALID_EVENT_NAME;
184     }
185 
186     int verifyRes = HIAPPEVENT_VERIFY_SUCCESSFUL;
187     std::list<AppEventParam>& baseParams = appEventPack->baseParams_;
188     if (!CheckParamsNum(baseParams)) {
189         HiLog::Warn(LABEL, "params that exceed 32 are discarded because the number of params cannot exceed 32.");
190         verifyRes = ERROR_INVALID_PARAM_NUM;
191     }
192 
193     for (auto it = baseParams.begin(); it != baseParams.end();) {
194         if (!CheckParamName(it->name)) {
195             HiLog::Warn(LABEL, "param=%{public}s is discarded because the paramName is invalid.", it->name.c_str());
196             verifyRes = ERROR_INVALID_PARAM_NAME;
197             baseParams.erase(it++);
198             continue;
199         }
200 
201         if (it->type == AppEventParamType::STRING && !CheckStrParamLength(it->value.valueUnion.str_)) {
202             HiLog::Warn(LABEL, "param=%{public}s is discarded because the string length exceeds 8192.",
203                 it->name.c_str());
204             verifyRes = ERROR_INVALID_PARAM_VALUE_LENGTH;
205             baseParams.erase(it++);
206             continue;
207         }
208 
209         if (it->type > AppEventParamType::STRING && !CheckListValueSize(it->type, it->value.valueUnion)) {
210             HiLog::Warn(LABEL, "list param=%{public}s is truncated because the list size exceeds 100.",
211                 it->name.c_str());
212             verifyRes = ERROR_INVALID_LIST_PARAM_SIZE;
213             continue;
214         }
215 
216         if (it->type == AppEventParamType::STRVECTOR && !CheckStringLengthOfList(it->value.valueUnion.strs_)) {
217             HiLog::Warn(LABEL, "param=%{public}s is discarded because the string length of list exceeds 8192.",
218                 it->name.c_str());
219             verifyRes = ERROR_INVALID_PARAM_VALUE_LENGTH;
220             baseParams.erase(it++);
221             continue;
222         }
223         it++;
224     }
225 
226     return verifyRes;
227 }
228 } // HiviewDFX
229 } // OHOS