Fix assignment to nil map.
Ensure that Tickets loaded from the database are returned with empty maps instead of nil maps. To be back-ported to 1.1.0 release.
This commit is contained in:
parent
9fa1012f3d
commit
aac96f8c9d
28
database/helpers.go
Normal file
28
database/helpers.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (c) 2022 The Decred developers
|
||||||
|
// Use of this source code is governed by an ISC
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
func bytesToStringMap(bytes []byte) (map[string]string, error) {
|
||||||
|
if bytes == nil {
|
||||||
|
return make(map[string]string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var stringMap map[string]string
|
||||||
|
err := json.Unmarshal(bytes, &stringMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// stringMap can still be nil here, eg. if bytes == "null".
|
||||||
|
if stringMap == nil {
|
||||||
|
stringMap = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringMap, nil
|
||||||
|
}
|
||||||
78
database/helpers_test.go
Normal file
78
database/helpers_test.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Copyright (c) 2022 The Decred developers
|
||||||
|
// Use of this source code is governed by an ISC
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBytesToStringMap(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var tests = []struct {
|
||||||
|
name string
|
||||||
|
input []byte
|
||||||
|
expect map[string]string
|
||||||
|
expectErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Empty map on nil bytes",
|
||||||
|
input: nil,
|
||||||
|
expect: map[string]string{},
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty map on empty json map",
|
||||||
|
input: []byte("{}"),
|
||||||
|
expect: map[string]string{},
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty map on null",
|
||||||
|
input: []byte("null"),
|
||||||
|
expect: map[string]string{},
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Correct values with valid json",
|
||||||
|
input: []byte("{\"key\":\"value\"}"),
|
||||||
|
expect: map[string]string{"key": "value"},
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Error on no bytes",
|
||||||
|
input: []byte(""),
|
||||||
|
expect: nil,
|
||||||
|
expectErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Error on invalid json",
|
||||||
|
input: []byte("invalid json"),
|
||||||
|
expect: nil,
|
||||||
|
expectErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Error on non-map json",
|
||||||
|
input: []byte("[\"not a map\"]"),
|
||||||
|
expect: nil,
|
||||||
|
expectErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
result, err := bytesToStringMap(test.input)
|
||||||
|
if !reflect.DeepEqual(test.expect, result) {
|
||||||
|
t.Fatalf("expected %v, got %v", test.expect, result)
|
||||||
|
}
|
||||||
|
if test.expectErr != (err != nil) {
|
||||||
|
t.Fatalf("expected err=%t, got %v", test.expectErr, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -223,29 +223,19 @@ func getTicketFromBkt(bkt *bolt.Bucket) (Ticket, error) {
|
|||||||
ticket.Confirmed = bytesToBool(bkt.Get(confirmedK))
|
ticket.Confirmed = bytesToBool(bkt.Get(confirmedK))
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
ticket.VoteChoices, err = bytesToStringMap(bkt.Get(voteChoicesK))
|
||||||
voteChoicesB := bkt.Get(voteChoicesK)
|
if err != nil {
|
||||||
if voteChoicesB != nil {
|
return ticket, fmt.Errorf("unmarshal VoteChoices err: %w", err)
|
||||||
err = json.Unmarshal(voteChoicesB, &ticket.VoteChoices)
|
|
||||||
if err != nil {
|
|
||||||
return ticket, fmt.Errorf("unmarshal VoteChoices err: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tSpendPolicyB := bkt.Get(tSpendPolicyK)
|
ticket.TSpendPolicy, err = bytesToStringMap(bkt.Get(tSpendPolicyK))
|
||||||
if tSpendPolicyB != nil {
|
if err != nil {
|
||||||
err = json.Unmarshal(tSpendPolicyB, &ticket.TSpendPolicy)
|
return ticket, fmt.Errorf("unmarshal TSpendPolicy err: %w", err)
|
||||||
if err != nil {
|
|
||||||
return ticket, fmt.Errorf("unmarshal TSpendPolicy err: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
treasuryPolicyB := bkt.Get(treasuryPolicyK)
|
ticket.TreasuryPolicy, err = bytesToStringMap(bkt.Get(treasuryPolicyK))
|
||||||
if treasuryPolicyB != nil {
|
if err != nil {
|
||||||
err = json.Unmarshal(treasuryPolicyB, &ticket.TreasuryPolicy)
|
return ticket, fmt.Errorf("unmarshal TreasuryPolicy err: %w", err)
|
||||||
if err != nil {
|
|
||||||
return ticket, fmt.Errorf("unmarshal TreasuryPolicy err: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ticket, nil
|
return ticket, nil
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user