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 21using namespace panda; 22using namespace panda::ecmascript; 23 24#define MAXBYTELEN sizeof(int32_t) 25 26namespace OHOS { 27void 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 64void 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(vm); 75 JSNApi::DestroyJSVM(vm); 76} 77 78void 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 100Local<JSValueRef> FunCallback(JsiRuntimeCallInfo *info) 101{ 102 EscapeLocalScope scope(info->GetVM()); 103 return scope.Escape(ArrayRef::New(info->GetVM(), info->GetArgsNumber())); 104} 105 106void 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 NativePointerCallback deleter = nullptr; 116 FunctionCallback nativeFunc = FunCallback; 117 Local<FunctionRef> obj(FunctionRef::NewClassFunction(vm, nativeFunc, deleter, (void *)(data + size))); 118 (void)obj->IsFunction(vm); 119 JSNApi::DestroyJSVM(vm); 120} 121 122void 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(vm); 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(vm); 152 Local<Uint32ArrayRef> typedArray = Uint32ArrayRef::New(vm, ref, (int32_t)size, (int32_t)size); 153 typedArray->IsTypedArray(vm); 154 JSNApi::DestroyJSVM(vm); 155} 156 157void 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(vm); 194 intValue->IsDate(vm); 195 stringUtf8->IsDate(vm); 196 dateRef->IsDate(vm); 197 JSNApi::DestroyJSVM(vm); 198} 199 200void 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(vm); 227 intValue->IsError(vm); 228 stringUtf8->IsError(vm); 229 error->IsError(vm); 230 JSNApi::DestroyJSVM(vm); 231} 232 233void 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. 274extern "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