• 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 
16 #include "kvutil_fuzzer.h"
17 
18 #include <string>
19 #include <sys/stat.h>
20 #include <vector>
21 #include "distributed_kv_data_manager.h"
22 #include "fuzzer/FuzzedDataProvider.h"
23 #include "datashare_predicates.h"
24 #include "datashare_values_bucket.h"
25 #include "store_errno.h"
26 #include "kv_utils.h"
27 
28 using namespace OHOS;
29 using namespace OHOS::DistributedKv;
30 using namespace OHOS::DataShare;
31 namespace OHOS {
32 using ValueType = std::variant<std::monostate, int64_t, double, std::string, bool, std::vector<uint8_t>>;
33 static std::shared_ptr<SingleKvStore> singleKvStore_ = nullptr;
34 static constexpr const char *KEY = "key";
35 static constexpr const char *VALUE = "value";
36 static constexpr const char *PREFIX = "test_";
37 enum DataType {
38     STRING = 1,
39     INT64,
40     BOOL,
41     DOUBLE,
42     VECTOR_INT64,
43 };
44 
SetUpTestCase(void)45 void SetUpTestCase(void)
46 {
47     DistributedKvDataManager manager;
48     Options options = {
49         .createIfMissing = true,
50         .encrypt = false,
51         .autoSync = true,
52         .securityLevel = S1,
53         .kvStoreType = KvStoreType::SINGLE_VERSION
54     };
55     options.area = EL1;
56     AppId appId = { "kvstorefuzzertest" };
57     options.baseDir = std::string("/data/service/el1/public/database/") + appId.appId;
58     /* define kvstore(database) name. */
59     StoreId storeId = { "fuzzer_single" };
60     mkdir(options.baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
61     /* [create and] open and initialize kvstore instance. */
62     manager.GetSingleKvStore(options, appId, storeId, singleKvStore_);
63 }
64 
TearDown(void)65 void TearDown(void)
66 {
67     (void)remove("/data/service/el1/public/database/kvutilfuzzertest/key");
68     (void)remove("/data/service/el1/public/database/kvutilfuzzertest/kvdb");
69     (void)remove("/data/service/el1/public/database/kvutilfuzzertest");
70 }
71 
ToResultSetBridgeFuzz(FuzzedDataProvider & provider)72 void ToResultSetBridgeFuzz(FuzzedDataProvider &provider)
73 {
74     std::string skey;
75     std::string svalue;
76     Entry entry;
77     std::vector<Entry> entries;
78     std::vector<Key> keys;
79     int sum = provider.ConsumeIntegralInRange<size_t>(0, 10);
80     for (size_t i = 0; i < sum; i++) {
81         skey = provider.ConsumeRandomLengthString();
82         svalue = provider.ConsumeRandomLengthString();
83         entry.key = {PREFIX + skey};
84         entry.value = {PREFIX + svalue};
85         entries.push_back(entry);
86         keys.push_back(entry.key);
87     }
88     singleKvStore_->PutBatch(entries);
89     std::shared_ptr<KvStoreResultSet> resultSet = nullptr;
90     DataSharePredicates predicates;
91     predicates.KeyPrefix("test");
92     DataQuery query;
93     auto status = KvUtils::ToQuery(predicates, query);
94     if (status == Status::SUCCESS) {
95         status = singleKvStore_->GetResultSet(query, resultSet);
96     }
97     KvUtils::ToResultSetBridge(resultSet);
98     singleKvStore_->DeleteBatch(keys);
99 }
100 
ToEntryFuzz(FuzzedDataProvider & provider)101 void ToEntryFuzz(FuzzedDataProvider &provider)
102 {
103     DataShareValuesBucket bucket {};
104     if (provider.ConsumeBool()) {
105         bucket.Put(KEY, provider.ConsumeRandomLengthString());
106         bucket.Put(VALUE, provider.ConsumeRandomLengthString());
107     }
108     auto entry = KvUtils::ToEntry(bucket);
109 }
110 
CreateData(int32_t type,FuzzedDataProvider & provider)111 ValueType CreateData(int32_t type, FuzzedDataProvider &provider)
112 {
113     ValueType data;
114     switch (type) {
115         case DataType::STRING:
116             data = provider.ConsumeRandomLengthString();
117             break;
118         case DataType::INT64:
119             data = provider.ConsumeIntegral<int64_t>();
120             break;
121         case DataType::BOOL:
122             data = provider.ConsumeBool();
123             break;
124         case DataType::DOUBLE:
125             data = provider.ConsumeFloatingPoint<double>();
126             break;
127         case DataType::VECTOR_INT64:
128             data = provider.ConsumeRemainingBytes<uint8_t>();
129             break;
130         default:
131             data = {};
132             break;
133     }
134     return data;
135 }
136 
ToEntriesFuzz(FuzzedDataProvider & provider)137 void ToEntriesFuzz(FuzzedDataProvider &provider)
138 {
139     std::vector<DataShareValuesBucket> buckets;
140     const uint8_t bucketCount = provider.ConsumeIntegralInRange<uint8_t>(1, 10);
141     DataShareValuesBucket bucket;
142     ValueType key;
143     ValueType value;
144     for (int i = 1; i < bucketCount; ++i) {
145         auto keyType = provider.ConsumeIntegralInRange(1, 5);
146         auto valueType = provider.ConsumeIntegralInRange(1, 5);
147         key = CreateData(keyType, provider);
148         value = CreateData(valueType, provider);
149         bucket.Put(KEY, key);
150         bucket.Put(VALUE, value);
151         buckets.push_back(std::move(bucket));
152     }
153     auto entry = KvUtils::ToEntries(buckets);
154 }
155 
GetKeysFuzz(FuzzedDataProvider & provider)156 void GetKeysFuzz(FuzzedDataProvider &provider)
157 {
158     std::vector<std::string> keys;
159     keys.push_back(provider.ConsumeRandomLengthString());
160     keys.push_back(provider.ConsumeRandomLengthString());
161     keys.push_back(provider.ConsumeRandomLengthString());
162     DataSharePredicates predicates;
163     predicates.InKeys(keys);
164     std::vector<Key> kvKeys;
165     KvUtils::GetKeys(predicates, kvKeys);
166 }
167 } // namespace OHOS
168 
169 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)170 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
171 {
172     /* Run your code on data */
173     FuzzedDataProvider provider(data, size);
174     OHOS::SetUpTestCase();
175     OHOS::ToResultSetBridgeFuzz(provider);
176     OHOS::ToEntryFuzz(provider);
177     OHOS::ToEntriesFuzz(provider);
178     OHOS::GetKeysFuzz(provider);
179     OHOS::TearDown();
180     return 0;
181 }