LCOV - code coverage report
Current view: top level - test/fuzzer - parser.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 21 24 87.5 %
Date: 2019-02-19 Functions: 4 4 100.0 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <limits.h>
       6             : #include <stddef.h>
       7             : #include <stdint.h>
       8             : 
       9             : #include <cctype>
      10             : #include <list>
      11             : 
      12             : #include "include/v8.h"
      13             : #include "src/objects-inl.h"
      14             : #include "src/objects.h"
      15             : #include "src/parsing/parse-info.h"
      16             : #include "src/parsing/parsing.h"
      17             : #include "src/parsing/preparser.h"
      18             : #include "test/fuzzer/fuzzer-support.h"
      19             : 
      20           1 : bool IsValidInput(const uint8_t* data, size_t size) {
      21             :   // Ignore too long inputs as they tend to find OOM or timeouts, not real bugs.
      22           1 :   if (size > 2048) {
      23             :     return false;
      24             :   }
      25             : 
      26             :   std::list<char> parentheses;
      27             :   const char* ptr = reinterpret_cast<const char*>(data);
      28             : 
      29          29 :   for (size_t i = 0; i != size; ++i) {
      30             :     // Check that all characters in the data are valid.
      31          28 :     if (!(std::isspace(ptr[i]) || std::isprint(ptr[i]))) {
      32             :       return false;
      33             :     }
      34             : 
      35             :     // Check balance of parentheses in the data.
      36          28 :     switch (ptr[i]) {
      37             :       case '(':
      38             :       case '[':
      39             :       case '{':
      40             :         parentheses.push_back(ptr[i]);
      41             :         break;
      42             :       case ')':
      43           1 :         if (parentheses.back() != '(') return false;
      44             :         parentheses.pop_back();
      45             :         break;
      46             :       case ']':
      47           0 :         if (parentheses.back() != '[') return false;
      48             :         parentheses.pop_back();
      49             :         break;
      50             :       case '}':
      51           0 :         if (parentheses.back() != '{') return false;
      52             :         parentheses.pop_back();
      53             :         break;
      54             :       default:
      55             :         break;
      56             :     }
      57             :   }
      58             : 
      59           1 :   return parentheses.empty();
      60             : }
      61             : 
      62           1 : extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
      63           1 :   if (!IsValidInput(data, size)) {
      64             :     return 0;
      65             :   }
      66             : 
      67           1 :   v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get();
      68             :   v8::Isolate* isolate = support->GetIsolate();
      69             : 
      70             :   v8::Isolate::Scope isolate_scope(isolate);
      71           2 :   v8::HandleScope handle_scope(isolate);
      72           1 :   v8::Context::Scope context_scope(support->GetContext());
      73           2 :   v8::TryCatch try_catch(isolate);
      74             : 
      75             :   v8::internal::Isolate* i_isolate =
      76             :       reinterpret_cast<v8::internal::Isolate*>(isolate);
      77             :   v8::internal::Factory* factory = i_isolate->factory();
      78             : 
      79           1 :   if (size > INT_MAX) return 0;
      80             :   v8::internal::MaybeHandle<v8::internal::String> source =
      81             :       factory->NewStringFromOneByte(
      82           2 :           v8::internal::Vector<const uint8_t>(data, static_cast<int>(size)));
      83           1 :   if (source.is_null()) return 0;
      84             : 
      85             :   v8::internal::Handle<v8::internal::Script> script =
      86           1 :       factory->NewScript(source.ToHandleChecked());
      87           2 :   v8::internal::ParseInfo info(i_isolate, script);
      88           1 :   if (!v8::internal::parsing::ParseProgram(&info, i_isolate)) {
      89           0 :     i_isolate->OptionalRescheduleException(true);
      90             :   }
      91             :   isolate->RequestGarbageCollectionForTesting(
      92           1 :       v8::Isolate::kFullGarbageCollection);
      93             :   return 0;
      94           3 : }

Generated by: LCOV version 1.10