• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #include "transdb_fuzzer.h"
16 
17 #include <fuzzer/FuzzedDataProvider.h>
18 #include <rdb_helper.h>
19 #include <rdb_store.h>
20 #include <rdb_store_config.h>
21 #include <securec.h>
22 #include <values_bucket.h>
23 
24 #include <memory>
25 
26 #include "connection_pool.h"
27 #include "trans_db.h"
28 
29 using namespace OHOS;
30 using namespace OHOS::NativeRdb;
31 namespace OHOS {
32 
33 static constexpr const char *CREATE_TABLE = "CREATE TABLE IF NOT EXISTS TEST (id INT PRIMARY KEY, name TEXT, "
34                                             "extend BLOB, code REAL, years UNLIMITED INT, attachment ASSET, "
35                                             "attachments ASSETS)";
36 static constexpr const char *DROP_TABLE = "DROP TABLE IF EXISTS TEST";
37 static constexpr const char *TABLE_NAME = "TEST";
38 static const int MIN_ROWS_SIZE = 1;
39 static const int MAX_ROWS_SIZE = 50;
40 
FillDataToValuesBucket(FuzzedDataProvider & provider,ValuesBucket & value)41 void FillDataToValuesBucket(FuzzedDataProvider &provider, ValuesBucket &value)
42 {
43     std::string valName = provider.ConsumeRandomLengthString();
44     int valAge = provider.ConsumeIntegral<int>();
45     double valSalary = provider.ConsumeFloatingPoint<double>();
46 
47     value.PutString("name", valName);
48     value.PutInt("age", valAge);
49     value.PutDouble("salary", valSalary);
50 }
51 
FillDataToValuesBuckets(FuzzedDataProvider & provider,ValuesBuckets & values)52 void FillDataToValuesBuckets(FuzzedDataProvider &provider, ValuesBuckets &values)
53 {
54     uint32_t loopTimes = provider.ConsumeIntegralInRange<uint32_t>(MIN_ROWS_SIZE, MAX_ROWS_SIZE);
55     for (uint32_t i = 0; i < loopTimes; i++) {
56         ValuesBucket value;
57         FillDataToValuesBucket(provider, value);
58         values.Put(value);
59     }
60 }
61 
TransDbExecuteFuzzTest(std::shared_ptr<RdbStore> transDB,FuzzedDataProvider & provider)62 void TransDbExecuteFuzzTest(std::shared_ptr<RdbStore> transDB, FuzzedDataProvider &provider)
63 {
64     if (transDB == nullptr) {
65         return;
66     }
67     transDB->Execute(DROP_TABLE);
68     transDB->Execute(CREATE_TABLE);
69     std::string sql = provider.ConsumeRandomLengthString();
70     transDB->Execute(sql);
71 }
72 
GetConflictResolution(FuzzedDataProvider & provider)73 ConflictResolution GetConflictResolution(FuzzedDataProvider &provider)
74 {
75     int min = static_cast<int>(ConflictResolution::ON_CONFLICT_NONE);
76     int max = static_cast<int>(ConflictResolution::ON_CONFLICT_REPLACE);
77     int enumInt = provider.ConsumeIntegralInRange<int>(min, max);
78     ConflictResolution resolution = static_cast<ConflictResolution>(enumInt);
79     return resolution;
80 }
81 
TransDbInsertFuzzTest(std::shared_ptr<RdbStore> transDB,FuzzedDataProvider & provider)82 void TransDbInsertFuzzTest(std::shared_ptr<RdbStore> transDB, FuzzedDataProvider &provider)
83 {
84     if (transDB == nullptr) {
85         return;
86     }
87     ValuesBucket value;
88     FillDataToValuesBucket(provider, value);
89 
90     {
91         ConflictResolution resolution = GetConflictResolution(provider);
92         transDB->Insert(TABLE_NAME, value, resolution);
93     }
94 
95     ValuesBuckets rows;
96     FillDataToValuesBuckets(provider, rows);
97     transDB->BatchInsert(TABLE_NAME, rows);
98 
99     {
100         ConflictResolution resolution = GetConflictResolution(provider);
101         transDB->BatchInsert(TABLE_NAME, rows, resolution);
102     }
103 }
104 
TransDbFuzzTest(FuzzedDataProvider & provider)105 void TransDbFuzzTest(FuzzedDataProvider &provider)
106 {
107     std::string path = provider.ConsumeRandomLengthString();
108     RdbStoreConfig config(path);
109     config.SetHaMode(provider.ConsumeIntegral<int32_t>());
110     int errCode = 0;
111     std::shared_ptr<ConnectionPool> connPool = ConnectionPool::Create(config, errCode);
112     if (connPool == nullptr) {
113         return;
114     }
115     auto [err, conn] = connPool->CreateTransConn();
116     if (err != E_OK || conn == nullptr) {
117         return;
118     }
119     std::shared_ptr<RdbStore> transDB = std::make_shared<TransDB>(conn, config.GetName());
120     if (transDB == nullptr) {
121         return;
122     }
123     TransDbExecuteFuzzTest(transDB, provider);
124     TransDbInsertFuzzTest(transDB, provider);
125 }
126 
127 } // namespace OHOS
128 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)129 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
130 {
131     FuzzedDataProvider provider(data, size);
132     OHOS::TransDbFuzzTest(provider);
133     return 0;
134 }
135