• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "containersplainarray_fuzzer.h"
17 
18 #include "ecmascript/base/builtins_base.h"
19 #include "ecmascript/containers/containers_plainarray.h"
20 #include "ecmascript/containers/containers_private.h"
21 #include "ecmascript/ecma_string-inl.h"
22 #include "ecmascript/ecma_vm.h"
23 #include "ecmascript/global_env.h"
24 #include "ecmascript/js_api/js_api_plain_array.h"
25 #include "ecmascript/js_handle.h"
26 #include "ecmascript/napi/include/jsnapi.h"
27 
28 using namespace panda;
29 using namespace panda::ecmascript;
30 using namespace panda::ecmascript::base;
31 using namespace panda::ecmascript::containers;
32 
33 namespace OHOS {
JSObjectCreate(JSThread * thread)34     JSFunction *JSObjectCreate(JSThread *thread)
35     {
36         JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
37         return globalEnv->GetObjectFunction().GetObject<JSFunction>();
38     }
39 
CreateEcmaRuntimeCallInfo(JSThread * thread,uint32_t numArgs)40     EcmaRuntimeCallInfo *CreateEcmaRuntimeCallInfo(JSThread *thread, uint32_t numArgs)
41     {
42         auto factory = thread->GetEcmaVM()->GetFactory();
43         JSHandle<JSTaggedValue> hclass(thread, JSObjectCreate(thread));
44         JSHandle<JSTaggedValue> callee(factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
45         JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
46         EcmaRuntimeCallInfo *objCallInfo =
47             EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, callee, undefined, numArgs);
48         return objCallInfo;
49     }
50 
InitializePlainArrayConstructor(JSThread * thread)51     JSTaggedValue InitializePlainArrayConstructor(JSThread *thread)
52     {
53         auto factory = thread->GetEcmaVM()->GetFactory();
54         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
55         JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
56         JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
57         JSHandle<JSTaggedValue> value =
58             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
59 
60         auto objCallInfo = CreateEcmaRuntimeCallInfo(thread, 6); // 6 : means the argv length
61         objCallInfo->SetFunction(JSTaggedValue::Undefined());
62         objCallInfo->SetThis(value.GetTaggedValue());
63         objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(ContainerTag::PlainArray)));
64         JSTaggedValue result = ContainersPrivate::Load(objCallInfo);
65         return result;
66     }
67 
CreateJSAPIPlainArray(JSThread * thread)68     JSHandle<JSAPIPlainArray> CreateJSAPIPlainArray(JSThread *thread)
69     {
70         JSHandle<JSFunction> newTarget(thread, InitializePlainArrayConstructor(thread));
71         auto objCallInfo = CreateEcmaRuntimeCallInfo(thread, 4);
72         objCallInfo->SetFunction(newTarget.GetTaggedValue());
73         objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
74         objCallInfo->SetThis(JSTaggedValue::Undefined());
75         JSTaggedValue result = ContainersPlainArray::PlainArrayConstructor(objCallInfo);
76         JSHandle<JSAPIPlainArray> array(thread, result);
77         return array;
78     }
79 
ContainersPlainArray_Constructor_FuzzTest(const uint8_t * data,size_t size)80     void ContainersPlainArray_Constructor_FuzzTest(const uint8_t* data, size_t size)
81     {
82         if (data == nullptr || size <= 0) {
83             std::cout << "illegal input!";
84             return;
85         }
86         RuntimeOption option;
87         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
88         EcmaVM *vm = JSNApi::CreateJSVM(option);
89         auto thread = vm->GetAssociatedJSThread();
90         uint32_t input = 0;
91         const uint32_t MAXBYTELEN = 4;
92         if (size > MAXBYTELEN) {
93             size = MAXBYTELEN;
94         }
95         if (memcpy_s(&input, MAXBYTELEN, data, size) != 0) {
96             std::cout << "memcpy_s failed!";
97             UNREACHABLE();
98         }
99         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
100         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 6); // 6 : means the argv length
101         callInfo->SetFunction(JSTaggedValue::Undefined());
102         callInfo->SetThis(plainArray.GetTaggedValue());
103         callInfo->SetCallArg(0, JSTaggedValue(input));
104         ContainersPlainArray::PlainArrayConstructor(callInfo);
105         JSNApi::DestroyJSVM(vm);
106     }
107 
ContainersPlainArray_Add_Has_FuzzTest(const uint8_t * data,size_t size)108     void ContainersPlainArray_Add_Has_FuzzTest(const uint8_t* data, size_t size)
109     {
110         if (data == nullptr || size <= 0) {
111             std::cout << "illegal input!";
112             return;
113         }
114         RuntimeOption option;
115         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
116         EcmaVM *vm = JSNApi::CreateJSVM(option);
117         auto thread = vm->GetAssociatedJSThread();
118         auto factory = vm->GetFactory();
119 
120         uint32_t inputNum = 0;
121         std::string inputStr(data, data + size);
122         const uint32_t MAXBYTELEN = 4;
123         if (size > MAXBYTELEN) {
124             size = MAXBYTELEN;
125         }
126         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
127             std::cout << "memcpy_s failed!";
128             UNREACHABLE();
129         }
130         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
131         const uint32_t addTimes = 3;
132         for (uint32_t i = 0; i < addTimes; i++) {
133             JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
134             EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
135             callInfo->SetFunction(JSTaggedValue::Undefined());
136             callInfo->SetThis(plainArray.GetTaggedValue());
137             callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum + i))); // set key
138             callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue()); // set value
139             ContainersPlainArray::Add(callInfo);
140         }
141 
142         for (uint32_t i = 0; i < addTimes; i++) {
143             EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 6); // 6 : means the argv length
144             callInfo->SetFunction(JSTaggedValue::Undefined());
145             callInfo->SetThis(plainArray.GetTaggedValue());
146             callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum + i)));
147             ContainersPlainArray::Has(callInfo);  // expected to return true
148         }
149         JSNApi::DestroyJSVM(vm);
150     }
151 
ContainersPlainArray_Clone_FuzzTest(const uint8_t * data,size_t size)152     void ContainersPlainArray_Clone_FuzzTest(const uint8_t* data, size_t size)
153     {
154         if (data == nullptr || size <= 0) {
155             std::cout << "illegal input!";
156             return;
157         }
158         RuntimeOption option;
159         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
160         EcmaVM *vm = JSNApi::CreateJSVM(option);
161         auto thread = vm->GetAssociatedJSThread();
162         auto factory = vm->GetFactory();
163 
164         uint32_t inputNum = 0;
165         std::string inputStr(data, data + size);
166         const uint32_t MAXBYTELEN = 4;
167         if (size > MAXBYTELEN) {
168             size = MAXBYTELEN;
169         }
170         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
171             std::cout << "memcpy_s failed!";
172             UNREACHABLE();
173         }
174         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
175         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
176         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
177         callInfo->SetFunction(JSTaggedValue::Undefined());
178         callInfo->SetThis(plainArray.GetTaggedValue());
179         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
180         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
181         ContainersPlainArray::Add(callInfo);
182 
183         EcmaRuntimeCallInfo *cfForClone = CreateEcmaRuntimeCallInfo(thread, 4); // 4 : means the argv length
184         cfForClone->SetFunction(JSTaggedValue::Undefined());
185         cfForClone->SetThis(plainArray.GetTaggedValue());
186         ContainersPlainArray::Clone(cfForClone); // expected to return new plain array
187         JSNApi::DestroyJSVM(vm);
188     }
189 
ContainersPlainArray_Clear_FuzzTest(const uint8_t * data,size_t size)190     void ContainersPlainArray_Clear_FuzzTest(const uint8_t* data, size_t size)
191     {
192         if (data == nullptr || size <= 0) {
193             std::cout << "illegal input!";
194             return;
195         }
196         RuntimeOption option;
197         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
198         EcmaVM *vm = JSNApi::CreateJSVM(option);
199         auto thread = vm->GetAssociatedJSThread();
200         auto factory = vm->GetFactory();
201 
202         uint32_t inputNum = 0;
203         std::string inputStr(data, data + size);
204         const uint32_t MAXBYTELEN = 4;
205         if (size > MAXBYTELEN) {
206             size = MAXBYTELEN;
207         }
208         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
209             std::cout << "memcpy_s failed!";
210             UNREACHABLE();
211         }
212         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
213         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
214         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
215         callInfo->SetFunction(JSTaggedValue::Undefined());
216         callInfo->SetThis(plainArray.GetTaggedValue());
217         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
218         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
219         ContainersPlainArray::Add(callInfo);
220 
221         EcmaRuntimeCallInfo *cfForClear = CreateEcmaRuntimeCallInfo(thread, 4); // 4 : means the argv length
222         cfForClear->SetFunction(JSTaggedValue::Undefined());
223         cfForClear->SetThis(plainArray.GetTaggedValue());
224         ContainersPlainArray::Clear(cfForClear); // expected to return true
225         JSNApi::DestroyJSVM(vm);
226     }
227 
ContainersPlainArray_Get_FuzzTest(const uint8_t * data,size_t size)228     void ContainersPlainArray_Get_FuzzTest(const uint8_t* data, size_t size)
229     {
230         if (data == nullptr || size <= 0) {
231             std::cout << "illegal input!";
232             return;
233         }
234         RuntimeOption option;
235         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
236         EcmaVM *vm = JSNApi::CreateJSVM(option);
237         auto thread = vm->GetAssociatedJSThread();
238         auto factory = vm->GetFactory();
239 
240         uint32_t inputNum = 0;
241         std::string inputStr(data, data + size);
242         const uint32_t MAXBYTELEN = 4;
243         if (size > MAXBYTELEN) {
244             size = MAXBYTELEN;
245         }
246         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
247             std::cout << "memcpy_s failed!";
248             UNREACHABLE();
249         }
250         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
251         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
252         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
253         callInfo->SetFunction(JSTaggedValue::Undefined());
254         callInfo->SetThis(plainArray.GetTaggedValue());
255         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
256         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
257         ContainersPlainArray::Add(callInfo);
258 
259         EcmaRuntimeCallInfo *cfForGet = CreateEcmaRuntimeCallInfo(thread, 6); // 6 : means the argv length
260         cfForGet->SetFunction(JSTaggedValue::Undefined());
261         cfForGet->SetThis(plainArray.GetTaggedValue());
262         cfForGet->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum))); // set key get value
263         ContainersPlainArray::Get(cfForGet); // expected to return value
264         JSNApi::DestroyJSVM(vm);
265     }
266 
ContainersPlainArray_GetIteratorObj_FuzzTest(const uint8_t * data,size_t size)267     void ContainersPlainArray_GetIteratorObj_FuzzTest(const uint8_t* data, size_t size)
268     {
269         if (data == nullptr || size <= 0) {
270             std::cout << "illegal input!";
271             return;
272         }
273         RuntimeOption option;
274         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
275         EcmaVM *vm = JSNApi::CreateJSVM(option);
276         auto thread = vm->GetAssociatedJSThread();
277         auto factory = vm->GetFactory();
278 
279         uint32_t inputNum = 0;
280         std::string inputStr(data, data + size);
281         const uint32_t MAXBYTELEN = 4;
282         if (size > MAXBYTELEN) {
283             size = MAXBYTELEN;
284         }
285         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
286             std::cout << "memcpy_s failed!";
287             UNREACHABLE();
288         }
289         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
290         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
291         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
292         callInfo->SetFunction(JSTaggedValue::Undefined());
293         callInfo->SetThis(plainArray.GetTaggedValue());
294         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
295         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
296         ContainersPlainArray::Add(callInfo);
297 
298         EcmaRuntimeCallInfo *cfForGetIteratorObj = CreateEcmaRuntimeCallInfo(thread, 4); // 4 : means the argv length
299         cfForGetIteratorObj->SetFunction(JSTaggedValue::Undefined());
300         cfForGetIteratorObj->SetThis(plainArray.GetTaggedValue());
301         ContainersPlainArray::GetIteratorObj(cfForGetIteratorObj); // expected to return iterator
302         JSNApi::DestroyJSVM(vm);
303     }
304 
TestForEachFunc(EcmaRuntimeCallInfo * argv)305     static JSTaggedValue TestForEachFunc(EcmaRuntimeCallInfo *argv)
306     {
307         JSThread *thread = argv->GetThread();
308         JSHandle<JSTaggedValue> key = BuiltinsBase::GetCallArg(argv, 0);  // 0 means the value
309         JSHandle<JSTaggedValue> value = BuiltinsBase::GetCallArg(argv, 1); // 1 means the value
310         JSHandle<JSAPIPlainArray> plainArray(BuiltinsBase::GetCallArg(argv, 2)); // 2 means the value
311         JSHandle<JSTaggedValue> newValue(thread, value.GetTaggedValue());
312         JSAPIPlainArray::Add(thread, plainArray, key, newValue);
313         return JSTaggedValue::True();
314     }
315 
ContainersPlainArray_ForEach_FuzzTest(const uint8_t * data,size_t size)316     void ContainersPlainArray_ForEach_FuzzTest(const uint8_t* data, size_t size)
317     {
318         if (data == nullptr || size <= 0) {
319             std::cout << "illegal input!";
320             return;
321         }
322         RuntimeOption option;
323         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
324         EcmaVM *vm = JSNApi::CreateJSVM(option);
325         auto thread = vm->GetAssociatedJSThread();
326         auto factory = vm->GetFactory();
327         JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
328 
329         uint32_t inputNum = 0;
330         std::string inputStr(data, data + size);
331         const uint32_t MAXBYTELEN = 4;
332         if (size > MAXBYTELEN) {
333             size = MAXBYTELEN;
334         }
335         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
336             std::cout << "memcpy_s failed!";
337             UNREACHABLE();
338         }
339         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
340         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
341         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
342         callInfo->SetFunction(JSTaggedValue::Undefined());
343         callInfo->SetThis(plainArray.GetTaggedValue());
344         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
345         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
346         ContainersPlainArray::Add(callInfo);
347 
348         JSHandle<JSAPIPlainArray> thisArg = CreateJSAPIPlainArray(thread);
349         JSHandle<JSFunction> cbFunc = factory->NewJSFunction(env, reinterpret_cast<void *>(TestForEachFunc));
350         EcmaRuntimeCallInfo *cfForForEach = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
351         cfForForEach->SetFunction(JSTaggedValue::Undefined());
352         cfForForEach->SetThis(plainArray.GetTaggedValue());
353         cfForForEach->SetCallArg(0, cbFunc.GetTaggedValue());
354         cfForForEach->SetCallArg(1, thisArg.GetTaggedValue());
355         ContainersPlainArray::ForEach(cfForForEach); // expected to return undefined
356         JSNApi::DestroyJSVM(vm);
357     }
358 
ContainersPlainArray_ToString_FuzzTest(const uint8_t * data,size_t size)359     void ContainersPlainArray_ToString_FuzzTest(const uint8_t* data, size_t size)
360     {
361         if (data == nullptr || size <= 0) {
362             std::cout << "illegal input!";
363             return;
364         }
365         RuntimeOption option;
366         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
367         EcmaVM *vm = JSNApi::CreateJSVM(option);
368         auto thread = vm->GetAssociatedJSThread();
369         auto factory = vm->GetFactory();
370 
371         uint32_t inputNum = 0;
372         std::string inputStr(data, data + size);
373         const uint32_t MAXBYTELEN = 4;
374         if (size > MAXBYTELEN) {
375             size = MAXBYTELEN;
376         }
377         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
378             std::cout << "memcpy_s failed!";
379             UNREACHABLE();
380         }
381         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
382         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
383         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
384         callInfo->SetFunction(JSTaggedValue::Undefined());
385         callInfo->SetThis(plainArray.GetTaggedValue());
386         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
387         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
388         ContainersPlainArray::Add(callInfo);
389 
390         EcmaRuntimeCallInfo *cfForToString = CreateEcmaRuntimeCallInfo(thread, 4); // 4 : means the argv length
391         cfForToString->SetFunction(JSTaggedValue::Undefined());
392         cfForToString->SetThis(plainArray.GetTaggedValue());
393         ContainersPlainArray::ToString(cfForToString); // expected to return string object
394         JSNApi::DestroyJSVM(vm);
395     }
396 
ContainersPlainArray_GetIndexOfKey_FuzzTest(const uint8_t * data,size_t size)397     void ContainersPlainArray_GetIndexOfKey_FuzzTest(const uint8_t* data, size_t size)
398     {
399         if (data == nullptr || size <= 0) {
400             std::cout << "illegal input!";
401             return;
402         }
403         RuntimeOption option;
404         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
405         EcmaVM *vm = JSNApi::CreateJSVM(option);
406         auto thread = vm->GetAssociatedJSThread();
407         auto factory = vm->GetFactory();
408 
409         uint32_t inputNum = 0;
410         std::string inputStr(data, data + size);
411         const uint32_t MAXBYTELEN = 4;
412         if (size > MAXBYTELEN) {
413             size = MAXBYTELEN;
414         }
415         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
416             std::cout << "memcpy_s failed!";
417             UNREACHABLE();
418         }
419         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
420         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
421         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
422         callInfo->SetFunction(JSTaggedValue::Undefined());
423         callInfo->SetThis(plainArray.GetTaggedValue());
424         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
425         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
426         ContainersPlainArray::Add(callInfo);
427 
428         EcmaRuntimeCallInfo *cfForGetIndexOfKey = CreateEcmaRuntimeCallInfo(thread, 6); // 6 : means the argv length
429         cfForGetIndexOfKey->SetFunction(JSTaggedValue::Undefined());
430         cfForGetIndexOfKey->SetThis(plainArray.GetTaggedValue());
431         cfForGetIndexOfKey->SetCallArg(0, inputEcmaStr.GetTaggedValue()); // value
432         ContainersPlainArray::GetIndexOfKey(cfForGetIndexOfKey); // expected to return the index of key
433         JSNApi::DestroyJSVM(vm);
434     }
435 
ContainersPlainArray_GetIndexOfValue_FuzzTest(const uint8_t * data,size_t size)436     void ContainersPlainArray_GetIndexOfValue_FuzzTest(const uint8_t* data, size_t size)
437     {
438         if (data == nullptr || size <= 0) {
439             std::cout << "illegal input!";
440             return;
441         }
442         RuntimeOption option;
443         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
444         EcmaVM *vm = JSNApi::CreateJSVM(option);
445         auto thread = vm->GetAssociatedJSThread();
446         auto factory = vm->GetFactory();
447 
448         uint32_t inputNum = 0;
449         std::string inputStr(data, data + size);
450         const uint32_t MAXBYTELEN = 4;
451         if (size > MAXBYTELEN) {
452             size = MAXBYTELEN;
453         }
454         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
455             std::cout << "memcpy_s failed!";
456             UNREACHABLE();
457         }
458         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
459         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
460         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
461         callInfo->SetFunction(JSTaggedValue::Undefined());
462         callInfo->SetThis(plainArray.GetTaggedValue());
463         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
464         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
465         ContainersPlainArray::Add(callInfo);
466 
467         EcmaRuntimeCallInfo *cfForGetIndexOfValue = CreateEcmaRuntimeCallInfo(thread, 6); // 6 : means the argv length
468         cfForGetIndexOfValue->SetFunction(JSTaggedValue::Undefined());
469         cfForGetIndexOfValue->SetThis(plainArray.GetTaggedValue());
470         cfForGetIndexOfValue->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum))); // key
471         ContainersPlainArray::GetIndexOfValue(cfForGetIndexOfValue); // expected to return the index of value
472         JSNApi::DestroyJSVM(vm);
473     }
474 
ContainersPlainArray_IsEmpty_FuzzTest(const uint8_t * data,size_t size)475     void ContainersPlainArray_IsEmpty_FuzzTest(const uint8_t* data, size_t size)
476     {
477         if (data == nullptr || size <= 0) {
478             std::cout << "illegal input!";
479             return;
480         }
481         RuntimeOption option;
482         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
483         EcmaVM *vm = JSNApi::CreateJSVM(option);
484         auto thread = vm->GetAssociatedJSThread();
485         auto factory = vm->GetFactory();
486 
487         uint32_t inputNum = 0;
488         std::string inputStr(data, data + size);
489         const uint32_t MAXBYTELEN = 4;
490         if (size > MAXBYTELEN) {
491             size = MAXBYTELEN;
492         }
493         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
494             std::cout << "memcpy_s failed!";
495             UNREACHABLE();
496         }
497         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
498         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
499         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
500         callInfo->SetFunction(JSTaggedValue::Undefined());
501         callInfo->SetThis(plainArray.GetTaggedValue());
502         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
503         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
504         ContainersPlainArray::Add(callInfo);
505 
506         EcmaRuntimeCallInfo *cfForIsEmpty = CreateEcmaRuntimeCallInfo(thread, 4); // 4 : means the argv length
507         cfForIsEmpty->SetFunction(JSTaggedValue::Undefined());
508         cfForIsEmpty->SetThis(plainArray.GetTaggedValue());
509         ContainersPlainArray::IsEmpty(cfForIsEmpty); // expected to return true or false
510         JSNApi::DestroyJSVM(vm);
511     }
512 
ContainersPlainArray_GetKeyAt_FuzzTest(const uint8_t * data,size_t size)513     void ContainersPlainArray_GetKeyAt_FuzzTest(const uint8_t* data, size_t size)
514     {
515         if (data == nullptr || size <= 0) {
516             std::cout << "illegal input!";
517             return;
518         }
519         RuntimeOption option;
520         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
521         EcmaVM *vm = JSNApi::CreateJSVM(option);
522         auto thread = vm->GetAssociatedJSThread();
523         auto factory = vm->GetFactory();
524 
525         uint32_t inputNum = 0;
526         std::string inputStr(data, data + size);
527         const uint32_t MAXBYTELEN = 4;
528         if (size > MAXBYTELEN) {
529             size = MAXBYTELEN;
530         }
531         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
532             std::cout << "memcpy_s failed!";
533             UNREACHABLE();
534         }
535         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
536         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
537         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
538         callInfo->SetFunction(JSTaggedValue::Undefined());
539         callInfo->SetThis(plainArray.GetTaggedValue());
540         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
541         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
542         ContainersPlainArray::Add(callInfo);
543 
544         EcmaRuntimeCallInfo *cfForGetKeyAt = CreateEcmaRuntimeCallInfo(thread, 6); // 6 : means the argv length
545         cfForGetKeyAt->SetFunction(JSTaggedValue::Undefined());
546         cfForGetKeyAt->SetThis(plainArray.GetTaggedValue());
547         cfForGetKeyAt->SetCallArg(0, inputEcmaStr.GetTaggedValue()); // value
548         ContainersPlainArray::GetKeyAt(cfForGetKeyAt); // expected to return the key
549         JSNApi::DestroyJSVM(vm);
550     }
551 
ContainersPlainArray_Remove_FuzzTest(const uint8_t * data,size_t size)552     void ContainersPlainArray_Remove_FuzzTest(const uint8_t* data, size_t size)
553     {
554         if (data == nullptr || size <= 0) {
555             std::cout << "illegal input!";
556             return;
557         }
558         RuntimeOption option;
559         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
560         EcmaVM *vm = JSNApi::CreateJSVM(option);
561         auto thread = vm->GetAssociatedJSThread();
562         auto factory = vm->GetFactory();
563 
564         uint32_t inputNum = 0;
565         std::string inputStr(data, data + size);
566         const uint32_t MAXBYTELEN = 4;
567         if (size > MAXBYTELEN) {
568             size = MAXBYTELEN;
569         }
570         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
571             std::cout << "memcpy_s failed!";
572             UNREACHABLE();
573         }
574         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
575         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
576         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
577         callInfo->SetFunction(JSTaggedValue::Undefined());
578         callInfo->SetThis(plainArray.GetTaggedValue());
579         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
580         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
581         ContainersPlainArray::Add(callInfo);
582 
583         EcmaRuntimeCallInfo *cfForRemove = CreateEcmaRuntimeCallInfo(thread, 6); // 6 : means the argv length
584         cfForRemove->SetFunction(JSTaggedValue::Undefined());
585         cfForRemove->SetThis(plainArray.GetTaggedValue());
586         cfForRemove->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
587         ContainersPlainArray::Remove(cfForRemove); // expected to return the value
588         JSNApi::DestroyJSVM(vm);
589     }
590 
ContainersPlainArray_RemoveAt_FuzzTest(const uint8_t * data,size_t size)591     void ContainersPlainArray_RemoveAt_FuzzTest(const uint8_t* data, size_t size)
592     {
593         if (data == nullptr || size <= 0) {
594             std::cout << "illegal input!";
595             return;
596         }
597         RuntimeOption option;
598         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
599         EcmaVM *vm = JSNApi::CreateJSVM(option);
600         auto thread = vm->GetAssociatedJSThread();
601         auto factory = vm->GetFactory();
602 
603         uint32_t inputNum = 0;
604         std::string inputStr(data, data + size);
605         const uint32_t MAXBYTELEN = 4;
606         if (size > MAXBYTELEN) {
607             size = MAXBYTELEN;
608         }
609         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
610             std::cout << "memcpy_s failed!";
611             UNREACHABLE();
612         }
613         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
614         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
615         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
616         callInfo->SetFunction(JSTaggedValue::Undefined());
617         callInfo->SetThis(plainArray.GetTaggedValue());
618         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
619         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
620         ContainersPlainArray::Add(callInfo);
621 
622         EcmaRuntimeCallInfo *cfForRemoveAt = CreateEcmaRuntimeCallInfo(thread, 6); // 6 : means the argv length
623         cfForRemoveAt->SetFunction(JSTaggedValue::Undefined());
624         cfForRemoveAt->SetThis(plainArray.GetTaggedValue());
625         cfForRemoveAt->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
626         ContainersPlainArray::RemoveAt(cfForRemoveAt); // expected to return the value
627         JSNApi::DestroyJSVM(vm);
628     }
629 
ContainersPlainArray_RemoveRangeFrom_FuzzTest(const uint8_t * data,size_t size)630     void ContainersPlainArray_RemoveRangeFrom_FuzzTest(const uint8_t* data, size_t size)
631     {
632         if (data == nullptr || size <= 0) {
633             std::cout << "illegal input!";
634             return;
635         }
636         RuntimeOption option;
637         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
638         EcmaVM *vm = JSNApi::CreateJSVM(option);
639         auto thread = vm->GetAssociatedJSThread();
640         auto factory = vm->GetFactory();
641 
642         uint32_t inputNum = 0;
643         std::string inputStr(data, data + size);
644         const uint32_t MAXBYTELEN = 4;
645         if (size > MAXBYTELEN) {
646             size = MAXBYTELEN;
647         }
648         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
649             std::cout << "memcpy_s failed!";
650             UNREACHABLE();
651         }
652         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
653         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
654         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
655         callInfo->SetFunction(JSTaggedValue::Undefined());
656         callInfo->SetThis(plainArray.GetTaggedValue());
657         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
658         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
659         ContainersPlainArray::Add(callInfo);
660 
661         EcmaRuntimeCallInfo *cfForRemoveRangeFrom = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
662         cfForRemoveRangeFrom->SetFunction(JSTaggedValue::Undefined());
663         cfForRemoveRangeFrom->SetThis(plainArray.GetTaggedValue());
664         cfForRemoveRangeFrom->SetCallArg(0, JSTaggedValue(0)); // set index as the head of array
665         cfForRemoveRangeFrom->SetCallArg(1, JSTaggedValue(static_cast<uint32_t>(inputNum))); // number to delete
666         ContainersPlainArray::RemoveRangeFrom(cfForRemoveRangeFrom); // expected to return the safe size
667         JSNApi::DestroyJSVM(vm);
668     }
669 
ContainersPlainArray_SetValueAt_FuzzTest(const uint8_t * data,size_t size)670     void ContainersPlainArray_SetValueAt_FuzzTest(const uint8_t* data, size_t size)
671     {
672         if (data == nullptr || size <= 0) {
673             std::cout << "illegal input!";
674             return;
675         }
676         RuntimeOption option;
677         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
678         EcmaVM *vm = JSNApi::CreateJSVM(option);
679         auto thread = vm->GetAssociatedJSThread();
680         auto factory = vm->GetFactory();
681 
682         uint32_t inputNum = 0;
683         std::string inputStr(data, data + size);
684         const uint32_t MAXBYTELEN = 4;
685         if (size > MAXBYTELEN) {
686             size = MAXBYTELEN;
687         }
688         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
689             std::cout << "memcpy_s failed!";
690             UNREACHABLE();
691         }
692         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
693         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
694         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
695         callInfo->SetFunction(JSTaggedValue::Undefined());
696         callInfo->SetThis(plainArray.GetTaggedValue());
697         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
698         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
699         ContainersPlainArray::Add(callInfo);
700 
701         EcmaRuntimeCallInfo *cfForSetValueAt = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
702         cfForSetValueAt->SetFunction(JSTaggedValue::Undefined());
703         cfForSetValueAt->SetThis(plainArray.GetTaggedValue());
704         cfForSetValueAt->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum))); // set index to set
705         cfForSetValueAt->SetCallArg(1, JSTaggedValue(static_cast<uint32_t>(inputNum))); // set new value
706         ContainersPlainArray::SetValueAt(cfForSetValueAt); // expected to return undefined
707         JSNApi::DestroyJSVM(vm);
708     }
709 
ContainersPlainArray_GetValueAt_FuzzTest(const uint8_t * data,size_t size)710     void ContainersPlainArray_GetValueAt_FuzzTest(const uint8_t* data, size_t size)
711     {
712         if (data == nullptr || size <= 0) {
713             std::cout << "illegal input!";
714             return;
715         }
716         RuntimeOption option;
717         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
718         EcmaVM *vm = JSNApi::CreateJSVM(option);
719         auto thread = vm->GetAssociatedJSThread();
720         auto factory = vm->GetFactory();
721 
722         uint32_t inputNum = 0;
723         std::string inputStr(data, data + size);
724         const uint32_t MAXBYTELEN = 4;
725         if (size > MAXBYTELEN) {
726             size = MAXBYTELEN;
727         }
728         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
729             std::cout << "memcpy_s failed!";
730             UNREACHABLE();
731         }
732         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
733         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
734         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
735         callInfo->SetFunction(JSTaggedValue::Undefined());
736         callInfo->SetThis(plainArray.GetTaggedValue());
737         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
738         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
739         ContainersPlainArray::Add(callInfo);
740 
741         EcmaRuntimeCallInfo *cfForGetValueAt = CreateEcmaRuntimeCallInfo(thread, 6); // 6 : means the argv length
742         cfForGetValueAt->SetFunction(JSTaggedValue::Undefined());
743         cfForGetValueAt->SetThis(plainArray.GetTaggedValue());
744         cfForGetValueAt->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum))); // set index to get
745         ContainersPlainArray::GetValueAt(cfForGetValueAt); // expected to return value
746         JSNApi::DestroyJSVM(vm);
747     }
748 
ContainersPlainArray_GetSize_FuzzTest(const uint8_t * data,size_t size)749     void ContainersPlainArray_GetSize_FuzzTest(const uint8_t* data, size_t size)
750     {
751         if (data == nullptr || size <= 0) {
752             std::cout << "illegal input!";
753             return;
754         }
755         RuntimeOption option;
756         option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
757         EcmaVM *vm = JSNApi::CreateJSVM(option);
758         auto thread = vm->GetAssociatedJSThread();
759         auto factory = vm->GetFactory();
760 
761         uint32_t inputNum = 0;
762         std::string inputStr(data, data + size);
763         const uint32_t MAXBYTELEN = 4;
764         if (size > MAXBYTELEN) {
765             size = MAXBYTELEN;
766         }
767         if (memcpy_s(&inputNum, MAXBYTELEN, data, size) != 0) {
768             std::cout << "memcpy_s failed!";
769             UNREACHABLE();
770         }
771         JSHandle<JSAPIPlainArray> plainArray = CreateJSAPIPlainArray(thread);
772         JSHandle<EcmaString> inputEcmaStr = factory->NewFromStdString(inputStr);
773         EcmaRuntimeCallInfo *callInfo = CreateEcmaRuntimeCallInfo(thread, 8); // 8 : means the argv length
774         callInfo->SetFunction(JSTaggedValue::Undefined());
775         callInfo->SetThis(plainArray.GetTaggedValue());
776         callInfo->SetCallArg(0, JSTaggedValue(static_cast<uint32_t>(inputNum)));
777         callInfo->SetCallArg(1, inputEcmaStr.GetTaggedValue());
778         ContainersPlainArray::Add(callInfo);
779 
780         EcmaRuntimeCallInfo *cfForGetSize = CreateEcmaRuntimeCallInfo(thread, 4); // 4 : means the argv length
781         cfForGetSize->SetFunction(JSTaggedValue::Undefined());
782         cfForGetSize->SetThis(plainArray.GetTaggedValue());
783         ContainersPlainArray::GetSize(cfForGetSize); // expected to return the size
784         JSNApi::DestroyJSVM(vm);
785     }
786 }
787 
788 // Fuzzer entry point.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)789 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
790 {
791     // Run your code on data.
792     OHOS::ContainersPlainArray_Constructor_FuzzTest(data, size);
793     OHOS::ContainersPlainArray_Add_Has_FuzzTest(data, size);
794     OHOS::ContainersPlainArray_Clone_FuzzTest(data, size);
795     OHOS::ContainersPlainArray_Clear_FuzzTest(data, size);
796     OHOS::ContainersPlainArray_Get_FuzzTest(data, size);
797     OHOS::ContainersPlainArray_GetIteratorObj_FuzzTest(data, size);
798     OHOS::ContainersPlainArray_ForEach_FuzzTest(data, size);
799     OHOS::ContainersPlainArray_ToString_FuzzTest(data, size);
800     OHOS::ContainersPlainArray_GetIndexOfKey_FuzzTest(data, size);
801     OHOS::ContainersPlainArray_GetIndexOfValue_FuzzTest(data, size);
802     OHOS::ContainersPlainArray_IsEmpty_FuzzTest(data, size);
803     OHOS::ContainersPlainArray_GetKeyAt_FuzzTest(data, size);
804     OHOS::ContainersPlainArray_Remove_FuzzTest(data, size);
805     OHOS::ContainersPlainArray_RemoveAt_FuzzTest(data, size);
806     OHOS::ContainersPlainArray_RemoveRangeFrom_FuzzTest(data, size);
807     OHOS::ContainersPlainArray_SetValueAt_FuzzTest(data, size);
808     OHOS::ContainersPlainArray_GetValueAt_FuzzTest(data, size);
809     OHOS::ContainersPlainArray_GetSize_FuzzTest(data, size);
810     return 0;
811 }