Skip to content

Commit 9402a8a

Browse files
authored
Merge branch 'main' into dependabot/github_actions/github/codeql-action-2.2.9
2 parents 840f374 + 35fec95 commit 9402a8a

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

flatten_json.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func (fj *flattenJSON) readObject(pathNode SegmentsTreeTracker) error {
168168
if pathNode.IsRoot() {
169169
return errEarlyStop
170170
} else {
171-
return fj.skipUntil('}')
171+
return fj.leaveObject()
172172
}
173173
}
174174

@@ -532,7 +532,7 @@ func (fj *flattenJSON) readLiteral(literal []byte) ([]byte, error) {
532532
return literal, nil
533533
}
534534

535-
func (fj *flattenJSON) skipUntil(symbol byte) error {
535+
func (fj *flattenJSON) leaveObject() error {
536536
for fj.eventIndex < len(fj.event) {
537537
ch := fj.event[fj.eventIndex]
538538

@@ -542,7 +542,14 @@ func (fj *flattenJSON) skipUntil(symbol byte) error {
542542
if err != nil {
543543
return err
544544
}
545-
case symbol:
545+
case '{', '[':
546+
// ch+2 is the matching closing brace, since both '}' and ']' are 2 characters away
547+
// from '{' and ']', respectively
548+
err := fj.skipBlock(ch, ch+2)
549+
if err != nil {
550+
return err
551+
}
552+
case '}':
546553
return nil
547554
}
548555

flatten_json_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package quamina
22

33
import (
44
"bytes"
5+
"fmt"
56
"os"
67
"testing"
78
)
@@ -315,6 +316,76 @@ func TestFJErrorCases(t *testing.T) {
315316
}
316317
}
317318

319+
func TestSkipUnusedPaths(t *testing.T) {
320+
// Each of theses cases has a nested object with additional values that should
321+
// be skipped after the specified paths have been checked
322+
//
323+
// e.g., take the following object and paths:
324+
//
325+
// object: { "a": { "b": 1, "c": 2} }
326+
// paths: ["a\nb", "d"]
327+
//
328+
// After the flattener evaluates a.b, it should skip a.c before looking
329+
// for d in the outer object.
330+
//
331+
// These tests make sure that the flattener correctly skips remaining
332+
// values including nested objects and arrays.
333+
//
334+
// The tests below contain an additional path to look for after the
335+
// paths in the nested object to make sure the flattener correctly
336+
// exits the nested object and begings parsing the rest of the event
337+
// at the correct location.
338+
cases := []struct {
339+
event string
340+
matcherPaths []string
341+
}{
342+
{
343+
event: `{"nested":{"thing":"whatever","extra":{}}}`,
344+
matcherPaths: []string{"nested\nthing", "another"},
345+
},
346+
{
347+
event: `{"nested":{"thing":"whatever","extra":{"empty": false}}}`,
348+
matcherPaths: []string{"nested\nthing", "another"},
349+
},
350+
{
351+
event: `{"nested":{"thing":"whatever","extra":[{}]}}`,
352+
matcherPaths: []string{"nested\nthing", "another"},
353+
},
354+
{
355+
event: `{"nested":{"thing":"whatever","extra":[{"empty": false}]}}`,
356+
matcherPaths: []string{"nested\nthing", "another"},
357+
},
358+
{
359+
event: `{"nested":{"thing":"whatever","extra":[]}}`,
360+
matcherPaths: []string{"nested\nthing", "another"},
361+
},
362+
{
363+
event: `{"nested":{"thing":"whatever","extra":[1,"two",true,null]}}`,
364+
matcherPaths: []string{"nested\nthing", "another"},
365+
},
366+
{
367+
event: `{"nested":{"thing":"whatever","extra":[],"andAnother":{}}}`,
368+
matcherPaths: []string{"nested\nthing", "another"},
369+
},
370+
}
371+
372+
for i, c := range cases {
373+
t.Run(fmt.Sprintf("case_%d", i), func(t *testing.T) {
374+
matcher := fakeMatcher(c.matcherPaths...)
375+
376+
fj := newJSONFlattener().(*flattenJSON)
377+
378+
// ignore the fields - this test isn't concerned with the flattening result
379+
_, err := fj.Flatten([]byte(c.event), matcher.getSegmentsTreeTracker())
380+
381+
// make sure the flattener didn't return an error
382+
if err != nil {
383+
t.Fatalf("failed to flatten json: %v", err)
384+
}
385+
})
386+
}
387+
}
388+
318389
func fakeMatcher(paths ...string) *coreMatcher {
319390
m := newCoreMatcher()
320391
for _, path := range paths {

0 commit comments

Comments
 (0)