Skip to content

Commit 4e19882

Browse files
authored
Merge pull request #3 from starius/fix-panic
Fix `NewScriptPubkey()` panic on empty scriptPubKey
2 parents 680aa68 + 3315ec3 commit 4e19882

File tree

2 files changed

+48
-18
lines changed

2 files changed

+48
-18
lines changed

kernel/script_pubkey.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ func newScriptPubkey(ptr *C.btck_ScriptPubkey, fromOwned bool) *ScriptPubkey {
3535
// Parameters:
3636
// - rawScriptPubkey: Serialized script pubkey data
3737
func NewScriptPubkey(rawScriptPubkey []byte) *ScriptPubkey {
38-
ptr := C.btck_script_pubkey_create(unsafe.Pointer(&rawScriptPubkey[0]), C.size_t(len(rawScriptPubkey)))
38+
var buf unsafe.Pointer
39+
if len(rawScriptPubkey) > 0 {
40+
buf = unsafe.Pointer(&rawScriptPubkey[0])
41+
}
42+
ptr := C.btck_script_pubkey_create(buf, C.size_t(len(rawScriptPubkey)))
3943
return newScriptPubkey(check(ptr), true)
4044
}
4145

kernel/script_pubkey_test.go

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,44 @@ import (
77
)
88

99
func TestScriptPubkeyFromRaw(t *testing.T) {
10-
scriptHex := "76a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe26158088ac"
11-
scriptBytes, err := hex.DecodeString(scriptHex)
12-
if err != nil {
13-
t.Fatalf("Failed to decode script hex: %v", err)
10+
tests := []struct {
11+
name string
12+
scriptHex string
13+
}{
14+
{
15+
name: "standard_p2pkh",
16+
scriptHex: "76a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe26158088ac",
17+
},
18+
{
19+
name: "empty_script",
20+
scriptHex: "",
21+
},
1422
}
1523

16-
scriptPubkey := NewScriptPubkey(scriptBytes)
17-
defer scriptPubkey.Destroy()
24+
for _, tt := range tests {
25+
t.Run(tt.name, func(t *testing.T) {
26+
scriptBytes, err := hex.DecodeString(tt.scriptHex)
27+
if err != nil {
28+
t.Fatalf("Failed to decode script hex: %v", err)
29+
}
1830

19-
// Test getting the serialized script pubkey
20-
data, err := scriptPubkey.Bytes()
21-
if err != nil {
22-
t.Fatalf("ScriptPubkey.Bytes() error = %v", err)
23-
}
31+
scriptPubkey := NewScriptPubkey(scriptBytes)
32+
defer scriptPubkey.Destroy()
2433

25-
if len(data) != len(scriptBytes) {
26-
t.Errorf("Expected data length %d, got %d", len(scriptBytes), len(data))
27-
}
34+
data, err := scriptPubkey.Bytes()
35+
if err != nil {
36+
t.Fatalf("ScriptPubkey.Bytes() error = %v", err)
37+
}
2838

29-
hexStr := hex.EncodeToString(data)
30-
if hexStr != scriptHex {
31-
t.Errorf("Expected data hex: %s, got %s", scriptHex, hexStr)
39+
if len(data) != len(scriptBytes) {
40+
t.Errorf("Expected data length %d, got %d", len(scriptBytes), len(data))
41+
}
42+
43+
hexStr := hex.EncodeToString(data)
44+
if hexStr != tt.scriptHex {
45+
t.Errorf("Expected data hex: %s, got %s", tt.scriptHex, hexStr)
46+
}
47+
})
3248
}
3349
}
3450

@@ -173,6 +189,16 @@ func TestInvalidScripts(t *testing.T) {
173189
inputIndex: 0,
174190
description: "a random segwit transaction from the blockchain using native segwit - WITH WRONG SEGWIT",
175191
},
192+
{
193+
name: "empty_scriptpubkey",
194+
scriptPubkeyHex: "",
195+
amount: 0,
196+
// Minimal coinbase-style transaction with a single empty scriptSig and zero-value output;
197+
// used to trigger verification paths.
198+
txToHex: "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff0100000000000000000000000000",
199+
inputIndex: 0,
200+
description: "empty scriptPubkey should fail verification",
201+
},
176202
}
177203

178204
for _, tt := range tests {

0 commit comments

Comments
 (0)