Skip to content

Commit

Permalink
Fix assignment to nil map.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jholdstock committed Mar 22, 2022
1 parent 4ba83f0 commit 1a8cf8c
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 19 deletions.
28 changes: 28 additions & 0 deletions database/helpers.go
Original file line number Diff line number Diff line change
@@ -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 changes: 78 additions & 0 deletions database/helpers_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
})
}
}
28 changes: 9 additions & 19 deletions database/ticket.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,29 +223,19 @@ func getTicketFromBkt(bkt *bolt.Bucket) (Ticket, error) {
ticket.Confirmed = bytesToBool(bkt.Get(confirmedK))

var err error

voteChoicesB := bkt.Get(voteChoicesK)
if voteChoicesB != nil {
err = json.Unmarshal(voteChoicesB, &ticket.VoteChoices)
if err != nil {
return ticket, fmt.Errorf("unmarshal VoteChoices err: %w", err)
}
ticket.VoteChoices, err = bytesToStringMap(bkt.Get(voteChoicesK))
if err != nil {
return ticket, fmt.Errorf("unmarshal VoteChoices err: %w", err)
}

tSpendPolicyB := bkt.Get(tSpendPolicyK)
if tSpendPolicyB != nil {
err = json.Unmarshal(tSpendPolicyB, &ticket.TSpendPolicy)
if err != nil {
return ticket, fmt.Errorf("unmarshal TSpendPolicy err: %w", err)
}
ticket.TSpendPolicy, err = bytesToStringMap(bkt.Get(tSpendPolicyK))
if err != nil {
return ticket, fmt.Errorf("unmarshal TSpendPolicy err: %w", err)
}

treasuryPolicyB := bkt.Get(treasuryPolicyK)
if treasuryPolicyB != nil {
err = json.Unmarshal(treasuryPolicyB, &ticket.TreasuryPolicy)
if err != nil {
return ticket, fmt.Errorf("unmarshal TreasuryPolicy err: %w", err)
}
ticket.TreasuryPolicy, err = bytesToStringMap(bkt.Get(treasuryPolicyK))
if err != nil {
return ticket, fmt.Errorf("unmarshal TreasuryPolicy err: %w", err)
}

return ticket, nil
Expand Down

0 comments on commit 1a8cf8c

Please sign in to comment.