diff --git a/core/src/main/java/com/google/bitcoin/script/ScriptBuilder.java b/core/src/main/java/com/google/bitcoin/script/ScriptBuilder.java index ffac76bd..08b1d1c8 100644 --- a/core/src/main/java/com/google/bitcoin/script/ScriptBuilder.java +++ b/core/src/main/java/com/google/bitcoin/script/ScriptBuilder.java @@ -203,7 +203,8 @@ public class ScriptBuilder { /** * Returns a copy of the given scriptSig with the signature inserted in the given position. * - * This function assumes that any missing sigs have OP_0 placeholders. + * This function assumes that any missing sigs have OP_0 placeholders. If given scriptSig already has all the signatures + * in place, IllegalArgumentException will be thrown. * * @param targetIndex where to insert the signature * @param sigsPrefixCount how many items to copy verbatim (e.g. initial OP_0 for multisig) @@ -215,6 +216,12 @@ public class ScriptBuilder { List inputChunks = scriptSig.getChunks(); int totalChunks = inputChunks.size(); + // Check if we have a place to insert, otherwise just return given scriptSig unchanged. + // We assume here that OP_0 placeholders always go after the sigs, so + // to find if we have sigs missing, we can just check the chunk in latest sig position + boolean hasMissingSigs = inputChunks.get(totalChunks - sigsSuffixCount - 1).equalsOpCode(OP_0); + checkArgument(hasMissingSigs, "ScriptSig is already filled with signatures"); + // copy the prefix for (ScriptChunk chunk: inputChunks.subList(0, sigsPrefixCount)) builder.addChunk(chunk); diff --git a/core/src/test/java/com/google/bitcoin/script/ScriptTest.java b/core/src/test/java/com/google/bitcoin/script/ScriptTest.java index f15f48a8..36e79f79 100644 --- a/core/src/test/java/com/google/bitcoin/script/ScriptTest.java +++ b/core/src/test/java/com/google/bitcoin/script/ScriptTest.java @@ -153,7 +153,7 @@ public class ScriptTest { } @Test - public void testCreateEmptyInputScript() throws Exception { + public void createAndUpdateEmptyInputScript() throws Exception { TransactionSignature dummySig = TransactionSignature.dummy(); ECKey key = new ECKey(); @@ -196,6 +196,14 @@ public class ScriptTest { assertThat(inputScript.getChunks().get(1).data, equalTo(dummySig.encodeToBitcoin())); assertThat(inputScript.getChunks().get(2).data, equalTo(dummySig.encodeToBitcoin())); assertThat(inputScript.getChunks().get(3).data, equalTo(multisigScript.getProgram())); + + // updating scriptSig with no missing signatures + try { + ScriptBuilder.updateScriptWithSignature(inputScript, dummySig.encodeToBitcoin(), 1, 1, 1); + fail("Exception expected"); + } catch (Exception e) { + assertEquals(IllegalArgumentException.class, e.getClass()); + } } private Script parseScriptString(String string) throws IOException {