aboutsummaryrefslogtreecommitdiff
path: root/src/script.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script.cpp')
-rw-r--r--src/script.cpp37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/script.cpp b/src/script.cpp
index c29648c2bc..4357a9a1b3 100644
--- a/src/script.cpp
+++ b/src/script.cpp
@@ -54,12 +54,29 @@ bool CastToBool(const valtype& vch)
return false;
}
+//
+// WARNING: This does not work as expected for signed integers; the sign-bit
+// is left in place as the integer is zero-extended. The correct behavior
+// would be to move the most significant bit of the last byte during the
+// resize process. MakeSameSize() is currently only used by the disabled
+// opcodes OP_AND, OP_OR, and OP_XOR.
+//
void MakeSameSize(valtype& vch1, valtype& vch2)
{
// Lengthen the shorter one
if (vch1.size() < vch2.size())
+ // PATCH:
+ // +unsigned char msb = vch1[vch1.size()-1];
+ // +vch1[vch1.size()-1] &= 0x7f;
+ // vch1.resize(vch2.size(), 0);
+ // +vch1[vch1.size()-1] = msb;
vch1.resize(vch2.size(), 0);
if (vch2.size() < vch1.size())
+ // PATCH:
+ // +unsigned char msb = vch2[vch2.size()-1];
+ // +vch2[vch2.size()-1] &= 0x7f;
+ // vch2.resize(vch1.size(), 0);
+ // +vch2[vch2.size()-1] = msb;
vch2.resize(vch1.size(), 0);
}
@@ -663,6 +680,11 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
}
break;
+ //
+ // WARNING: These disabled opcodes exhibit unexpected behavior
+ // when used on signed integers due to a bug in MakeSameSize()
+ // [see definition of MakeSameSize() above].
+ //
case OP_AND:
case OP_OR:
case OP_XOR:
@@ -672,7 +694,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
return false;
valtype& vch1 = stacktop(-2);
valtype& vch2 = stacktop(-1);
- MakeSameSize(vch1, vch2);
+ MakeSameSize(vch1, vch2); // <-- NOT SAFE FOR SIGNED VALUES
if (opcode == OP_AND)
{
for (unsigned int i = 0; i < vch1.size(); i++)
@@ -1070,7 +1092,7 @@ uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int
}
else if ((nHashType & 0x1f) == SIGHASH_SINGLE)
{
- // Only lockin the txout payee at same index as txin
+ // Only lock-in the txout payee at same index as txin
unsigned int nOut = nIn;
if (nOut >= txTmp.vout.size())
{
@@ -1127,8 +1149,7 @@ public:
return false;
}
- void
- Set(uint256 hash, const std::vector<unsigned char>& vchSig, const std::vector<unsigned char>& pubKey)
+ void Set(uint256 hash, const std::vector<unsigned char>& vchSig, const std::vector<unsigned char>& pubKey)
{
// DoS prevention: limit cache size to less than 10MB
// (~200 bytes per cache entry times 50,000 entries)
@@ -1272,7 +1293,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
if (!script2.GetOp(pc2, opcode2, vch2))
break;
// Normal situation is to fall through
- // to other if/else statments
+ // to other if/else statements
}
if (opcode2 == OP_PUBKEY)
@@ -1345,7 +1366,7 @@ bool SignN(const vector<valtype>& multisigdata, const CKeyStore& keystore, uint2
// Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type.
// Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
// unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
-// Returns false if scriptPubKey could not be completely satisified.
+// Returns false if scriptPubKey could not be completely satisfied.
//
bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType,
CScript& scriptSigRet, txnouttype& whichTypeRet)
@@ -1733,7 +1754,7 @@ static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo,
return PushAll(sigs1);
else
{
- // Recurse to combine:
+ // Recur to combine:
valtype spk = sigs1.back();
CScript pubKey2(spk.begin(), spk.end());
@@ -1811,7 +1832,7 @@ unsigned int CScript::GetSigOpCount(const CScript& scriptSig) const
return 0;
}
- /// ... and return it's opcount:
+ /// ... and return its opcount:
CScript subscript(data.begin(), data.end());
return subscript.GetSigOpCount(true);
}