Skip to content

Commit

Permalink
pgtype.parseHstore: Reject invalid input; Fix error messages
Browse files Browse the repository at this point in the history
The parseHstore function did not check the return value from
p.Consume() after a ', ' sequence. It expects a doublequote '"' that
starts the next key, but would accept any character. This means it
accepted invalid input such as:

    "key1"=>"b", ,key2"=>"value"

Add a unit test that covers this case
Fix a couple of the nearby error strings while looking at this.

Found by looking at staticcheck warnings:

    pgtype/hstore.go:434:6: this value of end is never used (SA4006)
    pgtype/hstore.go:434:6: this value of r is never used (SA4006)
  • Loading branch information
evanj authored and jackc committed May 15, 2023
1 parent bbcc4fc commit 8ceef73
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
13 changes: 11 additions & 2 deletions pgtype/hstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,12 +428,21 @@ func parseHstore(s string) (k []string, v []Text, err error) {
r, end = p.Consume()
switch {
case end:
err = errors.New("Found EOS after ',', expcting space")
err = errors.New("Found EOS after ',', expecting space")
case (unicode.IsSpace(r)):
// after space is a doublequote to start the key
r, end = p.Consume()
if end {
err = errors.New("Found EOS after space, expecting \"")
return
}
if r != '"' {
err = fmt.Errorf("Invalid character '%c' after space, expecting \"", r)
return
}
state = hsKey
default:
err = fmt.Errorf("Invalid character '%c' after ', ', expecting \"", r)
err = fmt.Errorf("Invalid character '%c' after ',', expecting space", r)
}
} else {
err = fmt.Errorf("Invalid character '%c' after value, expecting ','", r)
Expand Down
15 changes: 15 additions & 0 deletions pgtype/hstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,18 @@ func TestHstoreCodec(t *testing.T) {
}
})
}

func TestParseInvalidInputs(t *testing.T) {
// these inputs should be invalid, but previously were considered correct
invalidInputs := []string{
`"a"=>"1", ,b"=>"2"`,
`""=>"", 0"=>""`,
}
for i, input := range invalidInputs {
var hstore pgtype.Hstore
err := hstore.Scan(input)
if err == nil {
t.Errorf("test %d: input=%s (%#v) should fail; parsed correctly", i, input, input)
}
}
}

0 comments on commit 8ceef73

Please sign in to comment.