@@ -329,54 +329,111 @@ std::optional<uint32_t> ConsumeTimeLock(FuzzedDataProvider& provider) {
329
329
* bytes as the number of keys define the index of each key in the test data.
330
330
* - For thresh(), the next byte defines the threshold value and the following one the number of subs.
331
331
*/
332
- std::optional<NodeInfo> ConsumeNodeStable (FuzzedDataProvider& provider) {
332
+ std::optional<NodeInfo> ConsumeNodeStable (FuzzedDataProvider& provider, Type type_needed) {
333
+ bool allow_B = (type_needed == " " _mst) || (type_needed << " B" _mst);
334
+ bool allow_K = (type_needed == " " _mst) || (type_needed << " K" _mst);
335
+ bool allow_V = (type_needed == " " _mst) || (type_needed << " V" _mst);
336
+ bool allow_W = (type_needed == " " _mst) || (type_needed << " W" _mst);
337
+
333
338
switch (provider.ConsumeIntegral <uint8_t >()) {
334
- case 0 : return {{Fragment::JUST_0}};
335
- case 1 : return {{Fragment::JUST_1}};
336
- case 2 : return {{Fragment::PK_K, ConsumePubKey (provider)}};
337
- case 3 : return {{Fragment::PK_H, ConsumePubKey (provider)}};
339
+ case 0 :
340
+ if (!allow_B) return {};
341
+ return {{Fragment::JUST_0}};
342
+ case 1 :
343
+ if (!allow_B) return {};
344
+ return {{Fragment::JUST_1}};
345
+ case 2 :
346
+ if (!allow_K) return {};
347
+ return {{Fragment::PK_K, ConsumePubKey (provider)}};
348
+ case 3 :
349
+ if (!allow_K) return {};
350
+ return {{Fragment::PK_H, ConsumePubKey (provider)}};
338
351
case 4 : {
352
+ if (!allow_B) return {};
339
353
const auto k = ConsumeTimeLock (provider);
340
354
if (!k) return {};
341
355
return {{Fragment::OLDER, *k}};
342
356
}
343
357
case 5 : {
358
+ if (!allow_B) return {};
344
359
const auto k = ConsumeTimeLock (provider);
345
360
if (!k) return {};
346
361
return {{Fragment::AFTER, *k}};
347
362
}
348
- case 6 : return {{Fragment::SHA256, ConsumeSha256 (provider)}};
349
- case 7 : return {{Fragment::HASH256, ConsumeHash256 (provider)}};
350
- case 8 : return {{Fragment::RIPEMD160, ConsumeRipemd160 (provider)}};
351
- case 9 : return {{Fragment::HASH160, ConsumeHash160 (provider)}};
363
+ case 6 :
364
+ if (!allow_B) return {};
365
+ return {{Fragment::SHA256, ConsumeSha256 (provider)}};
366
+ case 7 :
367
+ if (!allow_B) return {};
368
+ return {{Fragment::HASH256, ConsumeHash256 (provider)}};
369
+ case 8 :
370
+ if (!allow_B) return {};
371
+ return {{Fragment::RIPEMD160, ConsumeRipemd160 (provider)}};
372
+ case 9 :
373
+ if (!allow_B) return {};
374
+ return {{Fragment::HASH160, ConsumeHash160 (provider)}};
352
375
case 10 : {
376
+ if (!allow_B) return {};
353
377
const auto k = provider.ConsumeIntegral <uint8_t >();
354
378
const auto n_keys = provider.ConsumeIntegral <uint8_t >();
355
379
if (n_keys > 20 || k == 0 || k > n_keys) return {};
356
380
std::vector<CPubKey> keys{n_keys};
357
381
for (auto & key: keys) key = ConsumePubKey (provider);
358
382
return {{Fragment::MULTI, k, std::move (keys)}};
359
383
}
360
- case 11 : return {{3 , Fragment::ANDOR}};
361
- case 12 : return {{2 , Fragment::AND_V}};
362
- case 13 : return {{2 , Fragment::AND_B}};
363
- case 15 : return {{2 , Fragment::OR_B}};
364
- case 16 : return {{2 , Fragment::OR_C}};
365
- case 17 : return {{2 , Fragment::OR_D}};
366
- case 18 : return {{2 , Fragment::OR_I}};
384
+ case 11 :
385
+ if (!(allow_B || allow_K || allow_V)) return {};
386
+ return {{{" B" _mst, type_needed, type_needed}, Fragment::ANDOR}};
387
+ case 12 :
388
+ if (!(allow_B || allow_K || allow_V)) return {};
389
+ return {{{" V" _mst, type_needed}, Fragment::AND_V}};
390
+ case 13 :
391
+ if (!allow_B) return {};
392
+ return {{{" B" _mst, " W" _mst}, Fragment::AND_B}};
393
+ case 15 :
394
+ if (!allow_B) return {};
395
+ return {{{" B" _mst, " W" _mst}, Fragment::OR_B}};
396
+ case 16 :
397
+ if (!allow_V) return {};
398
+ return {{{" B" _mst, " V" _mst}, Fragment::OR_C}};
399
+ case 17 :
400
+ if (!allow_B) return {};
401
+ return {{{" B" _mst, " B" _mst}, Fragment::OR_D}};
402
+ case 18 :
403
+ if (!(allow_B || allow_K || allow_V)) return {};
404
+ return {{{type_needed, type_needed}, Fragment::OR_I}};
367
405
case 19 : {
406
+ if (!allow_B) return {};
368
407
auto k = provider.ConsumeIntegral <uint8_t >();
369
408
auto n_subs = provider.ConsumeIntegral <uint8_t >();
370
409
if (k == 0 || k > n_subs) return {};
371
- return {{n_subs, Fragment::THRESH, k}};
410
+ std::vector<Type> subtypes;
411
+ subtypes.reserve (n_subs);
412
+ subtypes.emplace_back (" B" _mst);
413
+ for (size_t i = 1 ; i < n_subs; ++i) subtypes.emplace_back (" W" _mst);
414
+ return {{std::move (subtypes), Fragment::THRESH, k}};
372
415
}
373
- case 20 : return {{1 , Fragment::WRAP_A}};
374
- case 21 : return {{1 , Fragment::WRAP_S}};
375
- case 22 : return {{1 , Fragment::WRAP_C}};
376
- case 23 : return {{1 , Fragment::WRAP_D}};
377
- case 24 : return {{1 , Fragment::WRAP_V}};
378
- case 25 : return {{1 , Fragment::WRAP_J}};
379
- case 26 : return {{1 , Fragment::WRAP_N}};
416
+ case 20 :
417
+ if (!allow_W) return {};
418
+ return {{{" B" _mst}, Fragment::WRAP_A}};
419
+ case 21 :
420
+ if (!allow_W) return {};
421
+ return {{{" B" _mst}, Fragment::WRAP_S}};
422
+ case 22 :
423
+ if (!allow_B) return {};
424
+ return {{{" K" _mst}, Fragment::WRAP_C}};
425
+ case 23 :
426
+ if (!allow_B) return {};
427
+ return {{{" V" _mst}, Fragment::WRAP_D}};
428
+ case 24 :
429
+ if (!allow_V) return {};
430
+ return {{{" B" _mst}, Fragment::WRAP_V}};
431
+ case 25 :
432
+ if (!allow_B) return {};
433
+ return {{{" B" _mst}, Fragment::WRAP_J}};
434
+ case 26 :
435
+ if (!allow_B) return {};
436
+ return {{{" B" _mst}, Fragment::WRAP_N}};
380
437
default :
381
438
break ;
382
439
}
@@ -709,7 +766,7 @@ std::optional<NodeInfo> ConsumeNodeSmart(FuzzedDataProvider& provider, Type type
709
766
* a NodeRef whose Type() matches the type fed to ConsumeNode.
710
767
*/
711
768
template <typename F>
712
- NodeRef GenNode (F ConsumeNode, Type root_type = " " _mst , bool strict_valid = false ) {
769
+ NodeRef GenNode (F ConsumeNode, Type root_type, bool strict_valid = false ) {
713
770
/* * A stack of miniscript Nodes being built up. */
714
771
std::vector<NodeRef> stack;
715
772
/* * The queue of instructions. */
@@ -921,9 +978,9 @@ void FuzzInitSmart()
921
978
FUZZ_TARGET_INIT (miniscript_stable, FuzzInit)
922
979
{
923
980
FuzzedDataProvider provider (buffer.data (), buffer.size ());
924
- TestNode (GenNode ([&](Type) {
925
- return ConsumeNodeStable (provider);
926
- }), provider);
981
+ TestNode (GenNode ([&](Type needed_type ) {
982
+ return ConsumeNodeStable (provider, needed_type );
983
+ }, " " _mst ), provider);
927
984
}
928
985
929
986
/* * Fuzz target that runs TestNode on nodes generated using ConsumeNodeSmart. */
0 commit comments