大佬们,为什么go的json.valid()方法可以通过数字型字符串啊(是否有其他验证是否是json字符串的方式)

hengbo · 2023-01-09 17:32:28 · 1839 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2023-01-09 17:32:28 的主题,其中的信息可能已经有所发展或是发生改变。

func TestValidatJson(t *testing.T) {
        // 使用gin框架的tag验证也是这样
    //validate := validator.New()
    //err := validate.Struct(struct {
    //    Tmp string `json:"tmp" validate:"json"`
    //}{
    //    Tmp: "655452255",
    //})
    //if err != nil {
    //    fmt.Println(err)
    //}
    fmt.Println(json.Valid([]byte("6666666")), json.Valid([]byte("霍山石斛")))
}

输出如下:

=== RUN   TestValidatJson
true false
--- PASS: TestValidatJson (0.00s)
PASS

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1839 次点击  ∙  1 赞  
加入收藏 微博
4 回复  |  直到 2023-01-10 19:07:46
don178
don178 · #1 · 2年之前

github.com/json-iterator/go

用这个

编译gin项目时 :

go build -tags=jsoniter .
jan-bar
jan-bar · #2 · 2年之前

调试一下,追追源码,如下所示,那些字符串起始字符都是合法的。中文明显不能是json起始字符,所以错误。

按照源码规则,一串数字字符串是合法的json字符串。

github.com/json-iterator/go 这个库也会判断起始位数字字符串是合法的,但是该库认为数字结束至少需要其他字符,例如}@don178 因此三方库也不靠谱。并且有个 issues 官方貌似一直没处理。

搜狗截图20230110094447.jpg

func stateBeginValue(s *scanner, c byte) int {
    if isSpace(c) {
        return scanSkipSpace
    }

        // 下面表示验证字符串起始字符,只要符合其中一种就算正常json,按照第一个字符确定下一个字符判断规则,及赋值step
    switch c {
    case '{':
        s.step = stateBeginStringOrEmpty
        return s.pushParseState(c, parseObjectKey, scanBeginObject)
    case '[':
        s.step = stateBeginValueOrEmpty
        return s.pushParseState(c, parseArrayValue, scanBeginArray)
    case '"':
        s.step = stateInString
        return scanBeginLiteral
    case '-':
        s.step = stateNeg
        return scanBeginLiteral
    case '0': // beginning of 0.123
        s.step = state0
        return scanBeginLiteral
    case 't': // beginning of true
        s.step = stateT
        return scanBeginLiteral
    case 'f': // beginning of false
        s.step = stateF
        return scanBeginLiteral
    case 'n': // beginning of null
        s.step = stateN
        return scanBeginLiteral
    }
    if '1' <= c && c <= '9' { // beginning of 1234.5
        s.step = state1
        return scanBeginLiteral  // 最终会走到这里,表示下一个字符扫描数字
    }
    return s.error(c, "looking for beginning of value")
}
hengbo
hengbo · #3 · 2年之前
jan-barjan-bar #2 回复

调试一下,追追源码,如下所示,那些字符串起始字符都是合法的。中文明显不能是json起始字符,所以错误。 按照源码规则,一串数字字符串是合法的json字符串。 `github.com/json-iterator/go` 这个库也会判断起始位数字字符串是合法的,但是该库认为数字结束至少需要其他字符,例如`}`, @don178 因此三方库也不靠谱。并且有个 [issues](https://github.com/json-iterator/go/issues/519) 官方貌似一直没处理。 ![搜狗截图20230110094447.jpg](https://static.golangjob.cn/230110/6a62466e8d290cfbc66d6c875fe4d661.jpg) ```go func stateBeginValue(s *scanner, c byte) int { if isSpace(c) { return scanSkipSpace } // 下面表示验证字符串起始字符,只要符合其中一种就算正常json,按照第一个字符确定下一个字符判断规则,及赋值step switch c { case '{': s.step = stateBeginStringOrEmpty return s.pushParseState(c, parseObjectKey, scanBeginObject) case '[': s.step = stateBeginValueOrEmpty return s.pushParseState(c, parseArrayValue, scanBeginArray) case '"': s.step = stateInString return scanBeginLiteral case '-': s.step = stateNeg return scanBeginLiteral case '0': // beginning of 0.123 s.step = state0 return scanBeginLiteral case 't': // beginning of true s.step = stateT return scanBeginLiteral case 'f': // beginning of false s.step = stateF return scanBeginLiteral case 'n': // beginning of null s.step = stateN return scanBeginLiteral } if '1' <= c && c <= '9' { // beginning of 1234.5 s.step = state1 return scanBeginLiteral // 最终会走到这里,表示下一个字符扫描数字 } return s.error(c, "looking for beginning of value") } ```

感谢解答🤞

hengbo
hengbo · #4 · 2年之前
don178don178 #1 回复

github.com/json-iterator/go 用这个 编译gin项目时 : ``` go build -tags=jsoniter . ```

感谢解答🤞

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传