1115cd2caSopenharmony_ci/*
2115cd2caSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3115cd2caSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4115cd2caSopenharmony_ci * you may not use this file except in compliance with the License.
5115cd2caSopenharmony_ci * You may obtain a copy of the License at
6115cd2caSopenharmony_ci *
7115cd2caSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8115cd2caSopenharmony_ci *
9115cd2caSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10115cd2caSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11115cd2caSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12115cd2caSopenharmony_ci * See the License for the specific language governing permissions and
13115cd2caSopenharmony_ci * limitations under the License.
14115cd2caSopenharmony_ci */
15115cd2caSopenharmony_ci#include "sql_analyzer.h"
16115cd2caSopenharmony_ci
17115cd2caSopenharmony_ci#include "hilog_wrapper.h"
18115cd2caSopenharmony_ci
19115cd2caSopenharmony_cinamespace OHOS {
20115cd2caSopenharmony_cinamespace Contacts {
21115cd2caSopenharmony_ciconstexpr int POS_ADD_TWO = 2;
22115cd2caSopenharmony_ci
23115cd2caSopenharmony_ciSqlAnalyzer::SqlAnalyzer()
24115cd2caSopenharmony_ci{
25115cd2caSopenharmony_ci}
26115cd2caSopenharmony_ci
27115cd2caSopenharmony_ciSqlAnalyzer::~SqlAnalyzer()
28115cd2caSopenharmony_ci{
29115cd2caSopenharmony_ci}
30115cd2caSopenharmony_ci
31115cd2caSopenharmony_cibool SqlAnalyzer::CheckValuesBucket(const OHOS::NativeRdb::ValuesBucket &value)
32115cd2caSopenharmony_ci{
33115cd2caSopenharmony_ci    std::map<std::string, NativeRdb::ValueObject> valuesMap;
34115cd2caSopenharmony_ci    value.GetAll(valuesMap);
35115cd2caSopenharmony_ci    for (auto it = valuesMap.begin(); it != valuesMap.end(); ++it) {
36115cd2caSopenharmony_ci        std::string key = it->first;
37115cd2caSopenharmony_ci        bool isKey = FindIllegalWords(key);
38115cd2caSopenharmony_ci        if (isKey) {
39115cd2caSopenharmony_ci            HILOG_ERROR("SqlAnalyzer CheckValuesBucket key is %{public}s error", key.c_str());
40115cd2caSopenharmony_ci            return false;
41115cd2caSopenharmony_ci        }
42115cd2caSopenharmony_ci        NativeRdb::ValueObject value = it->second;
43115cd2caSopenharmony_ci        if (value.GetType() == NativeRdb::ValueObjectType::TYPE_STRING) {
44115cd2caSopenharmony_ci            std::string str;
45115cd2caSopenharmony_ci            value.GetString(str);
46115cd2caSopenharmony_ci            str = ParseSpecial(str);
47115cd2caSopenharmony_ci            bool isValue = FindIllegalWords(str);
48115cd2caSopenharmony_ci            if (isValue) {
49115cd2caSopenharmony_ci                HILOG_ERROR("SqlAnalyzer CheckValuesBucket value is %{public}s error", str.c_str());
50115cd2caSopenharmony_ci                return false;
51115cd2caSopenharmony_ci            }
52115cd2caSopenharmony_ci        }
53115cd2caSopenharmony_ci    }
54115cd2caSopenharmony_ci    return true;
55115cd2caSopenharmony_ci}
56115cd2caSopenharmony_ci
57115cd2caSopenharmony_cibool SqlAnalyzer::CharCheck(char &ch, std::string sql, std::size_t &pos)
58115cd2caSopenharmony_ci{
59115cd2caSopenharmony_ci    if (ch == '[') {
60115cd2caSopenharmony_ci        pos++;
61115cd2caSopenharmony_ci        std::size_t found = sql.find(']', pos);
62115cd2caSopenharmony_ci        if (found == std::string::npos) {
63115cd2caSopenharmony_ci            return true;
64115cd2caSopenharmony_ci        }
65115cd2caSopenharmony_ci        pos++;
66115cd2caSopenharmony_ci    }
67115cd2caSopenharmony_ci    if (ch == '-' && PickChar(sql, pos + 1) == '-') {
68115cd2caSopenharmony_ci        pos += POS_ADD_TWO;
69115cd2caSopenharmony_ci        std::size_t found = sql.find('\n', pos);
70115cd2caSopenharmony_ci        if (found == std::string::npos) {
71115cd2caSopenharmony_ci            return true;
72115cd2caSopenharmony_ci        }
73115cd2caSopenharmony_ci        pos++;
74115cd2caSopenharmony_ci    }
75115cd2caSopenharmony_ci    if (ch == '/' && PickChar(sql, pos + 1) == '*') {
76115cd2caSopenharmony_ci        pos += POS_ADD_TWO;
77115cd2caSopenharmony_ci        std::size_t found = sql.find("*/", pos);
78115cd2caSopenharmony_ci        if (found == std::string::npos) {
79115cd2caSopenharmony_ci            return true;
80115cd2caSopenharmony_ci        }
81115cd2caSopenharmony_ci        pos += POS_ADD_TWO;
82115cd2caSopenharmony_ci    }
83115cd2caSopenharmony_ci    if (ch == ';') {
84115cd2caSopenharmony_ci        return true;
85115cd2caSopenharmony_ci    }
86115cd2caSopenharmony_ci    pos++;
87115cd2caSopenharmony_ci    return false;
88115cd2caSopenharmony_ci}
89115cd2caSopenharmony_ci
90115cd2caSopenharmony_cibool SqlAnalyzer::StrCheck(char &ch, std::size_t strlen, std::string sql, std::size_t &pos)
91115cd2caSopenharmony_ci{
92115cd2caSopenharmony_ci    if (IsInStr(ch, "'\"`") == 0) {
93115cd2caSopenharmony_ci        pos++;
94115cd2caSopenharmony_ci        while (pos < strlen) {
95115cd2caSopenharmony_ci            std::size_t found = sql.find(ch, pos);
96115cd2caSopenharmony_ci            if (found == std::string::npos) {
97115cd2caSopenharmony_ci                return true;
98115cd2caSopenharmony_ci            }
99115cd2caSopenharmony_ci            if (PickChar(sql, pos + 1) != ch) {
100115cd2caSopenharmony_ci                break;
101115cd2caSopenharmony_ci            }
102115cd2caSopenharmony_ci            pos += POS_ADD_TWO;
103115cd2caSopenharmony_ci        }
104115cd2caSopenharmony_ci    }
105115cd2caSopenharmony_ci    return false;
106115cd2caSopenharmony_ci}
107115cd2caSopenharmony_ci
108115cd2caSopenharmony_cibool SqlAnalyzer::FindIllegalWords(std::string sql)
109115cd2caSopenharmony_ci{
110115cd2caSopenharmony_ci    if (sql.empty()) {
111115cd2caSopenharmony_ci        return false;
112115cd2caSopenharmony_ci    }
113115cd2caSopenharmony_ci    std::size_t pos = 0;
114115cd2caSopenharmony_ci    std::size_t strlen = sql.length();
115115cd2caSopenharmony_ci    while (pos < strlen) {
116115cd2caSopenharmony_ci        char ch = PickChar(sql, pos);
117115cd2caSopenharmony_ci        if (IsLetter(ch)) {
118115cd2caSopenharmony_ci            std::size_t start = pos;
119115cd2caSopenharmony_ci            pos++;
120115cd2caSopenharmony_ci            while (IsLetterNumber(PickChar(sql, pos))) {
121115cd2caSopenharmony_ci                pos++;
122115cd2caSopenharmony_ci            }
123115cd2caSopenharmony_ci            std::size_t count = pos - start + 1;
124115cd2caSopenharmony_ci            sql.substr(start, count);
125115cd2caSopenharmony_ci        }
126115cd2caSopenharmony_ci        if (IsInStr(ch, "'\"`") == 0) {
127115cd2caSopenharmony_ci            if (StrCheck(ch, strlen, sql, pos)) {
128115cd2caSopenharmony_ci                return true;
129115cd2caSopenharmony_ci            } else {
130115cd2caSopenharmony_ci                continue;
131115cd2caSopenharmony_ci            }
132115cd2caSopenharmony_ci        }
133115cd2caSopenharmony_ci        if (CharCheck(ch, sql, pos)) {
134115cd2caSopenharmony_ci            return true;
135115cd2caSopenharmony_ci        } else {
136115cd2caSopenharmony_ci            continue;
137115cd2caSopenharmony_ci        }
138115cd2caSopenharmony_ci    }
139115cd2caSopenharmony_ci    return false;
140115cd2caSopenharmony_ci}
141115cd2caSopenharmony_ci} // namespace Contacts
142115cd2caSopenharmony_ci} // namespace OHOS