@@ -157,6 +157,29 @@ bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags) {
157
157
return true ;
158
158
}
159
159
160
+ bool static CheckMinimalPush (const valtype& data, opcodetype opcode) {
161
+ if (data.size () == 0 ) {
162
+ // Could have used OP_0.
163
+ return opcode == OP_0;
164
+ } else if (data.size () == 1 && data[0 ] >= 1 && data[0 ] <= 16 ) {
165
+ // Could have used OP_1 .. OP_16.
166
+ return opcode == OP_1 + (data[0 ] - 1 );
167
+ } else if (data.size () == 1 && data[0 ] == 0x81 ) {
168
+ // Could have used OP_1NEGATE.
169
+ return opcode == OP_1NEGATE;
170
+ } else if (data.size () <= 75 ) {
171
+ // Could have used a direct push (opcode indicating number of bytes pushed + those bytes).
172
+ return opcode == data.size ();
173
+ } else if (data.size () <= 255 ) {
174
+ // Could have used OP_PUSHDATA.
175
+ return opcode == OP_PUSHDATA1;
176
+ } else if (data.size () <= 65535 ) {
177
+ // Could have used OP_PUSHDATA2.
178
+ return opcode == OP_PUSHDATA2;
179
+ }
180
+ return true ;
181
+ }
182
+
160
183
bool EvalScript (vector<vector<unsigned char > >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker)
161
184
{
162
185
CScript::const_iterator pc = script.begin ();
@@ -169,6 +192,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
169
192
if (script.size () > 10000 )
170
193
return false ;
171
194
int nOpCount = 0 ;
195
+ bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0 ;
172
196
173
197
try
174
198
{
@@ -205,9 +229,12 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
205
229
opcode == OP_RSHIFT)
206
230
return false ; // Disabled opcodes.
207
231
208
- if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4)
232
+ if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) {
233
+ if (fRequireMinimal && !CheckMinimalPush (vchPushValue, opcode)) {
234
+ return false ;
235
+ }
209
236
stack.push_back (vchPushValue);
210
- else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
237
+ } else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
211
238
switch (opcode)
212
239
{
213
240
//
@@ -234,6 +261,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
234
261
// ( -- value)
235
262
CScriptNum bn ((int )opcode - (int )(OP_1 - 1 ));
236
263
stack.push_back (bn.getvch ());
264
+ // The result of these opcodes should always be the minimal way to push the data
265
+ // they push, so no need for a CheckMinimalPush here.
237
266
}
238
267
break ;
239
268
@@ -458,7 +487,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
458
487
// (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
459
488
if (stack.size () < 2 )
460
489
return false ;
461
- int n = CScriptNum (stacktop (-1 )).getint ();
490
+ int n = CScriptNum (stacktop (-1 ), fRequireMinimal ).getint ();
462
491
popstack (stack);
463
492
if (n < 0 || n >= (int )stack.size ())
464
493
return false ;
@@ -557,7 +586,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
557
586
// (in -- out)
558
587
if (stack.size () < 1 )
559
588
return false ;
560
- CScriptNum bn (stacktop (-1 ));
589
+ CScriptNum bn (stacktop (-1 ), fRequireMinimal );
561
590
switch (opcode)
562
591
{
563
592
case OP_1ADD: bn += bnOne; break ;
@@ -590,8 +619,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
590
619
// (x1 x2 -- out)
591
620
if (stack.size () < 2 )
592
621
return false ;
593
- CScriptNum bn1 (stacktop (-2 ));
594
- CScriptNum bn2 (stacktop (-1 ));
622
+ CScriptNum bn1 (stacktop (-2 ), fRequireMinimal );
623
+ CScriptNum bn2 (stacktop (-1 ), fRequireMinimal );
595
624
CScriptNum bn (0 );
596
625
switch (opcode)
597
626
{
@@ -635,9 +664,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
635
664
// (x min max -- out)
636
665
if (stack.size () < 3 )
637
666
return false ;
638
- CScriptNum bn1 (stacktop (-3 ));
639
- CScriptNum bn2 (stacktop (-2 ));
640
- CScriptNum bn3 (stacktop (-1 ));
667
+ CScriptNum bn1 (stacktop (-3 ), fRequireMinimal );
668
+ CScriptNum bn2 (stacktop (-2 ), fRequireMinimal );
669
+ CScriptNum bn3 (stacktop (-1 ), fRequireMinimal );
641
670
bool fValue = (bn2 <= bn1 && bn1 < bn3);
642
671
popstack (stack);
643
672
popstack (stack);
@@ -727,7 +756,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
727
756
if ((int )stack.size () < i)
728
757
return false ;
729
758
730
- int nKeysCount = CScriptNum (stacktop (-i)).getint ();
759
+ int nKeysCount = CScriptNum (stacktop (-i), fRequireMinimal ).getint ();
731
760
if (nKeysCount < 0 || nKeysCount > 20 )
732
761
return false ;
733
762
nOpCount += nKeysCount;
@@ -738,7 +767,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
738
767
if ((int )stack.size () < i)
739
768
return false ;
740
769
741
- int nSigsCount = CScriptNum (stacktop (-i)).getint ();
770
+ int nSigsCount = CScriptNum (stacktop (-i), fRequireMinimal ).getint ();
742
771
if (nSigsCount < 0 || nSigsCount > nKeysCount)
743
772
return false ;
744
773
int isig = ++i;
@@ -980,6 +1009,10 @@ bool SignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vec
980
1009
981
1010
bool VerifyScript (const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker)
982
1011
{
1012
+ if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly ()) {
1013
+ return false ;
1014
+ }
1015
+
983
1016
vector<vector<unsigned char > > stack, stackCopy;
984
1017
if (!EvalScript (stack, scriptSig, flags, checker))
985
1018
return false ;
0 commit comments