Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2020 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 <cstdint> |
16 | | #include <chrono> |
17 | | #include <string> |
18 | | |
19 | | #define exprtk_enable_range_runtime_checks |
20 | | #include "exprtk.hpp" |
21 | | |
22 | | struct timeout_rtc_handler : public exprtk::loop_runtime_check |
23 | | { |
24 | | timeout_rtc_handler() |
25 | | : exprtk::loop_runtime_check() |
26 | 42.4k | {} |
27 | | |
28 | | class timeout_exception : public std::runtime_error |
29 | | { |
30 | | public: |
31 | | timeout_exception(const std::string& what = "") |
32 | | : std::runtime_error(what) |
33 | 1.61k | {} |
34 | | }; |
35 | | |
36 | | static constexpr std::size_t max_iterations = 5000000; |
37 | | |
38 | | using time_point_t = std::chrono::time_point<std::chrono::steady_clock>; |
39 | | |
40 | | void set_timeout_time(const time_point_t& timeout_tp) |
41 | 28.4k | { |
42 | 28.4k | timeout_tp_ = timeout_tp; |
43 | 28.4k | } |
44 | | |
45 | | bool check() override |
46 | 161M | { |
47 | 161M | if (++iterations_ >= max_iterations) |
48 | 0 | { |
49 | 0 | if (std::chrono::steady_clock::now() >= timeout_tp_) |
50 | 0 | { |
51 | 0 | return false; |
52 | 0 | } |
53 | 0 | iterations_ = 0; |
54 | 0 | } |
55 | | |
56 | 161M | return true; |
57 | 161M | } |
58 | | |
59 | | void handle_runtime_violation(const violation_context& ctx) override |
60 | 1.61k | { |
61 | 1.61k | throw timeout_exception("ExprTk Loop run-time timeout violation."); |
62 | 1.61k | } |
63 | | |
64 | | std::size_t iterations_ = 0; |
65 | | time_point_t timeout_tp_; |
66 | | }; |
67 | | |
68 | | template <typename T> |
69 | | void run(const std::string& expression_string) |
70 | 42.4k | { |
71 | 42.4k | typedef exprtk::symbol_table<T> symbol_table_t; |
72 | 42.4k | typedef exprtk::expression<T> expression_t; |
73 | 42.4k | typedef exprtk::parser<T> parser_t; |
74 | 42.4k | typedef exprtk::loop_runtime_check loop_runtime_check_t; |
75 | | |
76 | 42.4k | T x = T(1.2345); |
77 | 42.4k | T y = T(2.2345); |
78 | 42.4k | T z = T(3.2345); |
79 | 42.4k | T w = T(4.2345); |
80 | | |
81 | 42.4k | symbol_table_t symbol_table; |
82 | 42.4k | symbol_table.add_variable("x",x); |
83 | 42.4k | symbol_table.add_variable("y",y); |
84 | 42.4k | symbol_table.add_variable("z",z); |
85 | 42.4k | symbol_table.add_variable("w",w); |
86 | 42.4k | symbol_table.add_constants(); |
87 | | |
88 | 42.4k | expression_t expression; |
89 | 42.4k | expression.register_symbol_table(symbol_table); |
90 | | |
91 | 42.4k | timeout_rtc_handler loop_runtime_check; |
92 | 42.4k | loop_runtime_check.loop_set = loop_runtime_check_t::e_all_loops; |
93 | 42.4k | loop_runtime_check.max_loop_iterations = 100000; |
94 | | |
95 | 42.4k | parser_t parser; |
96 | | |
97 | 42.4k | parser.register_loop_runtime_check(loop_runtime_check); |
98 | | |
99 | 42.4k | if (parser.compile(expression_string, expression)) |
100 | 29.3k | { |
101 | 29.3k | const std::size_t max_expression_size = 64 * 1024; |
102 | | |
103 | 29.3k | if (expression_string.size() <= max_expression_size) |
104 | 28.4k | { |
105 | 28.4k | const auto max_duration = std::chrono::seconds(25); |
106 | 28.4k | const auto timeout_tp = std::chrono::steady_clock::now() + max_duration; |
107 | 28.4k | loop_runtime_check.set_timeout_time(timeout_tp); |
108 | | |
109 | 28.4k | try |
110 | 28.4k | { |
111 | 28.4k | expression.value(); |
112 | 28.4k | } |
113 | 28.4k | catch (std::runtime_error& rte) |
114 | 28.4k | {} |
115 | | |
116 | 28.4k | parser.clear_loop_runtime_check(); |
117 | 28.4k | } |
118 | 29.3k | } |
119 | 42.4k | } void run<double>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Line | Count | Source | 70 | 21.2k | { | 71 | 21.2k | typedef exprtk::symbol_table<T> symbol_table_t; | 72 | 21.2k | typedef exprtk::expression<T> expression_t; | 73 | 21.2k | typedef exprtk::parser<T> parser_t; | 74 | 21.2k | typedef exprtk::loop_runtime_check loop_runtime_check_t; | 75 | | | 76 | 21.2k | T x = T(1.2345); | 77 | 21.2k | T y = T(2.2345); | 78 | 21.2k | T z = T(3.2345); | 79 | 21.2k | T w = T(4.2345); | 80 | | | 81 | 21.2k | symbol_table_t symbol_table; | 82 | 21.2k | symbol_table.add_variable("x",x); | 83 | 21.2k | symbol_table.add_variable("y",y); | 84 | 21.2k | symbol_table.add_variable("z",z); | 85 | 21.2k | symbol_table.add_variable("w",w); | 86 | 21.2k | symbol_table.add_constants(); | 87 | | | 88 | 21.2k | expression_t expression; | 89 | 21.2k | expression.register_symbol_table(symbol_table); | 90 | | | 91 | 21.2k | timeout_rtc_handler loop_runtime_check; | 92 | 21.2k | loop_runtime_check.loop_set = loop_runtime_check_t::e_all_loops; | 93 | 21.2k | loop_runtime_check.max_loop_iterations = 100000; | 94 | | | 95 | 21.2k | parser_t parser; | 96 | | | 97 | 21.2k | parser.register_loop_runtime_check(loop_runtime_check); | 98 | | | 99 | 21.2k | if (parser.compile(expression_string, expression)) | 100 | 14.7k | { | 101 | 14.7k | const std::size_t max_expression_size = 64 * 1024; | 102 | | | 103 | 14.7k | if (expression_string.size() <= max_expression_size) | 104 | 14.2k | { | 105 | 14.2k | const auto max_duration = std::chrono::seconds(25); | 106 | 14.2k | const auto timeout_tp = std::chrono::steady_clock::now() + max_duration; | 107 | 14.2k | loop_runtime_check.set_timeout_time(timeout_tp); | 108 | | | 109 | 14.2k | try | 110 | 14.2k | { | 111 | 14.2k | expression.value(); | 112 | 14.2k | } | 113 | 14.2k | catch (std::runtime_error& rte) | 114 | 14.2k | {} | 115 | | | 116 | 14.2k | parser.clear_loop_runtime_check(); | 117 | 14.2k | } | 118 | 14.7k | } | 119 | 21.2k | } |
void run<float>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Line | Count | Source | 70 | 21.2k | { | 71 | 21.2k | typedef exprtk::symbol_table<T> symbol_table_t; | 72 | 21.2k | typedef exprtk::expression<T> expression_t; | 73 | 21.2k | typedef exprtk::parser<T> parser_t; | 74 | 21.2k | typedef exprtk::loop_runtime_check loop_runtime_check_t; | 75 | | | 76 | 21.2k | T x = T(1.2345); | 77 | 21.2k | T y = T(2.2345); | 78 | 21.2k | T z = T(3.2345); | 79 | 21.2k | T w = T(4.2345); | 80 | | | 81 | 21.2k | symbol_table_t symbol_table; | 82 | 21.2k | symbol_table.add_variable("x",x); | 83 | 21.2k | symbol_table.add_variable("y",y); | 84 | 21.2k | symbol_table.add_variable("z",z); | 85 | 21.2k | symbol_table.add_variable("w",w); | 86 | 21.2k | symbol_table.add_constants(); | 87 | | | 88 | 21.2k | expression_t expression; | 89 | 21.2k | expression.register_symbol_table(symbol_table); | 90 | | | 91 | 21.2k | timeout_rtc_handler loop_runtime_check; | 92 | 21.2k | loop_runtime_check.loop_set = loop_runtime_check_t::e_all_loops; | 93 | 21.2k | loop_runtime_check.max_loop_iterations = 100000; | 94 | | | 95 | 21.2k | parser_t parser; | 96 | | | 97 | 21.2k | parser.register_loop_runtime_check(loop_runtime_check); | 98 | | | 99 | 21.2k | if (parser.compile(expression_string, expression)) | 100 | 14.6k | { | 101 | 14.6k | const std::size_t max_expression_size = 64 * 1024; | 102 | | | 103 | 14.6k | if (expression_string.size() <= max_expression_size) | 104 | 14.1k | { | 105 | 14.1k | const auto max_duration = std::chrono::seconds(25); | 106 | 14.1k | const auto timeout_tp = std::chrono::steady_clock::now() + max_duration; | 107 | 14.1k | loop_runtime_check.set_timeout_time(timeout_tp); | 108 | | | 109 | 14.1k | try | 110 | 14.1k | { | 111 | 14.1k | expression.value(); | 112 | 14.1k | } | 113 | 14.1k | catch (std::runtime_error& rte) | 114 | 14.1k | {} | 115 | | | 116 | 14.1k | parser.clear_loop_runtime_check(); | 117 | 14.1k | } | 118 | 14.6k | } | 119 | 21.2k | } |
|
120 | | |
121 | | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) |
122 | 21.2k | { |
123 | 21.2k | const std::string expression(reinterpret_cast<const char*>(data), size); |
124 | | |
125 | 21.2k | run<double>(expression); |
126 | 21.2k | run<float> (expression); |
127 | | |
128 | 21.2k | return 0; |
129 | 21.2k | } |