Fix corrupt json bug in jsn package

This commit is contained in:
Vikram Rangnekar 2020-02-24 01:59:50 +05:30
parent 90694f8803
commit 51e105699e
8 changed files with 77 additions and 26 deletions

View File

@ -27,14 +27,20 @@ func Filter(w *bytes.Buffer, b []byte, keys []string) error {
var k []byte var k []byte
state := expectKey state := expectKey
instr := false
for i := 0; i < len(b); i++ { for i := 0; i < len(b); i++ {
if state == expectObjClose || state == expectListClose { if state == expectObjClose || state == expectListClose {
switch b[i] { if b[i-1] != '\\' && b[i] == '"' {
case '{', '[': instr = !instr
d++ }
case '}', ']': if !instr {
d-- switch b[i] {
case '{', '[':
d++
case '}', ']':
d--
}
} }
} }

View File

@ -51,13 +51,20 @@ func Get(b []byte, keys [][]byte) []Field {
state := expectKey state := expectKey
n := 0 n := 0
instr := false
for i := 0; i < len(b); i++ { for i := 0; i < len(b); i++ {
if state == expectObjClose || state == expectListClose { if state == expectObjClose || state == expectListClose {
switch b[i] { if b[i-1] != '\\' && b[i] == '"' {
case '{', '[': instr = !instr
d++ }
case '}', ']': if !instr {
d-- switch b[i] {
case '{', '[':
d++
case '}', ']':
d--
}
} }
} }

View File

@ -2,6 +2,7 @@ package jsn
import ( import (
"bytes" "bytes"
"io/ioutil"
"testing" "testing"
) )
@ -161,6 +162,8 @@ var (
input6 = ` input6 = `
{"users" : [{"id" : 1, "email" : "vicram@gmail.com", "slug" : "vikram-rangnekar", "threads" : [], "threads_cursor" : null}, {"id" : 3, "email" : "marareilly@lang.name", "slug" : "raymundo-corwin", "threads" : [{"id" : 9, "title" : "Et alias et aut porro praesentium nam in voluptatem reiciendis quisquam perspiciatis inventore eos quia et et enim qui amet."}, {"id" : 25, "title" : "Ipsam quam nemo culpa tempore amet optio sit sed eligendi autem consequatur quaerat rem velit quibusdam quibusdam optio a voluptatem."}], "threads_cursor" : 25}], "users_cursor" : 3}` {"users" : [{"id" : 1, "email" : "vicram@gmail.com", "slug" : "vikram-rangnekar", "threads" : [], "threads_cursor" : null}, {"id" : 3, "email" : "marareilly@lang.name", "slug" : "raymundo-corwin", "threads" : [{"id" : 9, "title" : "Et alias et aut porro praesentium nam in voluptatem reiciendis quisquam perspiciatis inventore eos quia et et enim qui amet."}, {"id" : 25, "title" : "Ipsam quam nemo culpa tempore amet optio sit sed eligendi autem consequatur quaerat rem velit quibusdam quibusdam optio a voluptatem."}], "threads_cursor" : 25}], "users_cursor" : 3}`
input7, _ = ioutil.ReadFile("test.json")
) )
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
@ -256,6 +259,15 @@ func TestGet2(t *testing.T) {
} }
} }
func TestGet3(t *testing.T) {
values := Get(input7, [][]byte{[]byte("data")})
v := values[0].Value
if !bytes.Equal(v[len(v)-11:], []byte(`Rangnekar"}`)) {
t.Fatal("corrupt ending")
}
}
func TestValue(t *testing.T) { func TestValue(t *testing.T) {
v1 := []byte("12345") v1 := []byte("12345")
if !bytes.Equal(Value(v1), v1) { if !bytes.Equal(Value(v1), v1) {

View File

@ -10,15 +10,20 @@ func Keys(b []byte) [][]byte {
st := NewStack() st := NewStack()
ae := 0 ae := 0
instr := false
for i := 0; i < len(b); i++ { for i := 0; i < len(b); i++ {
if state == expectObjClose || state == expectListClose { if state == expectObjClose || state == expectListClose {
switch b[i] { if b[i-1] != '\\' && b[i] == '"' {
case '{', '[': instr = !instr
d++ }
case '}', ']': if !instr {
d-- switch b[i] {
case '{', '[':
d++
case '}', ']':
d--
}
} }
} }

View File

@ -32,6 +32,8 @@ func Replace(w *bytes.Buffer, b []byte, from, to []Field) error {
state := expectKey state := expectKey
ws, we := -1, len(b) ws, we := -1, len(b)
instr := false
for i := 0; i < len(b); i++ { for i := 0; i < len(b); i++ {
// skip any left padding whitespace // skip any left padding whitespace
if ws == -1 && (b[i] == '{' || b[i] == '[') { if ws == -1 && (b[i] == '{' || b[i] == '[') {
@ -39,11 +41,16 @@ func Replace(w *bytes.Buffer, b []byte, from, to []Field) error {
} }
if state == expectObjClose || state == expectListClose { if state == expectObjClose || state == expectListClose {
switch b[i] { if b[i-1] != '\\' && b[i] == '"' {
case '{', '[': instr = !instr
d++ }
case '}', ']': if !instr {
d-- switch b[i] {
case '{', '[':
d++
case '}', ']':
d--
}
} }
} }

View File

@ -11,14 +11,20 @@ func Strip(b []byte, path [][]byte) []byte {
pi := 0 pi := 0
pm := false pm := false
state := expectKey state := expectKey
instr := false
for i := 0; i < len(b); i++ { for i := 0; i < len(b); i++ {
if state == expectObjClose || state == expectListClose { if state == expectObjClose || state == expectListClose {
switch b[i] { if b[i-1] != '\\' && b[i] == '"' {
case '{', '[': instr = !instr
d++ }
case '}', ']': if !instr {
d-- switch b[i] {
case '{', '[':
d++
case '}', ']':
d--
}
} }
} }

1
jsn/test.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -39,11 +39,16 @@ func argMap(ctx context.Context, vars []byte) func(w io.Writer, tag string) (int
} }
v := fields[0].Value v := fields[0].Value
// Open and close quotes
if len(v) >= 2 && v[0] == '"' && v[len(v)-1] == '"' { if len(v) >= 2 && v[0] == '"' && v[len(v)-1] == '"' {
fields[0].Value = v[1 : len(v)-1] fields[0].Value = v[1 : len(v)-1]
} }
if tag == "cursor" { if tag == "cursor" {
if bytes.EqualFold(v, []byte("null")) {
return io.WriteString(w, ``)
}
v1, err := decrypt(string(fields[0].Value)) v1, err := decrypt(string(fields[0].Value))
if err != nil { if err != nil {
return 0, err return 0, err
@ -52,6 +57,8 @@ func argMap(ctx context.Context, vars []byte) func(w io.Writer, tag string) (int
return w.Write(v1) return w.Write(v1)
} }
fmt.Println(">>>", tag, string(v))
return w.Write(escQuote(fields[0].Value)) return w.Write(escQuote(fields[0].Value))
} }
} }