| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include "bin/dartutils.h" |
| #include "platform/text_buffer.h" |
| #include "platform/unicode.h" |
| #include "platform/utils.h" |
| #include "vm/json_writer.h" |
| |
| // Defines target function. |
| static int target = 0; |
| |
| // Target function that stresses some unicode methods. |
| // Found: http://dartbug.com/36235 |
| static int TestUnicode(const uint8_t* Data, size_t Size) { |
| dart::Utf8::Type type = dart::Utf8::kLatin1; |
| dart::Utf8::CodeUnitCount(Data, Size, &type); |
| dart::Utf8::IsValid(Data, Size); |
| int32_t dst = 0; |
| dart::Utf8::Decode(Data, Size, &dst); |
| uint16_t dst16[1024]; |
| dart::Utf8::DecodeToUTF16(Data, Size, dst16, 1024); |
| int32_t dst32[1024]; |
| dart::Utf8::DecodeToUTF32(Data, Size, dst32, 1024); |
| dart::Utf8::ReportInvalidByte(Data, Size, 1024); |
| return 0; |
| } |
| |
| // Target function that stresses various utilities. |
| // Found: http://dartbug.com/36818 |
| static int TestUtilities(const uint8_t* Data, size_t Size) { |
| dart::Utils::StringHash(reinterpret_cast<const char*>(Data), Size); |
| dart::bin::DartUtils::SniffForMagicNumber(Data, Size); |
| // Text buffer. |
| dart::TextBuffer buffer(1); |
| for (size_t i = 0; i < Size; i++) { |
| buffer.AddChar(Data[i]); |
| } |
| if (static_cast<size_t>(buffer.length()) != Size) return 1; |
| buffer.AddRaw(Data, Size); |
| if (static_cast<size_t>(buffer.length()) != 2 * Size) return 1; |
| free(buffer.Steal()); |
| buffer.AddRaw(Data, Size); |
| if (static_cast<size_t>(buffer.length()) != Size) return 1; |
| // Json writer. |
| dart::JSONWriter writer(1); |
| writer.OpenObject("object"); |
| writer.AppendBytes(Data, Size); |
| writer.CloseObject(); |
| for (size_t i = 0; i < Size; i++) { |
| writer.PrintValue(static_cast<intptr_t>(Data[i])); |
| } |
| writer.PrintValueBase64(Data, Size); |
| return 0; |
| } |
| |
| // Dart VM specific initialization. |
| static int InitDartVM() { |
| // TODO(ajcbik): one-time setup of Dart VM. |
| return 0; |
| } |
| |
| // Libfuzzer one time initialization. |
| extern "C" int LLVMFuzzerInitialize(int* argc_in, char*** argv_in) { |
| // Parse --t=<target> from command line. |
| int argc = *argc_in; |
| char** argv = *argv_in; |
| while (--argc > 0) { |
| char* ptr = *++argv; |
| if (*ptr++ == '-' && *ptr++ == '-' && *ptr++ == 't' && *ptr++ == '=') { |
| target = atoi(ptr); |
| } |
| } |
| // Initialize Dart VM. |
| return InitDartVM(); |
| } |
| |
| // Libfuzzer target functions: |
| // 0 : unicode |
| // 1 : utilities |
| extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { |
| switch (target) { |
| case 0: |
| return TestUnicode(Data, Size); |
| case 1: |
| return TestUtilities(Data, Size); |
| default: |
| fprintf(stderr, "dart_libfuzzer: invalid target --t=%d\n", target); |
| return 1; |
| } |
| } |