@@ -425,4 +425,121 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
425425 BOOST_CHECK (combined == partial3c);
426426}
427427
428+ static CScript
429+ ScriptFromHex (const char * hex)
430+ {
431+ std::vector<unsigned char > data = ParseHex (hex);
432+ return CScript (data.begin (), data.end ());
433+ }
434+
435+
436+ BOOST_AUTO_TEST_CASE (script_FindAndDelete)
437+ {
438+ // Exercise the FindAndDelete functionality
439+ CScript s;
440+ CScript d;
441+ CScript expect;
442+
443+ s = CScript () << OP_1 << OP_2;
444+ d = CScript (); // delete nothing should be a no-op
445+ expect = s;
446+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 0 );
447+ BOOST_CHECK (s == expect);
448+
449+ s = CScript () << OP_1 << OP_2 << OP_3;
450+ d = CScript () << OP_2;
451+ expect = CScript () << OP_1 << OP_3;
452+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 1 );
453+ BOOST_CHECK (s == expect);
454+
455+ s = CScript () << OP_3 << OP_1 << OP_3 << OP_3 << OP_4 << OP_3;
456+ d = CScript () << OP_3;
457+ expect = CScript () << OP_1 << OP_4;
458+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 4 );
459+ BOOST_CHECK (s == expect);
460+
461+ s = ScriptFromHex (" 0302ff03" ); // PUSH 0x02ff03 onto stack
462+ d = ScriptFromHex (" 0302ff03" );
463+ expect = CScript ();
464+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 1 );
465+ BOOST_CHECK (s == expect);
466+
467+ s = ScriptFromHex (" 0302ff030302ff03" ); // PUSH 0x2ff03 PUSH 0x2ff03
468+ d = ScriptFromHex (" 0302ff03" );
469+ expect = CScript ();
470+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 2 );
471+ BOOST_CHECK (s == expect);
472+
473+ s = ScriptFromHex (" 0302ff030302ff03" );
474+ d = ScriptFromHex (" 02" );
475+ expect = s; // FindAndDelete matches entire opcodes
476+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 0 );
477+ BOOST_CHECK (s == expect);
478+
479+ s = ScriptFromHex (" 0302ff030302ff03" );
480+ d = ScriptFromHex (" ff" );
481+ expect = s;
482+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 0 );
483+ BOOST_CHECK (s == expect);
484+
485+ // This is an odd edge case: strip of the push-three-bytes
486+ // prefix, leaving 02ff03 which is push-two-bytes:
487+ s = ScriptFromHex (" 0302ff030302ff03" );
488+ d = ScriptFromHex (" 03" );
489+ expect = CScript () << ParseHex (" ff03" ) << ParseHex (" ff03" );
490+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 2 );
491+ BOOST_CHECK (s == expect);
492+
493+ // Byte sequence that spans multiple opcodes:
494+ s = ScriptFromHex (" 02feed5169" ); // PUSH(0xfeed) OP_1 OP_VERIFY
495+ d = ScriptFromHex (" feed51" );
496+ expect = s;
497+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 0 ); // doesn't match 'inside' opcodes
498+ BOOST_CHECK (s == expect);
499+
500+ s = ScriptFromHex (" 02feed5169" ); // PUSH(0xfeed) OP_1 OP_VERIFY
501+ d = ScriptFromHex (" 02feed51" );
502+ expect = ScriptFromHex (" 69" );
503+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 1 );
504+ BOOST_CHECK (s == expect);
505+
506+ s = ScriptFromHex (" 516902feed5169" );
507+ d = ScriptFromHex (" feed51" );
508+ expect = s;
509+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 0 );
510+ BOOST_CHECK (s == expect);
511+
512+ s = ScriptFromHex (" 516902feed5169" );
513+ d = ScriptFromHex (" 02feed51" );
514+ expect = ScriptFromHex (" 516969" );
515+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 1 );
516+ BOOST_CHECK (s == expect);
517+
518+ s = CScript () << OP_0 << OP_0 << OP_1 << OP_1;
519+ d = CScript () << OP_0 << OP_1;
520+ expect = CScript () << OP_0 << OP_1; // FindAndDelete is single-pass
521+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 1 );
522+ BOOST_CHECK (s == expect);
523+
524+ s = CScript () << OP_0 << OP_0 << OP_1 << OP_0 << OP_1 << OP_1;
525+ d = CScript () << OP_0 << OP_1;
526+ expect = CScript () << OP_0 << OP_1; // FindAndDelete is single-pass
527+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 2 );
528+ BOOST_CHECK (s == expect);
529+
530+ // Another weird edge case:
531+ // End with invalid push (not enough data)...
532+ s = ScriptFromHex (" 0003feed" );
533+ d = ScriptFromHex (" 03feed" ); // ... can remove the invalid push
534+ expect = ScriptFromHex (" 00" );
535+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 1 );
536+ BOOST_CHECK (s == expect);
537+
538+ s = ScriptFromHex (" 0003feed" );
539+ d = ScriptFromHex (" 00" );
540+ expect = ScriptFromHex (" 03feed" );
541+ BOOST_CHECK_EQUAL (s.FindAndDelete (d), 1 );
542+ BOOST_CHECK (s == expect);
543+ }
544+
428545BOOST_AUTO_TEST_SUITE_END ()
0 commit comments