re2 1.17.3 → 1.17.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -347,6 +347,7 @@ console.log('re2_res : ' + re2_res); // prints: re2_res : abc,a,b,c
347
347
 
348
348
  ## Release history
349
349
 
350
+ - 1.17.4 *Updated deps.*
350
351
  - 1.17.3 *Fixed bug with zero-length replacements.*
351
352
  - 1.17.2 *Added support for the enhanced local mirroring by updating [install-artifact-from-github](https://github.com/uhop/install-artifact-from-github).*
352
353
  - 1.17.1 *Fix for `lastIndex` for U+10000 - U+10FFFF UTF characters. Thx, [omg](https://github.com/omg).*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "re2",
3
- "version": "1.17.3",
3
+ "version": "1.17.4",
4
4
  "description": "Bindings for RE2: fast, safe alternative to backtracking regular expression engines.",
5
5
  "homepage": "https://github.com/uhop/node-re2",
6
6
  "bugs": "https://github.com/uhop/node-re2/issues",
@@ -14,11 +14,13 @@
14
14
  #define LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_
15
15
 
16
16
  #include <algorithm>
17
+ #include <array>
17
18
  #include <climits>
18
19
  #include <cstddef>
19
20
  #include <cstdint>
20
21
  #include <cstring>
21
22
  #include <initializer_list>
23
+ #include <limits>
22
24
  #include <string>
23
25
  #include <type_traits>
24
26
  #include <utility>
@@ -34,272 +36,362 @@ class FuzzedDataProvider {
34
36
  : data_ptr_(data), remaining_bytes_(size) {}
35
37
  ~FuzzedDataProvider() = default;
36
38
 
37
- // Returns a std::vector containing |num_bytes| of input data. If fewer than
38
- // |num_bytes| of data remain, returns a shorter std::vector containing all
39
- // of the data that's left. Can be used with any byte sized type, such as
40
- // char, unsigned char, uint8_t, etc.
41
- template <typename T> std::vector<T> ConsumeBytes(size_t num_bytes) {
42
- num_bytes = std::min(num_bytes, remaining_bytes_);
43
- return ConsumeBytes<T>(num_bytes, num_bytes);
44
- }
39
+ // See the implementation below (after the class definition) for more verbose
40
+ // comments for each of the methods.
45
41
 
46
- // Similar to |ConsumeBytes|, but also appends the terminator value at the end
47
- // of the resulting vector. Useful, when a mutable null-terminated C-string is
48
- // needed, for example. But that is a rare case. Better avoid it, if possible,
49
- // and prefer using |ConsumeBytes| or |ConsumeBytesAsString| methods.
42
+ // Methods returning std::vector of bytes. These are the most popular choice
43
+ // when splitting fuzzing input into pieces, as every piece is put into a
44
+ // separate buffer (i.e. ASan would catch any under-/overflow) and the memory
45
+ // will be released automatically.
46
+ template <typename T> std::vector<T> ConsumeBytes(size_t num_bytes);
50
47
  template <typename T>
51
- std::vector<T> ConsumeBytesWithTerminator(size_t num_bytes,
52
- T terminator = 0) {
53
- num_bytes = std::min(num_bytes, remaining_bytes_);
54
- std::vector<T> result = ConsumeBytes<T>(num_bytes + 1, num_bytes);
55
- result.back() = terminator;
56
- return result;
57
- }
48
+ std::vector<T> ConsumeBytesWithTerminator(size_t num_bytes, T terminator = 0);
49
+ template <typename T> std::vector<T> ConsumeRemainingBytes();
58
50
 
59
- // Returns a std::string containing |num_bytes| of input data. Using this and
60
- // |.c_str()| on the resulting string is the best way to get an immutable
61
- // null-terminated C string. If fewer than |num_bytes| of data remain, returns
62
- // a shorter std::string containing all of the data that's left.
63
- std::string ConsumeBytesAsString(size_t num_bytes) {
64
- static_assert(sizeof(std::string::value_type) == sizeof(uint8_t),
65
- "ConsumeBytesAsString cannot convert the data to a string.");
66
-
67
- num_bytes = std::min(num_bytes, remaining_bytes_);
68
- std::string result(
69
- reinterpret_cast<const std::string::value_type *>(data_ptr_),
70
- num_bytes);
71
- Advance(num_bytes);
72
- return result;
73
- }
51
+ // Methods returning strings. Use only when you need a std::string or a null
52
+ // terminated C-string. Otherwise, prefer the methods returning std::vector.
53
+ std::string ConsumeBytesAsString(size_t num_bytes);
54
+ std::string ConsumeRandomLengthString(size_t max_length);
55
+ std::string ConsumeRandomLengthString();
56
+ std::string ConsumeRemainingBytesAsString();
74
57
 
75
- // Returns a number in the range [min, max] by consuming bytes from the
76
- // input data. The value might not be uniformly distributed in the given
77
- // range. If there's no input data left, always returns |min|. |min| must
78
- // be less than or equal to |max|.
79
- template <typename T> T ConsumeIntegralInRange(T min, T max) {
80
- static_assert(std::is_integral<T>::value, "An integral type is required.");
81
- static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
58
+ // Methods returning integer values.
59
+ template <typename T> T ConsumeIntegral();
60
+ template <typename T> T ConsumeIntegralInRange(T min, T max);
82
61
 
83
- if (min > max)
84
- abort();
62
+ // Methods returning floating point values.
63
+ template <typename T> T ConsumeFloatingPoint();
64
+ template <typename T> T ConsumeFloatingPointInRange(T min, T max);
85
65
 
86
- // Use the biggest type possible to hold the range and the result.
87
- uint64_t range = static_cast<uint64_t>(max) - min;
88
- uint64_t result = 0;
89
- size_t offset = 0;
90
-
91
- while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
92
- remaining_bytes_ != 0) {
93
- // Pull bytes off the end of the seed data. Experimentally, this seems to
94
- // allow the fuzzer to more easily explore the input space. This makes
95
- // sense, since it works by modifying inputs that caused new code to run,
96
- // and this data is often used to encode length of data read by
97
- // |ConsumeBytes|. Separating out read lengths makes it easier modify the
98
- // contents of the data that is actually read.
99
- --remaining_bytes_;
100
- result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
101
- offset += CHAR_BIT;
102
- }
66
+ // 0 <= return value <= 1.
67
+ template <typename T> T ConsumeProbability();
103
68
 
104
- // Avoid division by 0, in case |range + 1| results in overflow.
105
- if (range != std::numeric_limits<decltype(range)>::max())
106
- result = result % (range + 1);
69
+ bool ConsumeBool();
107
70
 
108
- return static_cast<T>(min + result);
109
- }
71
+ // Returns a value chosen from the given enum.
72
+ template <typename T> T ConsumeEnum();
110
73
 
111
- // Returns a std::string of length from 0 to |max_length|. When it runs out of
112
- // input data, returns what remains of the input. Designed to be more stable
113
- // with respect to a fuzzer inserting characters than just picking a random
114
- // length and then consuming that many bytes with |ConsumeBytes|.
115
- std::string ConsumeRandomLengthString(size_t max_length) {
116
- // Reads bytes from the start of |data_ptr_|. Maps "\\" to "\", and maps "\"
117
- // followed by anything else to the end of the string. As a result of this
118
- // logic, a fuzzer can insert characters into the string, and the string
119
- // will be lengthened to include those new characters, resulting in a more
120
- // stable fuzzer than picking the length of a string independently from
121
- // picking its contents.
122
- std::string result;
123
-
124
- // Reserve the anticipated capaticity to prevent several reallocations.
125
- result.reserve(std::min(max_length, remaining_bytes_));
126
- for (size_t i = 0; i < max_length && remaining_bytes_ != 0; ++i) {
127
- char next = ConvertUnsignedToSigned<char>(data_ptr_[0]);
128
- Advance(1);
129
- if (next == '\\' && remaining_bytes_ != 0) {
130
- next = ConvertUnsignedToSigned<char>(data_ptr_[0]);
131
- Advance(1);
132
- if (next != '\\')
133
- break;
134
- }
135
- result += next;
136
- }
137
-
138
- result.shrink_to_fit();
139
- return result;
140
- }
74
+ // Returns a value from the given array.
75
+ template <typename T, size_t size> T PickValueInArray(const T (&array)[size]);
76
+ template <typename T, size_t size>
77
+ T PickValueInArray(const std::array<T, size> &array);
78
+ template <typename T> T PickValueInArray(std::initializer_list<const T> list);
141
79
 
142
- // Returns a std::vector containing all remaining bytes of the input data.
143
- template <typename T> std::vector<T> ConsumeRemainingBytes() {
144
- return ConsumeBytes<T>(remaining_bytes_);
145
- }
80
+ // Writes data to the given destination and returns number of bytes written.
81
+ size_t ConsumeData(void *destination, size_t num_bytes);
146
82
 
147
- // Returns a std::string containing all remaining bytes of the input data.
148
- // Prefer using |ConsumeRemainingBytes| unless you actually need a std::string
149
- // object.
150
- std::string ConsumeRemainingBytesAsString() {
151
- return ConsumeBytesAsString(remaining_bytes_);
152
- }
83
+ // Reports the remaining bytes available for fuzzed input.
84
+ size_t remaining_bytes() { return remaining_bytes_; }
153
85
 
154
- // Returns a number in the range [Type's min, Type's max]. The value might
155
- // not be uniformly distributed in the given range. If there's no input data
156
- // left, always returns |min|.
157
- template <typename T> T ConsumeIntegral() {
158
- return ConsumeIntegralInRange(std::numeric_limits<T>::min(),
159
- std::numeric_limits<T>::max());
160
- }
86
+ private:
87
+ FuzzedDataProvider(const FuzzedDataProvider &) = delete;
88
+ FuzzedDataProvider &operator=(const FuzzedDataProvider &) = delete;
161
89
 
162
- // Reads one byte and returns a bool, or false when no data remains.
163
- bool ConsumeBool() { return 1 & ConsumeIntegral<uint8_t>(); }
90
+ void CopyAndAdvance(void *destination, size_t num_bytes);
164
91
 
165
- // Returns a copy of the value selected from the given fixed-size |array|.
166
- template <typename T, size_t size>
167
- T PickValueInArray(const T (&array)[size]) {
168
- static_assert(size > 0, "The array must be non empty.");
169
- return array[ConsumeIntegralInRange<size_t>(0, size - 1)];
170
- }
92
+ void Advance(size_t num_bytes);
171
93
 
172
94
  template <typename T>
173
- T PickValueInArray(std::initializer_list<const T> list) {
174
- // TODO(Dor1s): switch to static_assert once C++14 is allowed.
175
- if (!list.size())
176
- abort();
177
-
178
- return *(list.begin() + ConsumeIntegralInRange<size_t>(0, list.size() - 1));
179
- }
180
-
181
- // Returns an enum value. The enum must start at 0 and be contiguous. It must
182
- // also contain |kMaxValue| aliased to its largest (inclusive) value. Such as:
183
- // enum class Foo { SomeValue, OtherValue, kMaxValue = OtherValue };
184
- template <typename T> T ConsumeEnum() {
185
- static_assert(std::is_enum<T>::value, "|T| must be an enum type.");
186
- return static_cast<T>(ConsumeIntegralInRange<uint32_t>(
187
- 0, static_cast<uint32_t>(T::kMaxValue)));
188
- }
95
+ std::vector<T> ConsumeBytes(size_t size, size_t num_bytes);
189
96
 
190
- // Returns a floating point number in the range [0.0, 1.0]. If there's no
191
- // input data left, always returns 0.
192
- template <typename T> T ConsumeProbability() {
193
- static_assert(std::is_floating_point<T>::value,
194
- "A floating point type is required.");
97
+ template <typename TS, typename TU> TS ConvertUnsignedToSigned(TU value);
195
98
 
196
- // Use different integral types for different floating point types in order
197
- // to provide better density of the resulting values.
198
- using IntegralType =
199
- typename std::conditional<(sizeof(T) <= sizeof(uint32_t)), uint32_t,
200
- uint64_t>::type;
99
+ const uint8_t *data_ptr_;
100
+ size_t remaining_bytes_;
101
+ };
201
102
 
202
- T result = static_cast<T>(ConsumeIntegral<IntegralType>());
203
- result /= static_cast<T>(std::numeric_limits<IntegralType>::max());
204
- return result;
103
+ // Returns a std::vector containing |num_bytes| of input data. If fewer than
104
+ // |num_bytes| of data remain, returns a shorter std::vector containing all
105
+ // of the data that's left. Can be used with any byte sized type, such as
106
+ // char, unsigned char, uint8_t, etc.
107
+ template <typename T>
108
+ std::vector<T> FuzzedDataProvider::ConsumeBytes(size_t num_bytes) {
109
+ num_bytes = std::min(num_bytes, remaining_bytes_);
110
+ return ConsumeBytes<T>(num_bytes, num_bytes);
111
+ }
112
+
113
+ // Similar to |ConsumeBytes|, but also appends the terminator value at the end
114
+ // of the resulting vector. Useful, when a mutable null-terminated C-string is
115
+ // needed, for example. But that is a rare case. Better avoid it, if possible,
116
+ // and prefer using |ConsumeBytes| or |ConsumeBytesAsString| methods.
117
+ template <typename T>
118
+ std::vector<T> FuzzedDataProvider::ConsumeBytesWithTerminator(size_t num_bytes,
119
+ T terminator) {
120
+ num_bytes = std::min(num_bytes, remaining_bytes_);
121
+ std::vector<T> result = ConsumeBytes<T>(num_bytes + 1, num_bytes);
122
+ result.back() = terminator;
123
+ return result;
124
+ }
125
+
126
+ // Returns a std::vector containing all remaining bytes of the input data.
127
+ template <typename T>
128
+ std::vector<T> FuzzedDataProvider::ConsumeRemainingBytes() {
129
+ return ConsumeBytes<T>(remaining_bytes_);
130
+ }
131
+
132
+ // Returns a std::string containing |num_bytes| of input data. Using this and
133
+ // |.c_str()| on the resulting string is the best way to get an immutable
134
+ // null-terminated C string. If fewer than |num_bytes| of data remain, returns
135
+ // a shorter std::string containing all of the data that's left.
136
+ inline std::string FuzzedDataProvider::ConsumeBytesAsString(size_t num_bytes) {
137
+ static_assert(sizeof(std::string::value_type) == sizeof(uint8_t),
138
+ "ConsumeBytesAsString cannot convert the data to a string.");
139
+
140
+ num_bytes = std::min(num_bytes, remaining_bytes_);
141
+ std::string result(
142
+ reinterpret_cast<const std::string::value_type *>(data_ptr_), num_bytes);
143
+ Advance(num_bytes);
144
+ return result;
145
+ }
146
+
147
+ // Returns a std::string of length from 0 to |max_length|. When it runs out of
148
+ // input data, returns what remains of the input. Designed to be more stable
149
+ // with respect to a fuzzer inserting characters than just picking a random
150
+ // length and then consuming that many bytes with |ConsumeBytes|.
151
+ inline std::string
152
+ FuzzedDataProvider::ConsumeRandomLengthString(size_t max_length) {
153
+ // Reads bytes from the start of |data_ptr_|. Maps "\\" to "\", and maps "\"
154
+ // followed by anything else to the end of the string. As a result of this
155
+ // logic, a fuzzer can insert characters into the string, and the string
156
+ // will be lengthened to include those new characters, resulting in a more
157
+ // stable fuzzer than picking the length of a string independently from
158
+ // picking its contents.
159
+ std::string result;
160
+
161
+ // Reserve the anticipated capaticity to prevent several reallocations.
162
+ result.reserve(std::min(max_length, remaining_bytes_));
163
+ for (size_t i = 0; i < max_length && remaining_bytes_ != 0; ++i) {
164
+ char next = ConvertUnsignedToSigned<char>(data_ptr_[0]);
165
+ Advance(1);
166
+ if (next == '\\' && remaining_bytes_ != 0) {
167
+ next = ConvertUnsignedToSigned<char>(data_ptr_[0]);
168
+ Advance(1);
169
+ if (next != '\\')
170
+ break;
171
+ }
172
+ result += next;
205
173
  }
206
174
 
207
- // Returns a floating point value in the range [Type's lowest, Type's max] by
208
- // consuming bytes from the input data. If there's no input data left, always
209
- // returns approximately 0.
210
- template <typename T> T ConsumeFloatingPoint() {
211
- return ConsumeFloatingPointInRange<T>(std::numeric_limits<T>::lowest(),
212
- std::numeric_limits<T>::max());
175
+ result.shrink_to_fit();
176
+ return result;
177
+ }
178
+
179
+ // Returns a std::string of length from 0 to |remaining_bytes_|.
180
+ inline std::string FuzzedDataProvider::ConsumeRandomLengthString() {
181
+ return ConsumeRandomLengthString(remaining_bytes_);
182
+ }
183
+
184
+ // Returns a std::string containing all remaining bytes of the input data.
185
+ // Prefer using |ConsumeRemainingBytes| unless you actually need a std::string
186
+ // object.
187
+ inline std::string FuzzedDataProvider::ConsumeRemainingBytesAsString() {
188
+ return ConsumeBytesAsString(remaining_bytes_);
189
+ }
190
+
191
+ // Returns a number in the range [Type's min, Type's max]. The value might
192
+ // not be uniformly distributed in the given range. If there's no input data
193
+ // left, always returns |min|.
194
+ template <typename T> T FuzzedDataProvider::ConsumeIntegral() {
195
+ return ConsumeIntegralInRange(std::numeric_limits<T>::min(),
196
+ std::numeric_limits<T>::max());
197
+ }
198
+
199
+ // Returns a number in the range [min, max] by consuming bytes from the
200
+ // input data. The value might not be uniformly distributed in the given
201
+ // range. If there's no input data left, always returns |min|. |min| must
202
+ // be less than or equal to |max|.
203
+ template <typename T>
204
+ T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) {
205
+ static_assert(std::is_integral<T>::value, "An integral type is required.");
206
+ static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
207
+
208
+ if (min > max)
209
+ abort();
210
+
211
+ // Use the biggest type possible to hold the range and the result.
212
+ uint64_t range = static_cast<uint64_t>(max) - min;
213
+ uint64_t result = 0;
214
+ size_t offset = 0;
215
+
216
+ while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
217
+ remaining_bytes_ != 0) {
218
+ // Pull bytes off the end of the seed data. Experimentally, this seems to
219
+ // allow the fuzzer to more easily explore the input space. This makes
220
+ // sense, since it works by modifying inputs that caused new code to run,
221
+ // and this data is often used to encode length of data read by
222
+ // |ConsumeBytes|. Separating out read lengths makes it easier modify the
223
+ // contents of the data that is actually read.
224
+ --remaining_bytes_;
225
+ result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
226
+ offset += CHAR_BIT;
213
227
  }
214
228
 
215
- // Returns a floating point value in the given range by consuming bytes from
216
- // the input data. If there's no input data left, returns |min|. Note that
217
- // |min| must be less than or equal to |max|.
218
- template <typename T> T ConsumeFloatingPointInRange(T min, T max) {
219
- if (min > max)
220
- abort();
221
-
222
- T range = .0;
223
- T result = min;
224
- constexpr T zero(.0);
225
- if (max > zero && min < zero && max > min + std::numeric_limits<T>::max()) {
226
- // The diff |max - min| would overflow the given floating point type. Use
227
- // the half of the diff as the range and consume a bool to decide whether
228
- // the result is in the first of the second part of the diff.
229
- range = (max / 2.0) - (min / 2.0);
230
- if (ConsumeBool()) {
231
- result += range;
232
- }
233
- } else {
234
- range = max - min;
229
+ // Avoid division by 0, in case |range + 1| results in overflow.
230
+ if (range != std::numeric_limits<decltype(range)>::max())
231
+ result = result % (range + 1);
232
+
233
+ return static_cast<T>(min + result);
234
+ }
235
+
236
+ // Returns a floating point value in the range [Type's lowest, Type's max] by
237
+ // consuming bytes from the input data. If there's no input data left, always
238
+ // returns approximately 0.
239
+ template <typename T> T FuzzedDataProvider::ConsumeFloatingPoint() {
240
+ return ConsumeFloatingPointInRange<T>(std::numeric_limits<T>::lowest(),
241
+ std::numeric_limits<T>::max());
242
+ }
243
+
244
+ // Returns a floating point value in the given range by consuming bytes from
245
+ // the input data. If there's no input data left, returns |min|. Note that
246
+ // |min| must be less than or equal to |max|.
247
+ template <typename T>
248
+ T FuzzedDataProvider::ConsumeFloatingPointInRange(T min, T max) {
249
+ if (min > max)
250
+ abort();
251
+
252
+ T range = .0;
253
+ T result = min;
254
+ constexpr T zero(.0);
255
+ if (max > zero && min < zero && max > min + std::numeric_limits<T>::max()) {
256
+ // The diff |max - min| would overflow the given floating point type. Use
257
+ // the half of the diff as the range and consume a bool to decide whether
258
+ // the result is in the first of the second part of the diff.
259
+ range = (max / 2.0) - (min / 2.0);
260
+ if (ConsumeBool()) {
261
+ result += range;
235
262
  }
236
-
237
- return result + range * ConsumeProbability<T>();
263
+ } else {
264
+ range = max - min;
238
265
  }
239
266
 
240
- // Reports the remaining bytes available for fuzzed input.
241
- size_t remaining_bytes() { return remaining_bytes_; }
242
-
243
- private:
244
- FuzzedDataProvider(const FuzzedDataProvider &) = delete;
245
- FuzzedDataProvider &operator=(const FuzzedDataProvider &) = delete;
246
-
247
- void Advance(size_t num_bytes) {
248
- if (num_bytes > remaining_bytes_)
267
+ return result + range * ConsumeProbability<T>();
268
+ }
269
+
270
+ // Returns a floating point number in the range [0.0, 1.0]. If there's no
271
+ // input data left, always returns 0.
272
+ template <typename T> T FuzzedDataProvider::ConsumeProbability() {
273
+ static_assert(std::is_floating_point<T>::value,
274
+ "A floating point type is required.");
275
+
276
+ // Use different integral types for different floating point types in order
277
+ // to provide better density of the resulting values.
278
+ using IntegralType =
279
+ typename std::conditional<(sizeof(T) <= sizeof(uint32_t)), uint32_t,
280
+ uint64_t>::type;
281
+
282
+ T result = static_cast<T>(ConsumeIntegral<IntegralType>());
283
+ result /= static_cast<T>(std::numeric_limits<IntegralType>::max());
284
+ return result;
285
+ }
286
+
287
+ // Reads one byte and returns a bool, or false when no data remains.
288
+ inline bool FuzzedDataProvider::ConsumeBool() {
289
+ return 1 & ConsumeIntegral<uint8_t>();
290
+ }
291
+
292
+ // Returns an enum value. The enum must start at 0 and be contiguous. It must
293
+ // also contain |kMaxValue| aliased to its largest (inclusive) value. Such as:
294
+ // enum class Foo { SomeValue, OtherValue, kMaxValue = OtherValue };
295
+ template <typename T> T FuzzedDataProvider::ConsumeEnum() {
296
+ static_assert(std::is_enum<T>::value, "|T| must be an enum type.");
297
+ return static_cast<T>(
298
+ ConsumeIntegralInRange<uint32_t>(0, static_cast<uint32_t>(T::kMaxValue)));
299
+ }
300
+
301
+ // Returns a copy of the value selected from the given fixed-size |array|.
302
+ template <typename T, size_t size>
303
+ T FuzzedDataProvider::PickValueInArray(const T (&array)[size]) {
304
+ static_assert(size > 0, "The array must be non empty.");
305
+ return array[ConsumeIntegralInRange<size_t>(0, size - 1)];
306
+ }
307
+
308
+ template <typename T, size_t size>
309
+ T FuzzedDataProvider::PickValueInArray(const std::array<T, size> &array) {
310
+ static_assert(size > 0, "The array must be non empty.");
311
+ return array[ConsumeIntegralInRange<size_t>(0, size - 1)];
312
+ }
313
+
314
+ template <typename T>
315
+ T FuzzedDataProvider::PickValueInArray(std::initializer_list<const T> list) {
316
+ // TODO(Dor1s): switch to static_assert once C++14 is allowed.
317
+ if (!list.size())
318
+ abort();
319
+
320
+ return *(list.begin() + ConsumeIntegralInRange<size_t>(0, list.size() - 1));
321
+ }
322
+
323
+ // Writes |num_bytes| of input data to the given destination pointer. If there
324
+ // is not enough data left, writes all remaining bytes. Return value is the
325
+ // number of bytes written.
326
+ // In general, it's better to avoid using this function, but it may be useful
327
+ // in cases when it's necessary to fill a certain buffer or object with
328
+ // fuzzing data.
329
+ inline size_t FuzzedDataProvider::ConsumeData(void *destination,
330
+ size_t num_bytes) {
331
+ num_bytes = std::min(num_bytes, remaining_bytes_);
332
+ CopyAndAdvance(destination, num_bytes);
333
+ return num_bytes;
334
+ }
335
+
336
+ // Private methods.
337
+ inline void FuzzedDataProvider::CopyAndAdvance(void *destination,
338
+ size_t num_bytes) {
339
+ std::memcpy(destination, data_ptr_, num_bytes);
340
+ Advance(num_bytes);
341
+ }
342
+
343
+ inline void FuzzedDataProvider::Advance(size_t num_bytes) {
344
+ if (num_bytes > remaining_bytes_)
345
+ abort();
346
+
347
+ data_ptr_ += num_bytes;
348
+ remaining_bytes_ -= num_bytes;
349
+ }
350
+
351
+ template <typename T>
352
+ std::vector<T> FuzzedDataProvider::ConsumeBytes(size_t size, size_t num_bytes) {
353
+ static_assert(sizeof(T) == sizeof(uint8_t), "Incompatible data type.");
354
+
355
+ // The point of using the size-based constructor below is to increase the
356
+ // odds of having a vector object with capacity being equal to the length.
357
+ // That part is always implementation specific, but at least both libc++ and
358
+ // libstdc++ allocate the requested number of bytes in that constructor,
359
+ // which seems to be a natural choice for other implementations as well.
360
+ // To increase the odds even more, we also call |shrink_to_fit| below.
361
+ std::vector<T> result(size);
362
+ if (size == 0) {
363
+ if (num_bytes != 0)
249
364
  abort();
250
-
251
- data_ptr_ += num_bytes;
252
- remaining_bytes_ -= num_bytes;
253
- }
254
-
255
- template <typename T>
256
- std::vector<T> ConsumeBytes(size_t size, size_t num_bytes_to_consume) {
257
- static_assert(sizeof(T) == sizeof(uint8_t), "Incompatible data type.");
258
-
259
- // The point of using the size-based constructor below is to increase the
260
- // odds of having a vector object with capacity being equal to the length.
261
- // That part is always implementation specific, but at least both libc++ and
262
- // libstdc++ allocate the requested number of bytes in that constructor,
263
- // which seems to be a natural choice for other implementations as well.
264
- // To increase the odds even more, we also call |shrink_to_fit| below.
265
- std::vector<T> result(size);
266
- if (size == 0) {
267
- if (num_bytes_to_consume != 0)
268
- abort();
269
- return result;
270
- }
271
-
272
- std::memcpy(result.data(), data_ptr_, num_bytes_to_consume);
273
- Advance(num_bytes_to_consume);
274
-
275
- // Even though |shrink_to_fit| is also implementation specific, we expect it
276
- // to provide an additional assurance in case vector's constructor allocated
277
- // a buffer which is larger than the actual amount of data we put inside it.
278
- result.shrink_to_fit();
279
365
  return result;
280
366
  }
281
367
 
282
- template <typename TS, typename TU> TS ConvertUnsignedToSigned(TU value) {
283
- static_assert(sizeof(TS) == sizeof(TU), "Incompatible data types.");
284
- static_assert(!std::numeric_limits<TU>::is_signed,
285
- "Source type must be unsigned.");
286
-
287
- // TODO(Dor1s): change to `if constexpr` once C++17 becomes mainstream.
288
- if (std::numeric_limits<TS>::is_modulo)
289
- return static_cast<TS>(value);
290
-
291
- // Avoid using implementation-defined unsigned to signer conversions.
292
- // To learn more, see https://stackoverflow.com/questions/13150449.
293
- if (value <= std::numeric_limits<TS>::max()) {
294
- return static_cast<TS>(value);
295
- } else {
296
- constexpr auto TS_min = std::numeric_limits<TS>::min();
297
- return TS_min + static_cast<char>(value - TS_min);
298
- }
368
+ CopyAndAdvance(result.data(), num_bytes);
369
+
370
+ // Even though |shrink_to_fit| is also implementation specific, we expect it
371
+ // to provide an additional assurance in case vector's constructor allocated
372
+ // a buffer which is larger than the actual amount of data we put inside it.
373
+ result.shrink_to_fit();
374
+ return result;
375
+ }
376
+
377
+ template <typename TS, typename TU>
378
+ TS FuzzedDataProvider::ConvertUnsignedToSigned(TU value) {
379
+ static_assert(sizeof(TS) == sizeof(TU), "Incompatible data types.");
380
+ static_assert(!std::numeric_limits<TU>::is_signed,
381
+ "Source type must be unsigned.");
382
+
383
+ // TODO(Dor1s): change to `if constexpr` once C++17 becomes mainstream.
384
+ if (std::numeric_limits<TS>::is_modulo)
385
+ return static_cast<TS>(value);
386
+
387
+ // Avoid using implementation-defined unsigned to signed conversions.
388
+ // To learn more, see https://stackoverflow.com/questions/13150449.
389
+ if (value <= std::numeric_limits<TS>::max()) {
390
+ return static_cast<TS>(value);
391
+ } else {
392
+ constexpr auto TS_min = std::numeric_limits<TS>::min();
393
+ return TS_min + static_cast<TS>(value - TS_min);
299
394
  }
300
-
301
- const uint8_t *data_ptr_;
302
- size_t remaining_bytes_;
303
- };
395
+ }
304
396
 
305
397
  #endif // LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_
@@ -1,4 +1,4 @@
1
- #!/usr/bin/python
1
+ #!/usr/bin/python3
2
2
  # coding=utf-8
3
3
  #
4
4
  # Copyright 2008 The RE2 Authors. All Rights Reserved.
@@ -1,4 +1,4 @@
1
- #!/usr/bin/python
1
+ #!/usr/bin/python3
2
2
  # Copyright 2008 The RE2 Authors. All Rights Reserved.
3
3
  # Use of this source code is governed by a BSD-style
4
4
  # license that can be found in the LICENSE file.
@@ -611,10 +611,13 @@ void Prog::Flatten() {
611
611
  inst_count_[ip->opcode()]++;
612
612
  }
613
613
 
614
- int total = 0;
614
+ #if !defined(NDEBUG)
615
+ // Address a `-Wunused-but-set-variable' warning from Clang 13.x.
616
+ size_t total = 0;
615
617
  for (int i = 0; i < kNumInst; i++)
616
618
  total += inst_count_[i];
617
- DCHECK_EQ(total, static_cast<int>(flat.size()));
619
+ CHECK_EQ(total, flat.size());
620
+ #endif
618
621
 
619
622
  // Remap start_unanchored and start.
620
623
  if (start_unanchored() == 0) {
package/vendor/re2/re2.h CHANGED
@@ -971,7 +971,7 @@ namespace hooks {
971
971
  // As per https://github.com/google/re2/issues/325, thread_local support in
972
972
  // MinGW seems to be buggy. (FWIW, Abseil folks also avoid it.)
973
973
  #define RE2_HAVE_THREAD_LOCAL
974
- #if (defined(__APPLE__) && !TARGET_OS_OSX) || defined(__MINGW32__)
974
+ #if (defined(__APPLE__) && !(defined(TARGET_OS_OSX) && TARGET_OS_OSX)) || defined(__MINGW32__)
975
975
  #undef RE2_HAVE_THREAD_LOCAL
976
976
  #endif
977
977
 
@@ -585,8 +585,7 @@ class NamedCapturesWalker : public Regexp::Walker<Ignored> {
585
585
  // Record first occurrence of each name.
586
586
  // (The rule is that if you have the same name
587
587
  // multiple times, only the leftmost one counts.)
588
- if (map_->find(*re->name()) == map_->end())
589
- (*map_)[*re->name()] = re->cap();
588
+ map_->insert({*re->name(), re->cap()});
590
589
  }
591
590
  return ignored;
592
591
  }