Skip to content

Commit

Permalink
Fix an issue regarding the JSON EscapeHTML flag
Browse files Browse the repository at this point in the history
  • Loading branch information
TomWright committed Oct 18, 2023
1 parent 4e6450b commit 2db336e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 7 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
16 changes: 10 additions & 6 deletions dencoding/json_encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -20,6 +24,7 @@ func NewJSONEncoder(w io.Writer, options ...JSONEncoderOption) *JSONEncoder {
for _, o := range options {
o.ApplyEncoder(encoder)
}
lastOptions = options
return encoder
}

Expand Down Expand Up @@ -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(`,`))
}
Expand Down
42 changes: 42 additions & 0 deletions internal/command/select_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
))

}

0 comments on commit 2db336e

Please sign in to comment.