Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
6102f1d66e | |||
701b2f3bfd | |||
bac89d8301 | |||
b3dfb2bc7b |
@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
@ -35,6 +36,7 @@ type List struct {
|
||||
type Config struct {
|
||||
CreateIfNotExists bool
|
||||
Persist bool
|
||||
Log *log.Logger
|
||||
}
|
||||
|
||||
func New(filename string, conf Config) (*List, error) {
|
||||
@ -80,6 +82,12 @@ func New(filename string, conf Config) (*List, error) {
|
||||
} else {
|
||||
al.filepath = filename
|
||||
}
|
||||
|
||||
if file, err := os.OpenFile(al.filepath, os.O_RDONLY|os.O_CREATE, 0644); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
file.Close()
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
@ -89,8 +97,10 @@ func New(filename string, conf Config) (*List, error) {
|
||||
|
||||
go func() {
|
||||
for v := range al.saveChan {
|
||||
if err = al.save(v); err != nil {
|
||||
break
|
||||
err := al.save(v)
|
||||
|
||||
if err != nil && conf.Log != nil {
|
||||
conf.Log.Println("WRN allow list save:", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/dosco/super-graph/core/internal/qcode"
|
||||
@ -1355,23 +1356,5 @@ func squoted(w io.Writer, identifier string) {
|
||||
const charset = "0123456789"
|
||||
|
||||
func int32String(w io.Writer, val int32) {
|
||||
if val < 10 {
|
||||
w.Write([]byte{charset[val]})
|
||||
return
|
||||
}
|
||||
|
||||
temp := int32(0)
|
||||
val2 := val
|
||||
for val2 > 0 {
|
||||
temp *= 10
|
||||
temp += val2 % 10
|
||||
val2 = int32(float64(val2 / 10))
|
||||
}
|
||||
|
||||
val3 := temp
|
||||
for val3 > 0 {
|
||||
d := val3 % 10
|
||||
val3 /= 10
|
||||
w.Write([]byte{charset[d]})
|
||||
}
|
||||
io.WriteString(w, strconv.FormatInt(int64(val), 10))
|
||||
}
|
||||
|
11
core/internal/qcode/bench.10
Normal file
11
core/internal/qcode/bench.10
Normal file
@ -0,0 +1,11 @@
|
||||
goos: darwin
|
||||
goarch: amd64
|
||||
pkg: github.com/dosco/super-graph/core/internal/qcode
|
||||
BenchmarkQCompile-16 120888 9236 ns/op 3755 B/op 28 allocs/op
|
||||
BenchmarkQCompileP-16 502248 2620 ns/op 3795 B/op 28 allocs/op
|
||||
BenchmarkParse-16 128370 9294 ns/op 3902 B/op 18 allocs/op
|
||||
BenchmarkParseP-16 575752 2340 ns/op 3903 B/op 18 allocs/op
|
||||
BenchmarkSchemaParse-16 212048 5779 ns/op 3968 B/op 57 allocs/op
|
||||
BenchmarkSchemaParseP-16 630918 1686 ns/op 3968 B/op 57 allocs/op
|
||||
PASS
|
||||
ok github.com/dosco/super-graph/core/internal/qcode 7.710s
|
@ -187,15 +187,14 @@ func (sg *SuperGraph) initAllowList() error {
|
||||
var ac allow.Config
|
||||
var err error
|
||||
|
||||
if len(sg.conf.AllowListFile) == 0 {
|
||||
sg.conf.UseAllowList = false
|
||||
sg.log.Printf("WRN allow list disabled no file specified")
|
||||
if sg.conf.AllowListFile == "" {
|
||||
sg.conf.AllowListFile = "allow.list"
|
||||
}
|
||||
|
||||
// When list is not eabled it is still created and
|
||||
// and new queries are saved to it.
|
||||
if !sg.conf.UseAllowList {
|
||||
ac = allow.Config{CreateIfNotExists: true, Persist: true}
|
||||
ac = allow.Config{CreateIfNotExists: true, Persist: true, Log: sg.log}
|
||||
}
|
||||
|
||||
sg.allowList, err = allow.New(sg.conf.AllowListFile, ac)
|
||||
|
3
go.mod
3
go.mod
@ -29,6 +29,7 @@ require (
|
||||
github.com/openzipkin/zipkin-go v0.2.2
|
||||
github.com/pelletier/go-toml v1.7.0 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/common v0.4.0
|
||||
github.com/rs/cors v1.7.0
|
||||
github.com/spf13/afero v1.2.2 // indirect
|
||||
github.com/spf13/cast v1.3.1 // indirect
|
||||
@ -41,7 +42,7 @@ require (
|
||||
go.uber.org/zap v1.14.1
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904
|
||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||
gopkg.in/ini.v1 v1.55.0 // indirect
|
||||
)
|
||||
|
5
go.sum
5
go.sum
@ -35,7 +35,9 @@ github.com/adjust/gorails v0.0.0-20171013043634-2786ed0c03d3 h1:+qz9Ga6l6lKw6fgv
|
||||
github.com/adjust/gorails v0.0.0-20171013043634-2786ed0c03d3/go.mod h1:FlkD11RtgMTYjVuBnb7cxoHmQGqvPpCsr2atC88nl/M=
|
||||
github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw=
|
||||
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/aws/aws-sdk-go v1.15.27 h1:i75BxN4Es/8rTVQbEKAP1WCiIhhz635xTNeDdZJRAXQ=
|
||||
@ -220,6 +222,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
@ -319,6 +322,7 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@ -543,6 +547,7 @@ google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@ -156,7 +156,7 @@ func cmdVersion(cmd *cobra.Command, args []string) {
|
||||
|
||||
func BuildDetails() string {
|
||||
if len(version) == 0 {
|
||||
return fmt.Sprintf(`
|
||||
return `
|
||||
Super Graph (unknown version)
|
||||
For documentation, visit https://supergraph.dev
|
||||
|
||||
@ -166,7 +166,7 @@ To build with version information please use the Makefile
|
||||
|
||||
Licensed under the Apache Public License 2.0
|
||||
Copyright 2020, Vikram Rangnekar
|
||||
`)
|
||||
`
|
||||
}
|
||||
|
||||
return fmt.Sprintf(`
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"github.com/dosco/super-graph/core"
|
||||
"github.com/gosimple/slug"
|
||||
"github.com/jackc/pgx/v4"
|
||||
"github.com/jackc/pgx/v4/stdlib"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@ -200,12 +201,12 @@ func importCSV(table, filename string) int64 {
|
||||
cols = append(cols, c.(string))
|
||||
}
|
||||
|
||||
conn, err := acquireConn(db)
|
||||
conn, err := stdlib.AcquireConn(db)
|
||||
if err != nil {
|
||||
log.Fatalf("ERR %v", err)
|
||||
}
|
||||
//nolint: errcheck
|
||||
defer releaseConn(db, conn)
|
||||
defer stdlib.ReleaseConn(db, conn)
|
||||
|
||||
n, err := conn.CopyFrom(
|
||||
context.Background(),
|
||||
|
@ -1,67 +0,0 @@
|
||||
package serv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
errors "golang.org/x/xerrors"
|
||||
|
||||
"github.com/jackc/pgx/v4"
|
||||
)
|
||||
|
||||
type ctxKey int
|
||||
|
||||
var ctxKeyFakeTx ctxKey = 0
|
||||
|
||||
var errNotPgx = errors.New("not pgx *sql.DB")
|
||||
|
||||
var (
|
||||
fakeTxMutex sync.Mutex
|
||||
fakeTxConns map[*pgx.Conn]*sql.Tx
|
||||
)
|
||||
|
||||
func acquireConn(db *sql.DB) (*pgx.Conn, error) {
|
||||
var conn *pgx.Conn
|
||||
ctx := context.WithValue(context.Background(), ctxKeyFakeTx, &conn)
|
||||
tx, err := db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if conn == nil {
|
||||
if err := tx.Rollback(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errNotPgx
|
||||
}
|
||||
|
||||
fakeTxMutex.Lock()
|
||||
fakeTxConns[conn] = tx
|
||||
fakeTxMutex.Unlock()
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func releaseConn(db *sql.DB, conn *pgx.Conn) error {
|
||||
var tx *sql.Tx
|
||||
var ok bool
|
||||
|
||||
if conn.PgConn().IsBusy() || conn.PgConn().TxStatus() != 'I' {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer cancel()
|
||||
conn.Close(ctx)
|
||||
}
|
||||
|
||||
fakeTxMutex.Lock()
|
||||
tx, ok = fakeTxConns[conn]
|
||||
if ok {
|
||||
delete(fakeTxConns, conn)
|
||||
fakeTxMutex.Unlock()
|
||||
} else {
|
||||
fakeTxMutex.Unlock()
|
||||
return errors.Errorf("can't release conn that is not acquired")
|
||||
}
|
||||
|
||||
return tx.Rollback()
|
||||
}
|
@ -3,6 +3,7 @@ package jsn
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
@ -68,7 +69,12 @@ func Clear(w *bytes.Buffer, v []byte) error {
|
||||
}
|
||||
|
||||
io := int(dec.InputOffset())
|
||||
w.Write(v[io-len(v1)-2 : io])
|
||||
s := io - len(v1) - 2
|
||||
if io <= s || s <= 0 {
|
||||
return errors.New("invalid json")
|
||||
}
|
||||
|
||||
w.Write(v[s:io])
|
||||
w.WriteString(`:`)
|
||||
isValue = true
|
||||
|
||||
|
51
jsn/fuzz.go
51
jsn/fuzz.go
@ -2,10 +2,55 @@
|
||||
|
||||
package jsn
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
if err := unifiedTest(data); err != nil {
|
||||
return 0
|
||||
c := 0
|
||||
|
||||
if err := Validate(string(data)); err == nil {
|
||||
c = 1
|
||||
}
|
||||
|
||||
return 1
|
||||
if err := fuzzTest(data); err == nil {
|
||||
c = 1
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func fuzzTest(data []byte) error {
|
||||
err1 := Validate(string(data))
|
||||
|
||||
var b1 bytes.Buffer
|
||||
err2 := Filter(&b1, data, []string{"id", "full_name", "embed"})
|
||||
|
||||
path1 := [][]byte{[]byte("data"), []byte("users")}
|
||||
Strip(data, path1)
|
||||
|
||||
from := []Field{
|
||||
{[]byte("__twitter_id"), []byte(`[{ "name": "hello" }, { "name": "world"}]`)},
|
||||
{[]byte("__twitter_id"), []byte(`"ABC123"`)},
|
||||
}
|
||||
|
||||
to := []Field{
|
||||
{[]byte("__twitter_id"), []byte(`"1234567890"`)},
|
||||
{[]byte("some_list"), []byte(`[{"id":1,"embed":{"id":8}},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9},{"id":10},{"id":11},{"id":12},{"id":13}]`)},
|
||||
}
|
||||
|
||||
var b2 bytes.Buffer
|
||||
err3 := Replace(&b2, data, from, to)
|
||||
|
||||
Keys(data)
|
||||
|
||||
var b3 bytes.Buffer
|
||||
err4 := Clear(&b3, data)
|
||||
|
||||
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
|
||||
return errors.New("there was an error")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
112
jsn/fuzz_test.go
112
jsn/fuzz_test.go
@ -1,60 +1,76 @@
|
||||
package jsn
|
||||
// +build gofuzz
|
||||
|
||||
package jsn_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/dosco/super-graph/jsn"
|
||||
)
|
||||
|
||||
var ret int
|
||||
|
||||
func TestFuzzCrashers(t *testing.T) {
|
||||
var crashers = []string{
|
||||
"00\"0000\"0{",
|
||||
"6\",\n\t\t\t\"something\": " +
|
||||
"null\n\t\t},\n\t\t{\n\t\t\t\"id" +
|
||||
"\": 12,\n\t\t\t\"full_name" +
|
||||
"\": \"Brenton Bauch Ph" +
|
||||
"D\",\n\t\t\t\"email\": \"ren" +
|
||||
"ee@miller.co\",\n\t\t\t\"_" +
|
||||
"_twitter_id\": 1\n\t\t}," +
|
||||
"\n\t\t{\n\t\t\t\"id\": 13,\n\t\t" +
|
||||
"\t\"full_name\": \"Daine" +
|
||||
" Gleichner\",\n\t\t\t\"ema" +
|
||||
"il\": \"andrea@gmail.c" +
|
||||
"om\",\n\t\t\t\"__twitter_i" +
|
||||
"d\": \"\",\n\t\t\t\"id__twit" +
|
||||
"ter_id\": \"NOOO\",\n\t\t\t" +
|
||||
"\"work_email\": \"andre" +
|
||||
"a@nienow.co\"\n\t\t}\n\t]}" +
|
||||
"\n\t}",
|
||||
"0000\"0000\"0{",
|
||||
"0000\"\"{",
|
||||
"0000\"000\"{",
|
||||
"0\"\"{",
|
||||
"\"0\"{",
|
||||
"000\"0\"{",
|
||||
"0\"0000\"0{",
|
||||
"000\"\"{",
|
||||
"0\"00\"{",
|
||||
"000\"0000\"0{",
|
||||
"000\"00\"{",
|
||||
"\"\"{",
|
||||
"0\"0000\"{",
|
||||
"\"000\"00{",
|
||||
"0000\"00\"{",
|
||||
"00\"0\"{",
|
||||
"0\"0\"{",
|
||||
"000\"0000\"{",
|
||||
"00\"0000\"{",
|
||||
"0000\"0000\"{",
|
||||
"\"000\"{",
|
||||
"00\"00\"{",
|
||||
"00\"0000\"00{",
|
||||
"0\"0000\"00{",
|
||||
"00\"\"{",
|
||||
"0000\"0\"{",
|
||||
"000\"000\"{",
|
||||
"\"00000000\"{",
|
||||
/*
|
||||
"00\"0000\"0{",
|
||||
"6\",\n\t\t\t\"something\": " +
|
||||
"null\n\t\t},\n\t\t{\n\t\t\t\"id" +
|
||||
"\": 12,\n\t\t\t\"full_name" +
|
||||
"\": \"Brenton Bauch Ph" +
|
||||
"D\",\n\t\t\t\"email\": \"ren" +
|
||||
"ee@miller.co\",\n\t\t\t\"_" +
|
||||
"_twitter_id\": 1\n\t\t}," +
|
||||
"\n\t\t{\n\t\t\t\"id\": 13,\n\t\t" +
|
||||
"\t\"full_name\": \"Daine" +
|
||||
" Gleichner\",\n\t\t\t\"ema" +
|
||||
"il\": \"andrea@gmail.c" +
|
||||
"om\",\n\t\t\t\"__twitter_i" +
|
||||
"d\": \"\",\n\t\t\t\"id__twit" +
|
||||
"ter_id\": \"NOOO\",\n\t\t\t" +
|
||||
"\"work_email\": \"andre" +
|
||||
"a@nienow.co\"\n\t\t}\n\t]}" +
|
||||
"\n\t}",
|
||||
"0000\"0000\"0{",
|
||||
"0000\"\"{",
|
||||
"0000\"000\"{",
|
||||
"0\"\"{",
|
||||
"\"0\"{",
|
||||
"000\"0\"{",
|
||||
"0\"0000\"0{",
|
||||
"000\"\"{",
|
||||
"0\"00\"{",
|
||||
"000\"0000\"0{",
|
||||
"000\"00\"{",
|
||||
"\"\"{",
|
||||
"0\"0000\"{",
|
||||
"\"000\"00{",
|
||||
"0000\"00\"{",
|
||||
"00\"0\"{",
|
||||
"0\"0\"{",
|
||||
"000\"0000\"{",
|
||||
"00\"0000\"{",
|
||||
"0000\"0000\"{",
|
||||
"\"000\"{",
|
||||
"00\"00\"{",
|
||||
"00\"0000\"00{",
|
||||
"0\"0000\"00{",
|
||||
"00\"\"{",
|
||||
"0000\"0\"{",
|
||||
"000\"000\"{",
|
||||
"\"00000000\"{",
|
||||
`0000"00"00000000"000000000"00"000000000000000"00000"00000": "00"0"__twitter_id": [{ "name": "hello" }, { "name": "world"}]`,
|
||||
*/
|
||||
|
||||
`0000"000000000000000000000000000000000000"00000000"000000000"00"000000000000000"00000"00000": "00000000000000"00000"__twitter_id": [{ "name": "hello" }, { "name": "world"}]`,
|
||||
`00"__twitter_id":[{ "name": "hello" }, { "name": "world"}]`,
|
||||
"\"\xb0\xef\xbd\xe3\xbd\xef\x99\xe3\xbd\xef\xbd\xef\xbd\xef\xbd\xe5\x99\xe3\xbd" +
|
||||
"\xef\x99\xe3\"",
|
||||
"\"\xef\xe3\xef\xe3\xe3\xe3\xef\xe3\xe3\xef\xe3\xef\xe3\xe3\xe3\xef\xe3\xef\xe3" +
|
||||
"\xe3\xef\xef\xef\xe5\xe3\xef\xe3\xc6\xef\xef\xef\xe5\xe3\xef\xe3\xc6\xef\xef\"",
|
||||
}
|
||||
|
||||
for _, f := range crashers {
|
||||
_ = unifiedTest([]byte(f))
|
||||
ret = jsn.Fuzz([]byte(f))
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package jsn
|
||||
package jsn_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -6,6 +6,8 @@ import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dosco/super-graph/jsn"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -171,13 +173,13 @@ var (
|
||||
)
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
values := Get([]byte(input1), [][]byte{
|
||||
values := jsn.Get([]byte(input1), [][]byte{
|
||||
[]byte("test_1a"),
|
||||
[]byte("__twitter_id"),
|
||||
[]byte("work_email"),
|
||||
})
|
||||
|
||||
expected := []Field{
|
||||
expected := []jsn.Field{
|
||||
{[]byte("test_1a"), []byte(`{ "__twitter_id": "ABCD" }`)},
|
||||
{[]byte("__twitter_id"), []byte(`"ABCD"`)},
|
||||
{[]byte("__twitter_id"), []byte(`"2048666903444506956"`)},
|
||||
@ -214,11 +216,11 @@ func TestGet(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGet1(t *testing.T) {
|
||||
values := Get([]byte(input5), [][]byte{
|
||||
values := jsn.Get([]byte(input5), [][]byte{
|
||||
[]byte("thread_slug"),
|
||||
})
|
||||
|
||||
expected := []Field{
|
||||
expected := []jsn.Field{
|
||||
{[]byte("thread_slug"), []byte(`"in-september-2018-slovak-police-stated-that-kuciak-7929"`)},
|
||||
}
|
||||
|
||||
@ -238,11 +240,11 @@ func TestGet1(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGet2(t *testing.T) {
|
||||
values := Get([]byte(input6), [][]byte{
|
||||
values := jsn.Get([]byte(input6), [][]byte{
|
||||
[]byte("users_cursor"), []byte("threads_cursor"),
|
||||
})
|
||||
|
||||
expected := []Field{
|
||||
expected := []jsn.Field{
|
||||
{[]byte("threads_cursor"), []byte(`null`)},
|
||||
{[]byte("threads_cursor"), []byte(`25`)},
|
||||
{[]byte("users_cursor"), []byte(`3`)},
|
||||
@ -264,7 +266,7 @@ func TestGet2(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGet3(t *testing.T) {
|
||||
values := Get(input7, [][]byte{[]byte("data")})
|
||||
values := jsn.Get(input7, [][]byte{[]byte("data")})
|
||||
v := values[0].Value
|
||||
|
||||
if !bytes.Equal(v[len(v)-11:], []byte(`Rangnekar"}`)) {
|
||||
@ -277,7 +279,7 @@ func TestGet4(t *testing.T) {
|
||||
|
||||
exp = strings.ReplaceAll(exp, "@", "`")
|
||||
|
||||
values := Get(input8, [][]byte{[]byte("body")})
|
||||
values := jsn.Get(input8, [][]byte{[]byte("body")})
|
||||
|
||||
if string(values[0].Key) != "body" {
|
||||
t.Fatal("unexpected key")
|
||||
@ -291,29 +293,29 @@ func TestGet4(t *testing.T) {
|
||||
|
||||
func TestValue(t *testing.T) {
|
||||
v1 := []byte("12345")
|
||||
if !bytes.Equal(Value(v1), v1) {
|
||||
if !bytes.Equal(jsn.Value(v1), v1) {
|
||||
t.Fatal("Number value invalid")
|
||||
}
|
||||
|
||||
v2 := []byte(`"12345"`)
|
||||
if !bytes.Equal(Value(v2), []byte(`12345`)) {
|
||||
if !bytes.Equal(jsn.Value(v2), []byte(`12345`)) {
|
||||
t.Fatal("String value invalid")
|
||||
}
|
||||
|
||||
v3 := []byte(`{ "hello": "world" }`)
|
||||
if Value(v3) != nil {
|
||||
t.Fatal("Object value is not nil", Value(v3))
|
||||
if jsn.Value(v3) != nil {
|
||||
t.Fatal("Object value is not nil", jsn.Value(v3))
|
||||
}
|
||||
|
||||
v4 := []byte(`[ "hello", "world" ]`)
|
||||
if Value(v4) != nil {
|
||||
if jsn.Value(v4) != nil {
|
||||
t.Fatal("List value is not nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilter1(t *testing.T) {
|
||||
var b bytes.Buffer
|
||||
err := Filter(&b, []byte(input2), []string{"id", "full_name", "embed"})
|
||||
err := jsn.Filter(&b, []byte(input2), []string{"id", "full_name", "embed"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -329,7 +331,7 @@ func TestFilter2(t *testing.T) {
|
||||
value := `[{"id":1,"customer_id":"cus_2TbMGf3cl0","object":"charge","amount":100,"amount_refunded":0,"date":"01/01/2019","application":null,"billing_details":{"address":"1 Infinity Drive","zipcode":"94024"}}, {"id":2,"customer_id":"cus_2TbMGf3cl0","object":"charge","amount":150,"amount_refunded":0,"date":"02/18/2019","billing_details":{"address":"1 Infinity Drive","zipcode":"94024"}},{"id":3,"customer_id":"cus_2TbMGf3cl0","object":"charge","amount":150,"amount_refunded":50,"date":"03/21/2019","billing_details":{"address":"1 Infinity Drive","zipcode":"94024"}}]`
|
||||
|
||||
var b bytes.Buffer
|
||||
err := Filter(&b, []byte(value), []string{"id"})
|
||||
err := jsn.Filter(&b, []byte(value), []string{"id"})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -343,7 +345,7 @@ func TestFilter2(t *testing.T) {
|
||||
|
||||
func TestStrip(t *testing.T) {
|
||||
path1 := [][]byte{[]byte("data"), []byte("users")}
|
||||
value1 := Strip([]byte(input3), path1)
|
||||
value1 := jsn.Strip([]byte(input3), path1)
|
||||
|
||||
expected := []byte(`[{"id":1,"embed":{"id":8}},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9},{"id":10},{"id":11},{"id":12},{"id":13}]`)
|
||||
|
||||
@ -353,7 +355,7 @@ func TestStrip(t *testing.T) {
|
||||
}
|
||||
|
||||
path2 := [][]byte{[]byte("boo"), []byte("hoo")}
|
||||
value2 := Strip([]byte(input3), path2)
|
||||
value2 := jsn.Strip([]byte(input3), path2)
|
||||
|
||||
if !bytes.Equal(value2, []byte(input3)) {
|
||||
t.Log(value2)
|
||||
@ -364,7 +366,7 @@ func TestStrip(t *testing.T) {
|
||||
func TestValidateTrue(t *testing.T) {
|
||||
json := []byte(` [{"id":1,"embed":{"id":8}},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9},{"id":10},{"id":11},{"id":12},{"id":13}]`)
|
||||
|
||||
err := Validate(string(json))
|
||||
err := jsn.Validate(string(json))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -373,7 +375,7 @@ func TestValidateTrue(t *testing.T) {
|
||||
func TestValidateFalse(t *testing.T) {
|
||||
json := []byte(` [{ "hello": 123"<html>}]`)
|
||||
|
||||
err := Validate(string(json))
|
||||
err := jsn.Validate(string(json))
|
||||
if err == nil {
|
||||
t.Error("JSON validation failed to detect invalid json")
|
||||
}
|
||||
@ -382,12 +384,12 @@ func TestValidateFalse(t *testing.T) {
|
||||
func TestReplace(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
from := []Field{
|
||||
from := []jsn.Field{
|
||||
{[]byte("__twitter_id"), []byte(`[{ "name": "hello" }, { "name": "world"}]`)},
|
||||
{[]byte("__twitter_id"), []byte(`"ABC123"`)},
|
||||
}
|
||||
|
||||
to := []Field{
|
||||
to := []jsn.Field{
|
||||
{[]byte("__twitter_id"), []byte(`"1234567890"`)},
|
||||
{[]byte("some_list"), []byte(`[{"id":1,"embed":{"id":8}},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9},{"id":10},{"id":11},{"id":12},{"id":13}]`)},
|
||||
}
|
||||
@ -412,7 +414,7 @@ func TestReplace(t *testing.T) {
|
||||
"__twitter_id":"1234567890"
|
||||
}] }`
|
||||
|
||||
err := Replace(&buf, []byte(input4), from, to)
|
||||
err := jsn.Replace(&buf, []byte(input4), from, to)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -428,7 +430,7 @@ func TestReplaceEmpty(t *testing.T) {
|
||||
|
||||
json := `{ "users" : [{"id":1,"full_name":"Sidney St[1]roman","email":"user0@demo.com","__users_twitter_id":"2048666903444506956"}, {"id":2,"full_name":"Jerry Dickinson","email":"user1@demo.com","__users_twitter_id":"2048666903444506956"}, {"id":3,"full_name":"Kenna Cassin","email":"user2@demo.com","__users_twitter_id":"2048666903444506956"}, {"id":4,"full_name":"Mr. Pat Parisian","email":"rodney@kautzer.biz","__users_twitter_id":"2048666903444506956"}, {"id":5,"full_name":"Bette Ebert","email":"janeenrath@goyette.com","__users_twitter_id":"2048666903444506956"}, {"id":6,"full_name":"Everett Kiehn","email":"michael@bartoletti.com","__users_twitter_id":"2048666903444506956"}, {"id":7,"full_name":"Katrina Cronin","email":"loretaklocko@framivolkman.org","__users_twitter_id":"2048666903444506956"}, {"id":8,"full_name":"Caroll Orn Sr.","email":"joannarau@hegmann.io","__users_twitter_id":"2048666903444506956"}, {"id":9,"full_name":"Gwendolyn Ziemann","email":"renaytoy@rutherford.co","__users_twitter_id":"2048666903444506956"}, {"id":10,"full_name":"Mrs. Rosann Fritsch","email":"holliemosciski@thiel.org","__users_twitter_id":"2048666903444506956"}, {"id":11,"full_name":"Arden Koss","email":"cristobalankunding@howewelch.org","__users_twitter_id":"2048666903444506956"}, {"id":12,"full_name":"Brenton Bauch PhD","email":"renee@miller.co","__users_twitter_id":"2048666903444506956"}, {"id":13,"full_name":"Daine Gleichner","email":"andrea@nienow.co","__users_twitter_id":"2048666903444506956"}] }`
|
||||
|
||||
err := Replace(&buf, []byte(json), []Field{}, []Field{})
|
||||
err := jsn.Replace(&buf, []byte(json), []jsn.Field{}, []jsn.Field{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -442,7 +444,7 @@ func TestReplaceEmpty(t *testing.T) {
|
||||
func TestKeys1(t *testing.T) {
|
||||
json := `[{"id":1,"posts": [{"title":"PT1-1","description":"PD1-1"}, {"title":"PT1-2","description":"PD1-2"}], "full_name":"FN1","email":"E1","books": [{"name":"BN1-1","description":"BD1-1"},{"name":"BN1-2","description":"BD1-2"},{"name":"BN1-2","description":"BD1-2"}]},{"id":1,"posts": [{"title":"PT1-1","description":"PD1-1"}, {"title":"PT1-2","description":"PD1-2"}], "full_name":"FN1","email":"E1","books": [{"name":"BN1-1","description":"BD1-1"},{"name":"BN1-2","description":"BD1-2"},{"name":"BN1-2","description":"BD1-2"}]},{"id":1,"posts": [{"title":"PT1-1","description":"PD1-1"}, {"title":"PT1-2","description":"PD1-2"}], "full_name":"FN1","email":"E1","books": [{"name":"BN1-1","description":"BD1-1"},{"name":"BN1-2","description":"BD1-2"},{"name":"BN1-2","description":"BD1-2"}]}]`
|
||||
|
||||
fields := Keys([]byte(json))
|
||||
fields := jsn.Keys([]byte(json))
|
||||
|
||||
exp := []string{
|
||||
"id", "posts", "title", "description", "full_name", "email", "books", "name", "description",
|
||||
@ -462,7 +464,7 @@ func TestKeys1(t *testing.T) {
|
||||
func TestKeys2(t *testing.T) {
|
||||
json := `{"id":1,"posts": [{"title":"PT1-1","description":"PD1-1"}, {"title":"PT1-2","description":"PD1-2"}], "full_name":"FN1","email":"E1","books": [{"name":"BN1-1","description":"BD1-1"},{"name":"BN1-2","description":"BD1-2"},{"name":"BN1-2","description":"BD1-2"}]}`
|
||||
|
||||
fields := Keys([]byte(json))
|
||||
fields := jsn.Keys([]byte(json))
|
||||
|
||||
exp := []string{
|
||||
"id", "posts", "title", "description", "full_name", "email", "books", "name", "description",
|
||||
@ -491,7 +493,7 @@ func TestKeys3(t *testing.T) {
|
||||
"user": 123
|
||||
}`
|
||||
|
||||
fields := Keys([]byte(json))
|
||||
fields := jsn.Keys([]byte(json))
|
||||
|
||||
exp := []string{
|
||||
"insert", "created_at", "test_1a", "type1", "type2", "name", "updated_at", "description",
|
||||
@ -526,7 +528,7 @@ func TestClear(t *testing.T) {
|
||||
|
||||
expected := `{"insert":{"created_at":"","test_1a":{"type1":"","type2":[{"a":0.0}]},"name":"","updated_at":"","description":""},"user":0.0,"tags":[]}`
|
||||
|
||||
err := Clear(&buf, []byte(json))
|
||||
err := jsn.Clear(&buf, []byte(json))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -541,7 +543,7 @@ func BenchmarkGet(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
Get([]byte(input1), [][]byte{[]byte("__twitter_id")})
|
||||
jsn.Get([]byte(input1), [][]byte{[]byte("__twitter_id")})
|
||||
}
|
||||
}
|
||||
|
||||
@ -553,7 +555,7 @@ func BenchmarkFilter(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
err := Filter(&buf, []byte(input2), keys)
|
||||
err := jsn.Filter(&buf, []byte(input2), keys)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@ -566,19 +568,19 @@ func BenchmarkStrip(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
Strip([]byte(input3), path)
|
||||
jsn.Strip([]byte(input3), path)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReplace(b *testing.B) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
from := []Field{
|
||||
from := []jsn.Field{
|
||||
{[]byte("__twitter_id"), []byte(`[{ "name": "hello" }, { "name": "world"}]`)},
|
||||
{[]byte("__twitter_id"), []byte(`"ABC123"`)},
|
||||
}
|
||||
|
||||
to := []Field{
|
||||
to := []jsn.Field{
|
||||
{[]byte("__twitter_id"), []byte(`"1234567890"`)},
|
||||
{[]byte("some_list"), []byte(`[{"id":1,"embed":{"id":8}},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9},{"id":10},{"id":11},{"id":12},{"id":13}]`)},
|
||||
}
|
||||
@ -587,7 +589,7 @@ func BenchmarkReplace(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
err := Replace(&buf, []byte(input4), from, to)
|
||||
err := jsn.Replace(&buf, []byte(input4), from, to)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
@ -133,9 +133,18 @@ func Replace(w *bytes.Buffer, b []byte, from, to []Field) error {
|
||||
if e != 0 {
|
||||
e++
|
||||
|
||||
if e <= s {
|
||||
return errors.New("invalid json")
|
||||
}
|
||||
|
||||
if _, err := h.Write(b[s:e]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if (we + 1) <= ws {
|
||||
return errors.New("invalid json")
|
||||
}
|
||||
|
||||
n, ok := tmap[h.Sum64()]
|
||||
h.Reset()
|
||||
|
||||
|
37
jsn/test.go
37
jsn/test.go
@ -1,37 +0,0 @@
|
||||
package jsn
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func unifiedTest(data []byte) error {
|
||||
err1 := Validate(string(data))
|
||||
|
||||
var b1 bytes.Buffer
|
||||
err2 := Filter(&b1, data, []string{"id", "full_name", "embed"})
|
||||
|
||||
path1 := [][]byte{[]byte("data"), []byte("users")}
|
||||
Strip(data, path1)
|
||||
|
||||
from := []Field{
|
||||
{[]byte("__twitter_id"), []byte(`[{ "name": "hello" }, { "name": "world"}]`)},
|
||||
{[]byte("__twitter_id"), []byte(`"ABC123"`)},
|
||||
}
|
||||
|
||||
to := []Field{
|
||||
{[]byte("__twitter_id"), []byte(`"1234567890"`)},
|
||||
{[]byte("some_list"), []byte(`[{"id":1,"embed":{"id":8}},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9},{"id":10},{"id":11},{"id":12},{"id":13}]`)},
|
||||
}
|
||||
|
||||
var b2 bytes.Buffer
|
||||
err3 := Replace(&b2, data, from, to)
|
||||
|
||||
Keys(data)
|
||||
|
||||
if err1 != nil || err2 != nil || err3 != nil {
|
||||
return errors.New("there was an error")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user