From 475b4036c39569593ccabc9770b1188ffd2193e0 Mon Sep 17 00:00:00 2001 From: tidwall Date: Thu, 4 Aug 2022 18:06:36 -0700 Subject: [PATCH] Allow for Index > 0 on path compontent that are not modifiers. This commit fixes an issue where non-modifier path components such as '@hello' return 0 for the Result.Index value. --- gjson.go | 25 ++++++++++++++++++++----- gjson_test.go | 11 +++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/gjson.go b/gjson.go index 67e67a0..9b0db4e 100644 --- a/gjson.go +++ b/gjson.go @@ -775,7 +775,7 @@ func parseArrayPath(path string) (r arrayPathResult) { } if path[i] == '.' { r.part = path[:i] - if !r.arrch && i < len(path)-1 && isDotPiperChar(path[i+1]) { + if !r.arrch && i < len(path)-1 && isDotPiperChar(path[i+1:]) { r.pipe = path[i+1:] r.piped = true } else { @@ -936,8 +936,23 @@ right: } // peek at the next byte and see if it's a '@', '[', or '{'. -func isDotPiperChar(c byte) bool { - return !DisableModifiers && (c == '@' || c == '[' || c == '{') +func isDotPiperChar(s string) bool { + if DisableModifiers { + return false + } + c := s[0] + if c == '@' { + // check that the next component is *not* a modifier. + i := 1 + for ; i < len(s); i++ { + if s[i] == '.' || s[i] == '|' { + break + } + } + _, ok := modifiers[s[1:i]] + return ok + } + return c == '[' || c == '{' } type objectPathResult struct { @@ -959,7 +974,7 @@ func parseObjectPath(path string) (r objectPathResult) { } if path[i] == '.' { r.part = path[:i] - if i < len(path)-1 && isDotPiperChar(path[i+1]) { + if i < len(path)-1 && isDotPiperChar(path[i+1:]) { r.pipe = path[i+1:] r.piped = true } else { @@ -989,7 +1004,7 @@ func parseObjectPath(path string) (r objectPathResult) { continue } else if path[i] == '.' { r.part = string(epart) - if i < len(path)-1 && isDotPiperChar(path[i+1]) { + if i < len(path)-1 && isDotPiperChar(path[i+1:]) { r.pipe = path[i+1:] r.piped = true } else { diff --git a/gjson_test.go b/gjson_test.go index 9353969..8ddab94 100644 --- a/gjson_test.go +++ b/gjson_test.go @@ -2543,3 +2543,14 @@ func TestJSONString(t *testing.T) { testJSONString(t, string(buf[:])) } } + +func TestIndexAtSymbol(t *testing.T) { + json := `{ + "@context": { + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "@vocab": "http://schema.org/", + "sh": "http://www.w3.org/ns/shacl#" + } + }` + assert(t, Get(json, "@context.@vocab").Index == 85) +}