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