diff --git a/CHANGELOG.md b/CHANGELOG.md index 99275b4f..092718ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Nothing yet + +## [v2.4.1] - 2023-10-18 + +### Fixed + +- JSON output now acts as expected regarding the EscapeHTML flag. + ## [v2.4.0] - 2023-10-18 ### Added @@ -626,7 +634,8 @@ See [documentation](https://daseldocs.tomwright.me) for all changes. - Everything! -[unreleased]: https://github.com/TomWright/dasel/compare/v2.4.0...HEAD +[unreleased]: https://github.com/TomWright/dasel/compare/v2.4.1...HEAD +[v2.4.1]: https://github.com/TomWright/dasel/compare/v2.4.0...v2.4.1 [v2.4.0]: https://github.com/TomWright/dasel/compare/v2.3.6...v2.4.0 [v2.3.6]: https://github.com/TomWright/dasel/compare/v2.3.5...v2.3.6 [v2.3.5]: https://github.com/TomWright/dasel/compare/v2.3.4...v2.3.5 diff --git a/dencoding/json_encoder.go b/dencoding/json_encoder.go index ded7a071..da060767 100644 --- a/dencoding/json_encoder.go +++ b/dencoding/json_encoder.go @@ -6,6 +6,10 @@ import ( "io" ) +// lastOptions contains the options that the last JSONEncoder was created with. +// Find a better way of passing this information into nested MarshalJSON calls. +var lastOptions []JSONEncoderOption + // JSONEncoder wraps a standard json encoder to implement custom ordering logic. type JSONEncoder struct { encoder *json.Encoder @@ -20,6 +24,7 @@ func NewJSONEncoder(w io.Writer, options ...JSONEncoderOption) *JSONEncoder { for _, o := range options { o.ApplyEncoder(encoder) } + lastOptions = options return encoder } @@ -64,21 +69,20 @@ func (option jsonEncodeIndent) ApplyEncoder(encoder *JSONEncoder) { // MarshalJSON JSON encodes the map and returns the bytes. // This maintains ordering. func (m *Map) MarshalJSON() ([]byte, error) { + buf := new(bytes.Buffer) buf.Write([]byte(`{`)) + encoder := NewJSONEncoder(buf, lastOptions...) for i, key := range m.keys { last := i == len(m.keys)-1 - keyBytes, err := json.Marshal(key) - if err != nil { + + if err := encoder.Encode(key); err != nil { return nil, err } - buf.Write(keyBytes) buf.Write([]byte(`:`)) - valBytes, err := json.Marshal(m.data[key]) - if err != nil { + if err := encoder.Encode(m.data[key]); err != nil { return nil, err } - buf.Write(valBytes) if !last { buf.Write([]byte(`,`)) } diff --git a/internal/command/select_test.go b/internal/command/select_test.go index 332ac9b4..5671ed36 100644 --- a/internal/command/select_test.go +++ b/internal/command/select_test.go @@ -336,4 +336,46 @@ d.e.f`)), nil, )) + t.Run("Issue351 incorrectly escaped html, default false", runTest( + []string{"-r", "json"}, + []byte(`{ + "field1": "A", + "field2": "A > B && B > C" +}`), + newline([]byte(`{ + "field1": "A", + "field2": "A > B && B > C" +}`)), + nil, + nil, + )) + + t.Run("Issue351 incorrectly escaped html, specific false", runTest( + []string{"-r", "json", "--escape-html=false"}, + []byte(`{ + "field1": "A", + "field2": "A > B && B > C" +}`), + newline([]byte(`{ + "field1": "A", + "field2": "A > B && B > C" +}`)), + nil, + nil, + )) + + t.Run("Issue351 correctly escaped html", runTest( + []string{"-r", "json", "--escape-html=true"}, + []byte(`{ + "field1": "A", + "field2": "A > B && B > C" +}`), + newline([]byte(`{ + "field1": "A", + "field2": "A \u003e B \u0026\u0026 B \u003e C" +}`)), + nil, + nil, + )) + }