1 /*
2  * Copyright (c) 2023 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 "jsvaluerefismodulenamespace_fuzzer.h"
17 #include "ecmascript/containers/containers_private.h"
18 #include "ecmascript/ecma_string-inl.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_api/js_api_list.h"
21 #include "ecmascript/js_api/js_api_queue.h"
22 #include "ecmascript/js_collator.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/js_plural_rules.h"
25 #include "ecmascript/module/js_module_manager.h"
26 #include "ecmascript/module/js_module_source_text.h"
27 #include "ecmascript/napi/include/jsnapi.h"
28 #include "ecmascript/tagged_list.h"
29 
30 using namespace panda;
31 using namespace panda::ecmascript;
32 
33 namespace OHOS {
34 constexpr uint32_t ERROR_TYPE_LEN = 2;
35 
IsModuleNamespaceObjectFuzztest([[maybe_unused]]const uint8_t *data, size_t size)36 void IsModuleNamespaceObjectFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
37 {
38     RuntimeOption option;
39     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
40     EcmaVM *vm = JSNApi::CreateJSVM(option);
41     {
42         JsiFastNativeScope scope(vm);
43         if (size <= 0) {
44             LOG_ECMA(ERROR) << "illegal input!";
45             return;
46         }
47         ObjectFactory *objectFactory = vm->GetFactory();
48         JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
49         JSHandle<LocalExportEntry> localExportEntry1 = objectFactory->NewLocalExportEntry();
50         SourceTextModule::AddLocalExportEntry(vm->GetJSThread(), module, localExportEntry1, 0, ERROR_TYPE_LEN);
51         JSHandle<LocalExportEntry> localExportEntry2 = objectFactory->NewLocalExportEntry();
52         SourceTextModule::AddLocalExportEntry(vm->GetJSThread(), module, localExportEntry2, 1, ERROR_TYPE_LEN);
53         JSHandle<TaggedArray> localExportEntries(vm->GetJSThread(), module->GetLocalExportEntries());
54         CString baseFileName = "a.abc";
55         module->SetEcmaModuleFilenameString(baseFileName);
56         ModuleManager *moduleManager = vm->GetJSThread()->GetCurrentEcmaContext()->GetModuleManager();
57         moduleManager->AddResolveImportedModule(baseFileName, module.GetTaggedValue());
58         JSHandle<ModuleNamespace> np = ModuleNamespace::ModuleNamespaceCreate(vm->GetJSThread(),
59             JSHandle<JSTaggedValue>::Cast(module), localExportEntries);
60         ModuleNamespace::PreventExtensions();
61         JSHandle<JSTaggedValue> moduleNamespaceTag = JSHandle<JSTaggedValue>::Cast(np);
62         Local<JSValueRef> moduleNamespace = JSNApiHelper::ToLocal<ModuleNamespace>(moduleNamespaceTag);
63         moduleNamespace->IsModuleNamespaceObject(vm);
64     }
65     JSNApi::DestroyJSVM(vm);
66 }
67 
IsProxyFuzztest([[maybe_unused]]const uint8_t *data, size_t size)68 void IsProxyFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
69 {
70     RuntimeOption option;
71     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
72     EcmaVM *vm = JSNApi::CreateJSVM(option);
73     {
74         JsiFastNativeScope scope(vm);
75         if (size <= 0) {
76             LOG_ECMA(ERROR) << "illegal input!";
77             return;
78         }
79         auto thread = vm->GetJSThread();
80         JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
81         JSHandle<JSTaggedValue> hclass(thread, globalEnv->GetObjectFunction().GetObject<JSFunction>());
82         JSHandle<JSTaggedValue> targetHandle(
83             thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
84         JSHandle<JSTaggedValue> handlerHandle(
85             thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(hclass), hclass));
86         JSHandle<JSProxy> proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle);
87         Local<JSValueRef> proxy = JSNApiHelper::ToLocal<JSProxy>(JSHandle<JSTaggedValue>(proxyHandle));
88         proxy->IsProxy(vm);
89     }
90     JSNApi::DestroyJSVM(vm);
91 }
92 
IsJSCollatorFuzztest([[maybe_unused]]const uint8_t *data, size_t size)93 void IsJSCollatorFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
94 {
95     RuntimeOption option;
96     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
97     EcmaVM *vm = JSNApi::CreateJSVM(option);
98     {
99         JsiFastNativeScope scope(vm);
100         if (size <= 0) {
101             LOG_ECMA(ERROR) << "illegal input!";
102             return;
103         }
104         auto thread = vm->GetJSThread();
105         ObjectFactory *factory = vm->GetFactory();
106         JSHandle<JSTaggedValue> ctor = vm->GetGlobalEnv()->GetCollatorFunction();
107         JSHandle<JSCollator> collator =
108             JSHandle<JSCollator>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
109         JSHandle<JSTaggedValue> localeStr = thread->GlobalConstants()->GetHandledEnUsString();
110         JSHandle<JSTaggedValue> undefinedHandle(thread, JSTaggedValue::Undefined());
111         JSHandle<JSCollator> initCollator =
112             JSCollator::InitializeCollator(thread, collator, localeStr, undefinedHandle);
113         JSHandle<JSTaggedValue> collatorTagHandleVal = JSHandle<JSTaggedValue>::Cast(initCollator);
114         Local<JSValueRef> object = JSNApiHelper::ToLocal<JSValueRef>(collatorTagHandleVal);
115         object->IsJSCollator(vm);
116     }
117     JSNApi::DestroyJSVM(vm);
118 }
119 
IsJSPluralRulesFuzztest([[maybe_unused]]const uint8_t *data, size_t size)120 void IsJSPluralRulesFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
121 {
122     RuntimeOption option;
123     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
124     EcmaVM *vm = JSNApi::CreateJSVM(option);
125     {
126         JsiFastNativeScope scope(vm);
127         if (size <= 0) {
128             LOG_ECMA(ERROR) << "illegal input!";
129             return;
130         }
131         auto thread = vm->GetJSThread();
132         ObjectFactory *factory = vm->GetFactory();
133         JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
134         JSHandle<JSTaggedValue> optionHandle(thread, JSTaggedValue::Undefined());
135         JSHandle<JSTaggedValue> ctor = env->GetPluralRulesFunction();
136         JSHandle<JSPluralRules> pluralRules =
137             JSHandle<JSPluralRules>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
138         JSHandle<JSTaggedValue> localeStr(factory->NewFromASCII("en-GB"));
139         JSHandle<JSPluralRules> initPluralRules =
140             JSPluralRules::InitializePluralRules(thread, pluralRules, localeStr, optionHandle);
141         JSHandle<JSTaggedValue> tagPlureRules = JSHandle<JSTaggedValue>::Cast(initPluralRules);
142         Local<JSValueRef> object = JSNApiHelper::ToLocal<JSValueRef>(tagPlureRules);
143         object->IsJSPluralRules(vm);
144     }
145     JSNApi::DestroyJSVM(vm);
146 }
147 
IsStrictEqualsFuzztest([[maybe_unused]]const uint8_t *data, size_t size)148 void IsStrictEqualsFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
149 {
150     RuntimeOption option;
151     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
152     EcmaVM *vm = JSNApi::CreateJSVM(option);
153     if (size <= 0) {
154         LOG_ECMA(ERROR) << "illegal input!";
155         return;
156     }
157     Local<ObjectRef> object = ObjectRef::New(vm);
158     Local<ObjectRef> object1 = ObjectRef::New(vm);
159     object->IsStrictEquals(vm, object1);
160     JSNApi::DestroyJSVM(vm);
161 }
162 
IsJSListFormatFuzztest([[maybe_unused]]const uint8_t *data, size_t size)163 void IsJSListFormatFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
164 {
165     RuntimeOption option;
166     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
167     EcmaVM *vm = JSNApi::CreateJSVM(option);
168     if (size <= 0) {
169         LOG_ECMA(ERROR) << "illegal input!";
170         return;
171     }
172     Local<JSValueRef> object = ObjectRef::New(vm);
173     object->IsJSListFormat(vm);
174     JSNApi::DestroyJSVM(vm);
175 }
176 
IsJSPrimitiveRefFuzztest([[maybe_unused]]const uint8_t *data, size_t size)177 void IsJSPrimitiveRefFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
178 {
179     RuntimeOption option;
180     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
181     EcmaVM *vm = JSNApi::CreateJSVM(option);
182     {
183         JsiFastNativeScope scope(vm);
184         if (size <= 0) {
185             LOG_ECMA(ERROR) << "illegal input!";
186             return;
187         }
188         auto thread = vm->GetJSThread();
189         auto factory = vm->GetFactory();
190         JSHandle<JSTaggedValue> nullHandle(thread, JSTaggedValue::Null());
191         JSHandle<JSHClass> jsClassHandle = factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_PRIMITIVE_REF, nullHandle);
192         TaggedObject *taggedObject = factory->NewObject(jsClassHandle);
193         JSHandle<JSTaggedValue> jsTaggedValue(thread, JSTaggedValue(taggedObject));
194         Local<JSValueRef> jsValueRef = JSNApiHelper::ToLocal<JSPrimitiveRef>(jsTaggedValue);
195         jsValueRef->IsJSPrimitiveRef(vm);
196     }
197     JSNApi::DestroyJSVM(vm);
198 }
199 
IsDequeFuzztest([[maybe_unused]]const uint8_t *data, size_t size)200 void IsDequeFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
201 {
202     RuntimeOption option;
203     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
204     EcmaVM *vm = JSNApi::CreateJSVM(option);
205     {
206         JsiFastNativeScope scope(vm);
207         if (size <= 0) {
208             LOG_ECMA(ERROR) << "illegal input!";
209             return;
210         }
211         auto thread = vm->GetJSThread();
212         auto factory = vm->GetFactory();
213         JSHandle<JSTaggedValue> proto = thread->GetEcmaVM()->GetGlobalEnv()->GetFunctionPrototype();
214         JSHandle<JSHClass> queueClass = factory->NewEcmaHClass(JSAPIQueue::SIZE, JSType::JS_API_QUEUE, proto);
215         JSHandle<JSAPIQueue> jsQueue = JSHandle<JSAPIQueue>::Cast(factory->NewJSObjectWithInit(queueClass));
216         JSHandle<TaggedArray> newElements = factory->NewTaggedArray(JSAPIQueue::DEFAULT_CAPACITY_LENGTH);
217         jsQueue->SetLength(thread, JSTaggedValue(0));
218         jsQueue->SetFront(0);
219         jsQueue->SetTail(0);
220         jsQueue->SetElements(thread, newElements);
221         JSHandle<JSTaggedValue> Que = JSHandle<JSTaggedValue>::Cast(jsQueue);
222         Local<JSValueRef> jsValueRef = JSNApiHelper::ToLocal<ArrayRef>(Que);
223         jsValueRef->IsDeque(vm);
224     }
225     JSNApi::DestroyJSVM(vm);
226 }
227 
CreateJSValueRef(EcmaVM *vm, panda::ecmascript::JSType type)228 Local<JSValueRef> CreateJSValueRef(EcmaVM *vm, panda::ecmascript::JSType type)
229 {
230     auto thread = vm->GetJSThread();
231     auto factory = vm->GetFactory();
232     JSHandle<JSTaggedValue> nullHandle(thread, JSTaggedValue::Null());
233     JSHandle<JSHClass> jsClassHandle = factory->NewEcmaHClass(JSObject::SIZE, type, nullHandle);
234     TaggedObject *taggedObject = factory->NewObject(jsClassHandle);
235     JSHandle<JSTaggedValue> jsTaggedValue(thread, JSTaggedValue(taggedObject));
236     return JSNApiHelper::ToLocal<JSValueRef>(jsTaggedValue);
237 }
238 
IsJSIntlFuzztest([[maybe_unused]]const uint8_t *data, size_t size)239 void IsJSIntlFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
240 {
241     RuntimeOption option;
242     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
243     EcmaVM *vm = JSNApi::CreateJSVM(option);
244     {
245         JsiFastNativeScope scope(vm);
246         if (size <= 0) {
247             LOG_ECMA(ERROR) << "illegal input!";
248             return;
249         }
250         Local<JSValueRef> jsInt1 = CreateJSValueRef(vm, JSType::JS_INTL);
251         jsInt1->IsJSIntl(vm);
252     }
253     JSNApi::DestroyJSVM(vm);
254 }
255 
IsJSDateTimeFormatFuzztest([[maybe_unused]]const uint8_t *data, size_t size)256 void IsJSDateTimeFormatFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
257 {
258     RuntimeOption option;
259     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
260     EcmaVM *vm = JSNApi::CreateJSVM(option);
261     {
262         JsiFastNativeScope scope(vm);
263         if (size <= 0) {
264             LOG_ECMA(ERROR) << "illegal input!";
265             return;
266         }
267         Local<JSValueRef> dateTime = CreateJSValueRef(vm, JSType::JS_DATE_TIME_FORMAT);
268         dateTime->IsJSDateTimeFormat(vm);
269     }
270     JSNApi::DestroyJSVM(vm);
271 }
272 
IsJSNumberFormatFuzztest([[maybe_unused]]const uint8_t *data, size_t size)273 void IsJSNumberFormatFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
274 {
275     RuntimeOption option;
276     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
277     EcmaVM *vm = JSNApi::CreateJSVM(option);
278     {
279         JsiFastNativeScope scope(vm);
280         if (size <= 0) {
281             LOG_ECMA(ERROR) << "illegal input!";
282             return;
283         }
284         Local<JSValueRef> number = CreateJSValueRef(vm, JSType::JS_NUMBER_FORMAT);
285         number->IsJSNumberFormat(vm);
286     }
287     JSNApi::DestroyJSVM(vm);
288 }
289 
IsJSRelativeTimeFormatFuzztest([[maybe_unused]]const uint8_t *data, size_t size)290 void IsJSRelativeTimeFormatFuzztest([[maybe_unused]]const uint8_t *data, size_t size)
291 {
292     RuntimeOption option;
293     option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
294     EcmaVM *vm = JSNApi::CreateJSVM(option);
295     {
296         JsiFastNativeScope scope(vm);
297         if (size <= 0) {
298             LOG_ECMA(ERROR) << "illegal input!";
299             return;
300         }
301         Local<JSValueRef> relative = CreateJSValueRef(vm, JSType::JS_RELATIVE_TIME_FORMAT);
302         relative->IsJSRelativeTimeFormat(vm);
303     }
304     JSNApi::DestroyJSVM(vm);
305 }
306 }
307 
308 // Fuzzer entry point.
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)309 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
310 {
311     // Run your code on data.
312     OHOS::IsModuleNamespaceObjectFuzztest(data, size);
313     OHOS::IsProxyFuzztest(data, size);
314     OHOS::IsJSCollatorFuzztest(data, size);
315     OHOS::IsJSPluralRulesFuzztest(data, size);
316     OHOS::IsStrictEqualsFuzztest(data, size);
317     OHOS::IsJSListFormatFuzztest(data, size);
318     OHOS::IsJSPrimitiveRefFuzztest(data, size);
319     OHOS::IsDequeFuzztest(data, size);
320     OHOS::IsJSIntlFuzztest(data, size);
321     OHOS::IsJSDateTimeFormatFuzztest(data, size);
322     OHOS::IsJSNumberFormatFuzztest(data, size);
323     OHOS::IsJSRelativeTimeFormatFuzztest(data, size);
324     return 0;
325 }