diff options
Diffstat (limited to 'src/script.cpp')
-rw-r--r-- | src/script.cpp | 37 |
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); } |