Skip to content

Commit 120991f

Browse files
authored
add option to not parse beyond end of structure (#435)
1 parent c88f0b4 commit 120991f

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

codec/dagjson/nongreedy_test.go

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package dagjson
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/ipld/go-ipld-prime/datamodel"
8+
"github.com/ipld/go-ipld-prime/node/basicnode"
9+
)
10+
11+
func TestNonGreedy(t *testing.T) {
12+
buf := bytes.NewBufferString(`{"a": 1}{"b": 2}`)
13+
opts := DecodeOptions{
14+
ParseLinks: false,
15+
ParseBytes: false,
16+
DontParseBeyondEnd: true,
17+
}
18+
nb1 := basicnode.Prototype.Map.NewBuilder()
19+
err := opts.Decode(nb1, buf)
20+
if err != nil {
21+
t.Fatalf("first decode (%v)", err)
22+
}
23+
n1 := nb1.Build()
24+
if n1.Kind() != datamodel.Kind_Map {
25+
t.Errorf("expecting a map")
26+
}
27+
if _, err := n1.LookupByString("a"); err != nil {
28+
t.Fatalf("missing fist key")
29+
}
30+
nb2 := basicnode.Prototype.Map.NewBuilder()
31+
err = opts.Decode(nb2, buf)
32+
if err != nil {
33+
t.Fatalf("second decode (%v)", err)
34+
}
35+
n2 := nb2.Build()
36+
if n2.Kind() != datamodel.Kind_Map {
37+
t.Errorf("expecting a map")
38+
}
39+
if _, err := n2.LookupByString("b"); err != nil {
40+
t.Fatalf("missing second key")
41+
}
42+
}

codec/dagjson/unmarshal.go

+10
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ type DecodeOptions struct {
3232
// If true, parse DAG-JSON `{"/":{"bytes":"base64 bytes..."}}` as a Bytes kind
3333
// node rather than nested plain maps
3434
ParseBytes bool
35+
36+
// If true, the decoder stops reading from the stream at the end of the JSON structure.
37+
// i.e. it does not slurp remaining whitespaces and EOF.
38+
// As per standard IPLD behavior, the parser considers the entire block to be
39+
// part of the JSON structure and will error if there is extraneous
40+
// non-whitespace data.
41+
DontParseBeyondEnd bool
3542
}
3643

3744
// Decode deserializes data from the given io.Reader and feeds it into the given datamodel.NodeAssembler.
@@ -43,6 +50,9 @@ func (cfg DecodeOptions) Decode(na datamodel.NodeAssembler, r io.Reader) error {
4350
if err != nil {
4451
return err
4552
}
53+
if cfg.DontParseBeyondEnd {
54+
return nil
55+
}
4656
// Slurp any remaining whitespace.
4757
// This behavior may be due for review.
4858
// (This is relevant if our reader is tee'ing bytes to a hasher, and

0 commit comments

Comments
 (0)