diff --git a/src/script/script.h b/src/script/script.h index e97967dce..05f2e7e3a 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -197,8 +197,23 @@ public: if (vch.size() > nMaxNumSize) { throw scriptnum_error("script number overflow"); } - if (fRequireMinimal && vch.size() > 0 && (vch.back() & 0x7f) == 0 && (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0)) { - throw scriptnum_error("non-minimally encoded script number"); + if (fRequireMinimal && vch.size() > 0) { + // Check that the number is encoded with the minimum possible + // number of bytes. + // + // If the most-significant-byte - excluding the sign bit - is zero + // then we're not minimal. Note how this test also rejects the + // negative-zero encoding, 0x80. + if ((vch.back() & 0x7f) == 0) { + // One exception: if there's more than one byte and the most + // significant bit of the second-most-significant-byte is set + // it would conflict with the sign bit. An example of this case + // is +-255, which encode to 0xff00 and 0xff80 respectively. + // (big-endian). + if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0) { + throw scriptnum_error("non-minimally encoded script number"); + } + } } m_value = set_vch(vch); }