Coverage Report

Created: 2026-08-14 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm_interp_fuzzer.cc
Line
Count
Source
1
// Copyright 2026 Google LLC
2
//
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
#include <cstddef>
16
#include <cstdint>
17
#include <vector>
18
19
#include "wabt/interp/binary-reader-interp.h"
20
#include "wabt/binary-reader.h"
21
#include "wabt/interp/interp.h"
22
#include "wabt/interp/interp-util.h"
23
24
12.2k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
25
12.2k
  wabt::Errors errors;
26
12.2k
  wabt::Features features;
27
  // Enable all features for more coverage.
28
256k
#define WABT_FEATURE(variable, flag, default_, help) features.enable_##variable();
29
12.2k
#include "wabt/feature.def"
30
12.2k
#undef WABT_FEATURE
31
32
12.2k
  wabt::interp::Store store;
33
12.2k
  store.setFeatures(features);
34
35
12.2k
  wabt::interp::ModuleDesc module_desc;
36
12.2k
  wabt::ReadBinaryOptions options(features, nullptr,
37
12.2k
                                  /*read_debug_names=*/true,
38
12.2k
                                  /*stop_on_first_error=*/true,
39
12.2k
                                  /*fail_on_custom_section_error=*/true);
40
12.2k
  if (wabt::Succeeded(wabt::interp::ReadBinaryInterp("<fuzzer>", data, size, options, &errors, &module_desc))) {
41
    // Check for excessive memory allocation to avoid OOM.
42
563
    for (auto&& mem : module_desc.memories) {
43
406
      if (mem.type.limits.initial > 1024) {
44
51
        return 0;
45
51
      }
46
406
    }
47
48
512
    wabt::interp::Module::Ptr module = wabt::interp::Module::New(store, module_desc);
49
512
    wabt::interp::RefVec imports;
50
    
51
    // Bind dummy imports
52
1.67k
    for (auto&& import : module->desc().imports) {
53
1.67k
      if (import.type.type->kind == wabt::interp::ExternKind::Func) {
54
1.16k
        auto func_type = *wabt::cast<wabt::interp::FuncType>(import.type.type.get());
55
1.16k
        auto host_func = wabt::interp::HostFunc::New(
56
1.16k
            store, func_type,
57
1.16k
            [](wabt::interp::Thread& thread, const wabt::interp::Values& params,
58
1.16k
               wabt::interp::Values& results, wabt::interp::Trap::Ptr* trap) -> wabt::Result {
59
33
              return wabt::Result::Ok;
60
33
            });
61
1.16k
        imports.push_back(host_func.ref());
62
1.16k
      } else {
63
510
        imports.push_back(wabt::interp::Ref::Null);
64
510
      }
65
1.67k
    }
66
67
512
    wabt::interp::Instance::Ptr instance;
68
512
    wabt::interp::Trap::Ptr trap;
69
512
    instance = wabt::interp::Instance::Instantiate(store, module.ref(), imports, &trap);
70
512
    if (instance) {
71
      // Run all exported functions that have no parameters.
72
      // This is a simple way to exercise the interpreter without complex argument generation.
73
441
      for (auto&& export_ : module->desc().exports) {
74
62
        if (export_.type.type->kind == wabt::ExternalKind::Func) {
75
51
          auto* func_type = wabt::cast<wabt::interp::FuncType>(export_.type.type.get());
76
51
          if (func_type->params.empty()) {
77
32
            auto func = store.UnsafeGet<wabt::interp::Func>(instance->funcs()[export_.index]);
78
32
            wabt::interp::Values params;
79
32
            wabt::interp::Values results;
80
32
            wabt::interp::Trap::Ptr call_trap;
81
32
            func->Call(store, params, results, &call_trap);
82
32
          }
83
51
        }
84
62
      }
85
441
    }
86
512
  }
87
88
12.1k
  return 0;
89
12.2k
}