test: add script_tests cases covering interpreter mutants #36291

pull ViniciusCestarii wants to merge 6 commits into bitcoin:master from ViniciusCestarii:kill-interpreter-mutants changing 1 files +15 −0
  1. ViniciusCestarii commented at 7:37 PM on September 17, 2026: contributor

    Kills some live mutants on interpreter.cpp found by https://bitcoincore.space. They are:

    <details> <summary><a href="https://bitcoincore.space/src/script/interpreter.cpp#5168">interpreter.cpp#5168</a>: <code>IsCompressedOrUncompressedPubKey</code>: pubkey with neither compressed nor uncompressed prefix returns <code>true</code></summary>

    diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
    index 98b16eca6b..a9dd379a3d 100644
    --- a/src/script/interpreter.cpp
    +++ b/src/script/interpreter.cpp
    @@ -81,7 +81,7 @@ bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {
                 //  Non-canonical public key: invalid length for uncompressed key
                 return false;
             }
    -    } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) {
    +    } else if (1==1) {
             if (vchPubKey.size() != CPubKey::COMPRESSED_SIZE) {
                 //  Non-canonical public key: invalid length for compressed key
                 return false;
    

    </details>

    <details> <summary><a href="https://bitcoincore.space/src/script/interpreter.cpp#5191">interpreter.cpp#5191</a>: <code>IsValidSignatureEncoding</code>: 73-byte upper bound returns <code>true</code></summary>

    diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
    index 98b16eca6b..58d275b139 100644
    --- a/src/script/interpreter.cpp
    +++ b/src/script/interpreter.cpp
    @@ -130,7 +130,7 @@ bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
     
         // Minimum and maximum size constraints.
         if (sig.size() < 9) return false;
    -    if (sig.size() > 73) return false;
    +
     
         // A signature is of type 0x30 (compound).
         if (sig[0] != 0x30) return false;
    

    </details>

    <details> <summary><a href="https://bitcoincore.space/src/script/interpreter.cpp#5200">interpreter.cpp#5200</a>: <code>IsValidSignatureEncoding</code>: total-length byte check returns <code>true</code></summary>

    diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
    index 98b16eca6b..b2d3e0677f 100644
    --- a/src/script/interpreter.cpp
    +++ b/src/script/interpreter.cpp
    @@ -136,7 +136,7 @@ bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
         if (sig[0] != 0x30) return false;
     
         // Make sure the length covers the entire signature.
    -    if (sig[1] != sig.size() - 3) return false;
    +
     
         // Extract the length of the R element.
         unsigned int lenR = sig[3];
    

    </details>

    <details> <summary><a href="https://bitcoincore.space/src/script/interpreter.cpp#5232">interpreter.cpp#5232</a>: <code>IsValidSignatureEncoding</code>: null R byte check <code>lenR > 1</code> -> <code>lenR >=1</code></summary>

    diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
    index 98b16eca6b..0170ffe487 100644
    --- a/src/script/interpreter.cpp
    +++ b/src/script/interpreter.cpp
    @@ -162,7 +162,7 @@ bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
     
         // Null bytes at the start of R are not allowed, unless R would
         // otherwise be interpreted as a negative number.
    -    if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false;
    +    if (lenR >= 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false;
     
         // Check whether the S element is an integer.
         if (sig[lenR + 4] != 0x02) return false;
    

    </details>

    <details> <summary><a href="https://bitcoincore.space/src/script/interpreter.cpp#5259">interpreter.cpp#5259</a>: <code>IsValidSignatureEncoding</code>: null S byte check <code>lenS > 1</code> -> <code>lenS >= 1</code></summary>

    diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
    index 98b16eca6b..e85e8dc85b 100644
    --- a/src/script/interpreter.cpp
    +++ b/src/script/interpreter.cpp
    @@ -175,7 +175,7 @@ bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
     
         // Null bytes at the start of S are not allowed, unless S would otherwise be
         // interpreted as a negative number.
    -    if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false;
    +    if (lenS >= 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false;
     
         return true;
     }
    

    </details>

    <details> <summary><a href="https://bitcoincore.space/src/script/interpreter.cpp#5186">interpreter.cpp#5186</a>: <code>IsValidSignatureEncoding</code>: 9-byte lower bound returns <code>true</code></summary>

    diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
    index 98b16eca6b..52f31306e8 100644
    --- a/src/script/interpreter.cpp
    +++ b/src/script/interpreter.cpp
    @@ -129,7 +129,7 @@ bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
         //   signature)
     
         // Minimum and maximum size constraints.
    -    if (sig.size() < 9) return false;
    +
         if (sig.size() > 73) return false;
     
         // A signature is of type 0x30 (compound).
    

    </details>

    The first affects policy only, the next four affect consensus, and the last covers the lower bound and lets ASan catch UB: a 3-byte signature reaches the sig[3] read that the sig.size() < 9 guard protects.

    Recommend reviewing per commit.

  2. test: cover STRICTENC rejects bad 33-byte pubkey prefix
    https://bitcoincore.space/src/script/interpreter.cpp#5168
    cb2a804837
  3. test: cover DERSIG 73-byte signature upper bound
    https://bitcoincore.space/src/script/interpreter.cpp#5191
    318ed1fd4d
  4. test: cover DERSIG total-length byte check
    https://bitcoincore.space/src/script/interpreter.cpp#5200
    3721f787f3
  5. test: cover DERSIG null R byte only when R is multi-byte
    https://bitcoincore.space/src/script/interpreter.cpp#5232
    7ea49187f7
  6. test: cover DERSIG null S byte only when S is multi-byte
    https://bitcoincore.space/src/script/interpreter.cpp#5259
    4d07d244f4
  7. test: cover DERSIG 9-byte signature lower bound
    https://bitcoincore.space/src/script/interpreter.cpp#5186
    
    Mirrors the 74-byte upper bound test. The 3-byte case reaches the sig[3] read the size guard protects, so ASan can catch the guard being weakened.
    d34cd78bd5
  8. DrahtBot added the label Tests on Sep 17, 2026
  9. DrahtBot commented at 7:37 PM on September 17, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/36291.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process. A summary of reviews will appear here.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  10. ViniciusCestarii renamed this:
    test: add script_tests cases covering interpreter mutants Tests
    test: add script_tests cases covering interpreter mutants
    on Sep 21, 2026
Labels

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-09-23 13:51 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me