Fix corrupt json bug in jsn package
This commit is contained in:
parent
90694f8803
commit
51e105699e
|
@ -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--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
jsn/get.go
17
jsn/get.go
|
@ -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--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
17
jsn/keys.go
17
jsn/keys.go
|
@ -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--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
jsn/strip.go
16
jsn/strip.go
|
@ -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--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue