Coverage Report

Created: 2026-06-30 06:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/c_api_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
16
#include <stdint.h>
17
#include <stdio.h>
18
#include <string.h>
19
#include <vector>
20
#include <string>
21
22
#include "muParserDLL.h"
23
24
// Callbacks
25
230
muFloat_t MyFun1(muFloat_t v) { return v * 2; }
26
223
muFloat_t MyFun2(muFloat_t v1, muFloat_t v2) { return v1 + v2; }
27
547k
muFloat_t MyInfixFun(muFloat_t v) { return -v; }
28
7.39k
muFloat_t MyPostfixFun(muFloat_t v) { return v + 1; }
29
1.00k
muFloat_t MyOprtFun(muFloat_t v1, muFloat_t v2) { return v1 * v2 + 1; }
30
31
18.6k
muFloat_t* MyVarFactory(const muChar_t* name, void* pUserData) {
32
18.6k
  static muFloat_t v[10];
33
18.6k
  return v;
34
18.6k
}
35
36
488k
muInt_t MyIdentFun(const muChar_t* name, muInt_t* pos, muFloat_t* val) {
37
488k
  if (strncmp(name, "test", 4) == 0) {
38
469
    *val = 123.0;
39
469
    *pos += 4;
40
469
    return 1;
41
469
  }
42
488k
  return 0;
43
488k
}
44
45
5.51k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
46
5.51k
  if (size < 10) return 0;
47
48
  // Use the first few bytes for configuration
49
5.50k
  uint8_t config = data[0];
50
5.50k
  uint8_t config2 = data[1];
51
5.50k
  int base_type = (config & 0x01) ? muBASETYPE_INT : muBASETYPE_FLOAT;
52
  
53
5.50k
  muParserHandle_t hParser = mupCreate(base_type);
54
5.50k
  if (!hParser) return 0;
55
56
  // Remaining data as expression
57
5.50k
  size_t expr_size = (size - 2) / 2;
58
5.50k
  std::string expr((char *)(data + 2), expr_size);
59
5.50k
  mupSetExpr(hParser, expr.c_str());
60
61
5.50k
  std::string custom_chars((char *)(data + 2 + expr_size), size - 2 - expr_size);
62
63
  // Conditional configurations based on config bits
64
5.50k
  if (config & 0x02) {
65
2.76k
    mupDefineInfixOprt(hParser, "!", MyInfixFun, 0, 1);
66
2.76k
  }
67
5.50k
  if (config & 0x04) {
68
3.00k
    mupDefinePostfixOprt(hParser, "!!", MyPostfixFun, 1);
69
3.00k
  }
70
5.50k
  if (config & 0x08) {
71
2.93k
    mupDefineOprt(hParser, "shr", MyOprtFun, 0, muOPRT_ASCT_LEFT, 1);
72
2.93k
  }
73
5.50k
  if (config & 0x10) {
74
4.83k
    mupSetVarFactory(hParser, MyVarFactory, NULL);
75
4.83k
  }
76
5.50k
  if (config & 0x20) {
77
4.48k
    mupAddValIdent(hParser, MyIdentFun);
78
4.48k
  }
79
  
80
5.50k
  if (!custom_chars.empty()) {
81
5.50k
    if (config & 0x40) {
82
1.49k
      mupDefineNameChars(hParser, custom_chars.c_str());
83
1.49k
    }
84
5.50k
    if (config & 0x80) {
85
1.26k
      mupDefineOprtChars(hParser, custom_chars.c_str());
86
1.26k
    }
87
5.50k
  }
88
89
  // Set some common things anyway
90
5.50k
  muFloat_t v1[10] = {1.0};
91
5.50k
  mupDefineVar(hParser, "v1", v1);
92
5.50k
  mupDefineConst(hParser, "c1", 3.14);
93
5.50k
  mupDefineStrConst(hParser, "s1", "hello");
94
  
95
  // From c_api_fuzzer.cc
96
5.50k
  mupDefineFun1(hParser, "f1", MyFun1, 1);
97
5.50k
  mupDefineFun2(hParser, "f2", MyFun2, 1);
98
99
  // Evaluate
100
5.50k
  try {
101
5.50k
    if (config2 & 0x01) {
102
      // Bulk mode evaluation
103
2.81k
      muFloat_t results[10];
104
2.81k
      mupEvalBulk(hParser, results, 10);
105
2.81k
    } else {
106
2.68k
      mupEval(hParser);
107
      
108
      // Try mupEvalMulti only if no error occurred in mupEval
109
2.68k
      if (!mupError(hParser)) {
110
954
        int nNum;
111
954
        mupEvalMulti(hParser, &nNum);
112
954
      }
113
2.68k
    }
114
5.50k
  } catch (...) {
115
0
  }
116
117
  // Error handling
118
5.50k
  if (mupError(hParser)) {
119
1.68k
    mupGetErrorCode(hParser);
120
1.68k
    mupGetErrorPos(hParser);
121
1.68k
    mupGetErrorMsg(hParser);
122
1.68k
    mupGetErrorToken(hParser);
123
1.68k
  }
124
125
5.50k
  mupRelease(hParser);
126
5.50k
  return 0;
127
5.50k
}