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
30using namespace panda;
31using namespace panda::ecmascript;
32
33namespace OHOS {
34constexpr uint32_t ERROR_TYPE_LEN = 2;
35
36void 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
68void 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
93void 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
120void 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
148void 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
163void 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
177void 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
200void 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
228Local<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
239void 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
256void 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
273void 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
290void 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.
309extern "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}