Skip to content

Commit 9bc0483

Browse files
committed
fix(parser): ensure subsequent calls on a failed decoder does not panic
Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>
1 parent e828582 commit 9bc0483

File tree

2 files changed

+17
-20
lines changed

2 files changed

+17
-20
lines changed

internal/parser/cedar_unmarshal.go

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,39 +36,35 @@ func (p *PolicySlice) UnmarshalCedar(b []byte) error {
3636
}
3737

3838
type Decoder struct {
39-
r io.Reader
40-
41-
once sync.Once
42-
43-
parser *parser
39+
createParser func() (*parser, error)
4440
}
4541

4642
func NewDecoder(r io.Reader) *Decoder {
47-
return &Decoder{r: r}
48-
}
43+
return &Decoder{
44+
createParser: sync.OnceValues(func() (*parser, error) {
45+
tokens, err := TokenizeReader(r)
46+
if err != nil {
47+
return nil, err
48+
}
4949

50-
func (d *Decoder) Decode(p *Policy) error {
51-
var err error
50+
p := newParser(tokens)
5251

53-
d.once.Do(func() {
54-
tokens, e := TokenizeReader(d.r)
55-
if e != nil {
56-
err = e
57-
return
58-
}
52+
return &p, nil
53+
}),
54+
}
55+
}
5956

60-
parser := newParser(tokens)
61-
d.parser = &parser
62-
})
57+
func (d *Decoder) Decode(p *Policy) error {
58+
parser, err := d.createParser()
6359
if err != nil {
6460
return err
6561
}
6662

67-
if d.parser.peek().isEOF() {
63+
if parser.peek().isEOF() {
6864
return io.EOF
6965
}
7066

71-
return p.fromCedar(d.parser)
67+
return p.fromCedar(parser)
7268
}
7369

7470
func (p *Policy) UnmarshalCedar(b []byte) error {

internal/parser/cedar_unmarshal_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,7 @@ func TestDecoderErrors(t *testing.T) {
579579
decoder := parser.NewDecoder(strings.NewReader(tt))
580580

581581
testutil.Error(t, decoder.Decode(nil))
582+
testutil.Error(t, decoder.Decode(nil))
582583
})
583584
}
584585
}

0 commit comments

Comments
 (0)