From 79752a8880bf03e330bc1f2def93a29fc645cf54 Mon Sep 17 00:00:00 2001 From: Calvin Kim Date: Sat, 30 May 2026 13:53:12 +0900 Subject: [PATCH] btcjson: accept null in StringOrArray.UnmarshalJSON StringOrArray.MarshalJSON emits JSON null for a nil slice (see existing test "nil slice marshals as null" in TestStringOrArrayMarshalJSON), but UnmarshalJSON did not have a matching case for null and fell to the default branch, returning "invalid string_or_array value: ". A round trip of a nil slice therefore failed. This bit the rpcclient against btcd's own getblockchaininfo, whose Warnings field is a StringOrArray that the server leaves as a nil slice when there are no warnings. Every rpctest integration test that touches GetBlockChainInfo (TestBIP0009, TestBIP0068AndBIP0112Activation, TestBIP0113Activation, TestPrune) failed to decode the response. Handle the nil case explicitly so null decodes back to a nil slice, and add regression cases for "warnings: null" and an omitted warnings field to TestGetBlockChainInfoWarnings. --- btcjson/chainsvrresults.go | 3 +++ btcjson/chainsvrresults_test.go | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 3ee2b8b6..5cd1e907 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -385,6 +385,9 @@ func (h *StringOrArray) UnmarshalJSON(data []byte) error { } switch v := unmarshalled.(type) { + case nil: + *h = nil + case string: *h = []string{v} diff --git a/btcjson/chainsvrresults_test.go b/btcjson/chainsvrresults_test.go index fb681a9c..f37adb4b 100644 --- a/btcjson/chainsvrresults_test.go +++ b/btcjson/chainsvrresults_test.go @@ -350,6 +350,16 @@ func TestGetBlockChainInfoWarnings(t *testing.T) { result: `{"warnings": []}`, expected: btcjson.StringOrArray{}, }, + { + name: "blockchain info with null warnings", + result: `{"warnings": null}`, + expected: nil, + }, + { + name: "blockchain info with warnings field omitted", + result: `{}`, + expected: nil, + }, } for _, test := range tests {