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