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 "jsvaluereffoundationvalue_fuzzer.h"
17 #include "ecmascript/base/string_helper.h"
18 #include "ecmascript/ecma_string-inl.h"
19 #include "ecmascript/napi/include/jsnapi.h"
20
21 using namespace panda;
22 using namespace panda::ecmascript;
23
24 #define MAXBYTELEN sizeof(int32_t)
25
26 namespace OHOS {
JSValueRefIsNumberValueFuzzTest(const uint8_t * data,size_t size)27 void JSValueRefIsNumberValueFuzzTest(const uint8_t *data, size_t size)
28 {
29 RuntimeOption option;
30 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
31 EcmaVM *vm = JSNApi::CreateJSVM(option);
32 int key = 0;
33 uint32_t inputUnit32 = 32;
34 if (data == nullptr || size <= 0) {
35 std::cout << "illegal input!";
36 return;
37 }
38 if (size > MAXBYTELEN) {
39 size = MAXBYTELEN;
40 }
41 if (memcpy_s(&key, MAXBYTELEN, data, size) != EOK) {
42 std::cout << "memcpy_s failed!";
43 UNREACHABLE();
44 }
45 Local<IntegerRef> intValue = IntegerRef::New(vm, key);
46 if (memcpy_s(&inputUnit32, MAXBYTELEN, data, size) != EOK) {
47 std::cout << "memcpy_s failed!";
48 UNREACHABLE();
49 }
50 Local<NumberRef> resUnit32 = NumberRef::New(vm, inputUnit32);
51 bool inputBool = true;
52 if (size == 0 || data == nullptr) {
53 inputBool = false;
54 }
55 Local<BooleanRef> resBool = BooleanRef::New(vm, inputBool);
56 Local<StringRef> stringUtf8 = StringRef::NewFromUtf8(vm, (char *)data, (int)size);
57 intValue->IsNumber();
58 resUnit32->IsNumber();
59 resBool->IsNumber();
60 stringUtf8->IsNumber();
61 JSNApi::DestroyJSVM(vm);
62 }
63
JSValueRefIsStringValueFuzzTest(const uint8_t * data,size_t size)64 void JSValueRefIsStringValueFuzzTest(const uint8_t *data, size_t size)
65 {
66 RuntimeOption option;
67 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
68 EcmaVM *vm = JSNApi::CreateJSVM(option);
69 if (data == nullptr || size <= 0) {
70 std::cout << "illegal input!";
71 return;
72 }
73 Local<JSValueRef> tag = StringRef::NewFromUtf8(vm, (char *)data, (int)size);
74 tag->IsString();
75 JSNApi::DestroyJSVM(vm);
76 }
77
JSValueRefWithinInt32ValueFuzzTest(const uint8_t * data,size_t size)78 void JSValueRefWithinInt32ValueFuzzTest(const uint8_t *data, size_t size)
79 {
80 RuntimeOption option;
81 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
82 EcmaVM *vm = JSNApi::CreateJSVM(option);
83 int number = 0;
84 if (data == nullptr || size <= 0) {
85 std::cout << "illegal input!";
86 return;
87 }
88 if (size > MAXBYTELEN) {
89 size = MAXBYTELEN;
90 }
91 if (memcpy_s(&number, MAXBYTELEN, data, size) != 0) {
92 std::cout << "memcpy_s failed!";
93 UNREACHABLE();
94 }
95 Local<JSValueRef> tag = IntegerRef::New(vm, number);
96 tag->WithinInt32();
97 JSNApi::DestroyJSVM(vm);
98 }
99
FunCallback(JsiRuntimeCallInfo * info)100 Local<JSValueRef> FunCallback(JsiRuntimeCallInfo *info)
101 {
102 EscapeLocalScope scope(info->GetVM());
103 return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber()));
104 }
105
JSValueRefIsFunctionValueFuzzTest(const uint8_t * data,size_t size)106 void JSValueRefIsFunctionValueFuzzTest(const uint8_t *data, size_t size)
107 {
108 RuntimeOption option;
109 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
110 EcmaVM *vm = JSNApi::CreateJSVM(option);
111 if (data == nullptr || size <= 0) {
112 std::cout << "illegal input!";
113 return;
114 }
115 Deleter deleter = nullptr;
116 FunctionCallback nativeFunc = FunCallback;
117 Local<FunctionRef> obj(FunctionRef::NewClassFunction(vm, nativeFunc, deleter, (void *)(data + size)));
118 (void)obj->IsFunction();
119 JSNApi::DestroyJSVM(vm);
120 }
121
JSValueRefIsTypedArrayValueFuzzTest(const uint8_t * data,size_t size)122 void JSValueRefIsTypedArrayValueFuzzTest(const uint8_t *data, size_t size)
123 {
124 RuntimeOption option;
125 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
126 EcmaVM *vm = JSNApi::CreateJSVM(option);
127 int number = 123;
128 if (data == nullptr || size <= 0) {
129 std::cout << "illegal input!";
130 return;
131 }
132 if (size > MAXBYTELEN) {
133 size = MAXBYTELEN;
134 }
135 if (memcpy_s(&number, MAXBYTELEN, data, size) != 0) {
136 std::cout << "memcpy_s failed!";
137 UNREACHABLE();
138 }
139 Local<JSValueRef> targetUInt = IntegerRef::New(vm, number);
140 targetUInt->IsTypedArray();
141 int32_t input;
142 if (memcpy_s(&input, MAXBYTELEN, data, size) != 0) {
143 std::cout << "memcpy_s failed!";
144 UNREACHABLE();
145 }
146 const int32_t MaxMenory = 1024;
147 if (input > MaxMenory) {
148 input = MaxMenory;
149 }
150 Local<ArrayBufferRef> ref = ArrayBufferRef::New(vm, input);
151 ref->IsArrayBuffer();
152 Local<Uint32ArrayRef> typedArray = Uint32ArrayRef::New(vm, ref, (int32_t)size, (int32_t)size);
153 typedArray->IsTypedArray();
154 JSNApi::DestroyJSVM(vm);
155 }
156
JSValueRefIsDateValueFuzzTest(const uint8_t * data,size_t size)157 void JSValueRefIsDateValueFuzzTest(const uint8_t *data, size_t size)
158 {
159 RuntimeOption option;
160 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
161 EcmaVM *vm = JSNApi::CreateJSVM(option);
162 int key = 0;
163 uint32_t inputUnit32 = 32;
164 if (data == nullptr || size <= 0) {
165 std::cout << "illegal input!";
166 return;
167 }
168 if (size > MAXBYTELEN) {
169 size = MAXBYTELEN;
170 }
171 if (memcpy_s(&key, MAXBYTELEN, data, size) != EOK) {
172 std::cout << "memcpy_s failed!";
173 UNREACHABLE();
174 }
175 Local<IntegerRef> intValue = IntegerRef::New(vm, key);
176 if (memcpy_s(&inputUnit32, MAXBYTELEN, data, size) != EOK) {
177 std::cout << "memcpy_s failed!";
178 UNREACHABLE();
179 }
180 Local<NumberRef> resUnit32 = NumberRef::New(vm, inputUnit32);
181 Local<StringRef> stringUtf8 = StringRef::NewFromUtf8(vm, (char *)data, (int)size);
182
183 double timeRef = 1.1;
184 size_t maxByteLen = 8;
185 if (size > maxByteLen) {
186 size = maxByteLen;
187 }
188 if (memcpy_s(&timeRef, maxByteLen, data, size) != EOK) {
189 std::cout << "memcpy_s failed!";
190 UNREACHABLE();
191 }
192 Local<DateRef> dateRef = DateRef::New(vm, timeRef);
193 resUnit32->IsDate();
194 intValue->IsDate();
195 stringUtf8->IsDate();
196 dateRef->IsDate();
197 JSNApi::DestroyJSVM(vm);
198 }
199
JSValueRefIsErrorValueFuzzTest(const uint8_t * data,size_t size)200 void JSValueRefIsErrorValueFuzzTest(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 int key = 0;
206 uint32_t inputUnit32 = 32;
207 if (data == nullptr || size <= 0) {
208 std::cout << "illegal input!";
209 return;
210 }
211 if (size > MAXBYTELEN) {
212 size = MAXBYTELEN;
213 }
214 if (memcpy_s(&key, MAXBYTELEN, data, size) != EOK) {
215 std::cout << "memcpy_s failed!";
216 UNREACHABLE();
217 }
218 Local<IntegerRef> intValue = IntegerRef::New(vm, key);
219 if (memcpy_s(&inputUnit32, MAXBYTELEN, data, size) != EOK) {
220 std::cout << "memcpy_s failed!";
221 UNREACHABLE();
222 }
223 Local<NumberRef> resUnit32 = NumberRef::New(vm, inputUnit32);
224 Local<StringRef> stringUtf8 = StringRef::NewFromUtf8(vm, (char *)data, (int)size);
225 Local<JSValueRef> error = Exception::Error(vm, stringUtf8);
226 resUnit32->IsError();
227 intValue->IsError();
228 stringUtf8->IsError();
229 error->IsError();
230 JSNApi::DestroyJSVM(vm);
231 }
232
JSValueRefToStringValueFuzzTest(const uint8_t * data,size_t size)233 void JSValueRefToStringValueFuzzTest(const uint8_t *data, size_t size)
234 {
235 RuntimeOption option;
236 option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
237 EcmaVM *vm = JSNApi::CreateJSVM(option);
238 int key = 0;
239 uint32_t inputUnit32 = 32;
240 if (data == nullptr || size <= 0) {
241 std::cout << "illegal input!";
242 return;
243 }
244 if (size > MAXBYTELEN) {
245 size = MAXBYTELEN;
246 }
247 if (memcpy_s(&key, MAXBYTELEN, data, size) != EOK) {
248 std::cout << "memcpy_s failed!";
249 UNREACHABLE();
250 }
251 Local<IntegerRef> intValue = IntegerRef::New(vm, key);
252 if (memcpy_s(&inputUnit32, MAXBYTELEN, data, size) != EOK) {
253 std::cout << "memcpy_s failed!";
254 UNREACHABLE();
255 }
256 Local<NumberRef> resUnit32 = NumberRef::New(vm, inputUnit32);
257 bool inputBool = true;
258 if (size == 0 || data == nullptr) {
259 inputBool = false;
260 }
261 Local<BooleanRef> resBool = BooleanRef::New(vm, inputBool);
262 Local<StringRef> stringUtf8 = StringRef::NewFromUtf8(vm, (char *)data, (int)size);
263 Local<JSValueRef> toTarget(stringUtf8);
264 intValue->ToString(vm);
265 resUnit32->ToString(vm);
266 resBool->ToString(vm);
267 toTarget->ToString(vm);
268 JSNApi::DestroyJSVM(vm);
269 }
270 }
271
272
273 // Fuzzer entry point.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)274 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
275 {
276 // Run your code on data.
277 OHOS::JSValueRefIsNumberValueFuzzTest(data, size);
278 OHOS::JSValueRefIsStringValueFuzzTest(data, size);
279 OHOS::JSValueRefWithinInt32ValueFuzzTest(data, size);
280 OHOS::JSValueRefIsFunctionValueFuzzTest(data, size);
281 OHOS::JSValueRefIsTypedArrayValueFuzzTest(data, size);
282 OHOS::JSValueRefIsDateValueFuzzTest(data, size);
283 OHOS::JSValueRefIsErrorValueFuzzTest(data, size);
284 OHOS::JSValueRefToStringValueFuzzTest(data, size);
285 return 0;
286 }
287