Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.14.2: Breaking change: gjson.GetManyBytes does not respect custom modifiers #290

Closed
janisz opened this issue Aug 9, 2022 · 1 comment · Fixed by #291
Closed

1.14.2: Breaking change: gjson.GetManyBytes does not respect custom modifiers #290

janisz opened this issue Aug 9, 2022 · 1 comment · Fixed by #291

Comments

@janisz
Copy link
Contributor

janisz commented Aug 9, 2022

Consider following tests. It's passing on 1.14.1 but fails on 1.14.2 with

# 1.14.2
Expected :{"_":[["-"]]}
Actual   :{"_":[[]]}
package gjson

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tidwall/gjson"
)

func TestGetManyBytes(t *testing.T) {
	gjson.AddModifier("boolReplace", BoolReplaceModifier())
	rawJson := `{"x":[{"y":[{"z":false}]}]}`
	jsonPathExpr := `{x.#.y.#.z.@boolReplace:{"true":"X","false":"-"}}`
	results := gjson.GetManyBytes([]byte(rawJson), jsonPathExpr)
	assert.Len(t, results, 1)
	actua := results[0].Raw
	expected := `{"_":[["-"]]}`
	assert.Equal(t, expected, actua)
}

// BoolReplaceModifier provides the @boolReplace modifier for gjson which replaces "true" and "false" with the given
// strings, the configuration happens via a json object.
// The JSON object has the following structure:
// {"true": "string-you-want-to-replace-with", "false": "string-you-want-to-replace-with"}
func BoolReplaceModifier() CustomModifier {
	return func(j, arg string) string {
		opts := defaultReplaceBoolOptions()
		if arg != "" {
			gjson.Parse(arg).ForEach(func(key, value gjson.Result) bool {
				switch key.Bool() {
				case true:
					opts.TrueReplace = value.String()
				case false:
					opts.FalseReplace = value.String()
				}
				return true
			})
		}

		res := gjson.Parse(j)
		if res.Type == gjson.True {
			j = strings.ReplaceAll(j, "true", opts.TrueReplace)
		} else if res.Type == gjson.False {
			j = strings.ReplaceAll(j, "false", opts.FalseReplace)
		}
		bytes, _ := json.Marshal(j)
		return string(bytes)
	}
}

Refs: stackrox/stackrox#2654
Introduced in: 475b403

@janisz janisz changed the title 1.14.2: Breaking change: gjson.GetManyBytes does not respect @boolReplace 1.14.2: Breaking change: gjson.GetManyBytes does not respect custom modifiers Aug 9, 2022
@janisz
Copy link
Contributor Author

janisz commented Aug 9, 2022

Here is breaking test for built in modifier

func TestGetManyBytes(t *testing.T) {
	rawJson := `{"x":[{"y":[{"z":{"b":1, "c": 2, "a": 3}}]}]}`
	jsonPathExpr := `x.#.y.#.z.@pretty:{"sortKeys":true}`
	results := gjson.GetManyBytes([]byte(rawJson), jsonPathExpr)
	assert.Len(t, results, 1)
	actua := results[0].Raw
	expected := `[[{
  "a": 3,
  "b": 1,
  "c": 2
}
]]`
	assert.Equal(t, expected, actua)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant