json-iterator / go

A high-performance 100% compatible drop-in replacement of "encoding/json"
http://jsoniter.com/migrate-from-go-std.html
MIT License
13.43k stars 1.03k forks source link

Valid() function returns true with string started with number which should be false #519

Open M-AIDEZ opened 3 years ago

M-AIDEZ commented 3 years ago

For example:

func TestSomething(t *testing.T) {
    valid := jsoniter.Valid([]byte("abc"))
    require.False(t, valid)
}

returns false and pass the test case, but

func TestSomething(t *testing.T) {
    valid := jsoniter.Valid([]byte("123abc"))
    require.False(t, valid)
}

returns true which shoud be false.

JeckieLI commented 3 years ago

It seems Valid() only skip one json object without checking whether there would be any data left Here is one workaround:

func ValidJson(data []byte) bool {
    iter := jsoniter.ConfigDefault.BorrowIterator(data)
    defer jsoniter.ConfigDefault.ReturnIterator(iter)
    iter.Skip()
    if iter.Error != nil {
        return false
    }
    iter.WhatIsNext()           //  read non-empty character
    return iter.Error == io.EOF // io.EOF means there is no more data to be parsed 
}
WillAbides commented 3 years ago

One more adjustment to add to @JeckieLI's workaround. Skipping number at the end of the file sets iter.Error to io.EOF. A workaround for that is data = append(data, '\n') at the beginning of the func.