Files
ARTEX-chixuweihu/db/jsonb_clean_test.go
T
Autumn-27 16e87b48c2 fix(db): side_question checkpoint 入库前剥除 jsonb 不支持的 NUL 转义
HTTP/工具响应含裸 NUL 字节时,json.Marshal 将其编码为 \u0000 转义,
PostgreSQL jsonb 列拒绝并抛 SQLSTATE 22P05,导致 SaveSideSnapshot 的
INSERT 每秒失败数十次刷屏。新增 jsonbClean 在 marshal 后剥除真正的
\u0000 转义(按前置反斜杠奇偶判断,避免误伤字面 \\u0000),并订正
exploration.go 中 "json.Marshal already sanitizes" 的错误注释。

Closes #111, Closes #112
2026-09-12 03:00:28 -04:00

45 lines
1.3 KiB
Go

package db
import (
"encoding/json"
"strings"
"testing"
)
func TestJsonbClean(t *testing.T) {
// A marshaled payload carrying a NUL byte (e.g. captured HTTP/tool output).
b, err := json.Marshal(map[string]string{"body": "ab\x00cd"})
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(b), `\u0000`) {
t.Fatalf("precondition: marshaled JSON should contain the NUL escape, got %s", b)
}
cleaned := jsonbClean(b)
if strings.Contains(string(cleaned), `\u0000`) {
t.Fatalf("jsonbClean left a NUL escape jsonb rejects: %s", cleaned)
}
// Result must stay valid JSON with the NUL simply dropped.
var out map[string]string
if err := json.Unmarshal(cleaned, &out); err != nil {
t.Fatalf("cleaned bytes are not valid JSON: %v (%s)", err, cleaned)
}
if out["body"] != "abcd" {
t.Fatalf("expected NUL stripped to \"abcd\", got %q", out["body"])
}
// A NUL escape typed literally in source text (doubled backslash) is preserved.
lit := []byte(`{"body":"\\u0000"}`)
if got := jsonbClean(lit); string(got) != string(lit) {
t.Fatalf("literal \\\\u0000 must be untouched, got %s", got)
}
// No NUL escape → returned unchanged.
plain := []byte(`{"body":"hello"}`)
if got := jsonbClean(plain); string(got) != string(plain) {
t.Fatalf("plain JSON must be untouched, got %s", got)
}
}