File tree Expand file tree Collapse file tree 4 files changed +53
-1
lines changed Expand file tree Collapse file tree 4 files changed +53
-1
lines changed Original file line number Diff line number Diff line change @@ -442,6 +442,10 @@ bool IsStandardTx(const CTransaction& tx, string& reason)
442
442
reason = " scriptsig-not-pushonly" ;
443
443
return false ;
444
444
}
445
+ if (!txin.scriptSig .HasCanonicalPushes ()) {
446
+ reason = " non-canonical-push" ;
447
+ return false ;
448
+ }
445
449
}
446
450
447
451
unsigned int nDataOut = 0 ;
Original file line number Diff line number Diff line change @@ -1881,6 +1881,33 @@ bool CScript::IsPushOnly() const
1881
1881
return true ;
1882
1882
}
1883
1883
1884
+ bool CScript::HasCanonicalPushes () const
1885
+ {
1886
+ const_iterator pc = begin ();
1887
+ while (pc < end ())
1888
+ {
1889
+ opcodetype opcode;
1890
+ std::vector<unsigned char > data;
1891
+ if (!GetOp (pc, opcode, data))
1892
+ return false ;
1893
+ if (opcode > OP_16)
1894
+ continue ;
1895
+ if (opcode < OP_PUSHDATA1 && opcode > OP_0 && (data.size () == 1 && data[0 ] <= 16 ))
1896
+ // Could have used an OP_n code, rather than a 1-byte push.
1897
+ return false ;
1898
+ if (opcode == OP_PUSHDATA1 && data.size () < OP_PUSHDATA1)
1899
+ // Could have used a normal n-byte push, rather than OP_PUSHDATA1.
1900
+ return false ;
1901
+ if (opcode == OP_PUSHDATA2 && data.size () <= 0xFF )
1902
+ // Could have used an OP_PUSHDATA1.
1903
+ return false ;
1904
+ if (opcode == OP_PUSHDATA4 && data.size () <= 0xFFFF )
1905
+ // Could have used an OP_PUSHDATA2.
1906
+ return false ;
1907
+ }
1908
+ return true ;
1909
+ }
1910
+
1884
1911
class CScriptVisitor : public boost ::static_visitor<bool >
1885
1912
{
1886
1913
private:
Original file line number Diff line number Diff line change @@ -541,9 +541,12 @@ class CScript : public std::vector<unsigned char>
541
541
542
542
bool IsPayToScriptHash () const ;
543
543
544
- // Called by IsStandardTx
544
+ // Called by IsStandardTx and P2SH VerifyScript (which makes it consensus-critical).
545
545
bool IsPushOnly () const ;
546
546
547
+ // Called by IsStandardTx.
548
+ bool HasCanonicalPushes () const ;
549
+
547
550
// Returns whether the script is guaranteed to fail at execution,
548
551
// regardless of the initial stack. This allows outputs to be pruned
549
552
// instantly when entering the UTXO set.
Original file line number Diff line number Diff line change @@ -438,4 +438,22 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
438
438
BOOST_CHECK (combined == partial3c);
439
439
}
440
440
441
+ BOOST_AUTO_TEST_CASE (script_standard_push)
442
+ {
443
+ for (int i=0 ; i<1000 ; i++) {
444
+ CScript script;
445
+ script << i;
446
+ BOOST_CHECK_MESSAGE (script.IsPushOnly (), " Number " << i << " is not pure push." );
447
+ BOOST_CHECK_MESSAGE (script.HasCanonicalPushes (), " Number " << i << " push is not canonical." );
448
+ }
449
+
450
+ for (int i=0 ; i<1000 ; i++) {
451
+ std::vector<unsigned char > data (i, ' \111 ' );
452
+ CScript script;
453
+ script << data;
454
+ BOOST_CHECK_MESSAGE (script.IsPushOnly (), " Length " << i << " is not pure push." );
455
+ BOOST_CHECK_MESSAGE (script.HasCanonicalPushes (), " Length " << i << " push is not canonical." );
456
+ }
457
+ }
458
+
441
459
BOOST_AUTO_TEST_SUITE_END ()
You can’t perform that action at this time.
0 commit comments