pquerna / ffjson

faster JSON serialization for Go
Apache License 2.0
2.96k stars 235 forks source link

SetEscapeHTML don't work for pointer types #237

Open Hamper opened 6 years ago

Hamper commented 6 years ago
type T struct {
    A map[string]interface{}
    B map[string]string
    C string
    D Tx
    E *string
    F *Tx
}

type Tx struct {
    A map[string]interface{}
    B map[string]string
    C string
}

func main() {
    s := "test&test"
    x := T{
        A: map[string]interface{}{
            "test": "test&test",
        },
        B: map[string]string{
            "test": "test&test",
        },
        C: "test&test",
        D: Tx{
            A: map[string]interface{}{
                "test": "test&test",
            },
            B: map[string]string{
                "test": "test&test",
            },
            C: "test&test",
        },
        E: &s,
        F: &Tx{
            A: map[string]interface{}{
                "test": "test&test",
            },
            B: map[string]string{
                "test": "test&test",
            },
            C: "test&test",
        },
    }

    buffer := &bytes.Buffer{}
    encoder := json.NewEncoder(buffer)
    encoder.SetEscapeHTML(false)
    _ = encoder.Encode(x)
    fmt.Println(buffer.String())
}

With ffjson:

{"A":{"test":"test&test"},"B":{"test":"test&test"},"C":"test&test","D":{"A":{"test":"test&test"},"B":{"test":"test&test"},"C":"test&test"},"E":"test&test","F":{"A":{"test":"test\u0026test"},"B":{"test":"test\u0026test"},"C":"test\u0026test"}}

Without ffjson:

{"A":{"test":"test&test"},"B":{"test":"test&test"},"C":"test&test","D":{"A":{"test":"test&test"},"B":{"test":"test&test"},"C":"test&test"},"E":"test&test","F":{"A":{"test":"test&test"},"B":{"test":"test&test"},"C":"test&test"}}
jrmarkle commented 5 years ago

SetEscapeHTML() only calls through to the fall-back "encoding/json".Encoder from the standard library. The ffjson generated code always escapes the "HTML unsafe" characters.

If you encode a (non-pointer) struct it will use the fallback encoder because the generated code uses pointer receivers. If you want to use the fast ffjson encoder it will not respect the SetEscapeHTML() call.

I made PR #249 as a possible fix.