Skip to content

Pretty JSON output resolves literal object keys as GJSON paths #81

Description

@sylvesterkaczmarek

Summary

The static pretty JSON renderer enumerates object keys literally with @keys, but then reads each value using result.Get(key.Str). gjson.Result.Get interprets its argument as a GJSON path expression, so a JSON key containing path syntax can resolve a different value than the literal key actually owns.

A common example is a key containing a dot.

Reproduction

On current main (d082a010f7c6cacf407d8a1581446a7857f9f1bb), consider:

{
  "a.b": "literal-value",
  "a": {
    "b": "nested-value"
  }
}

formatJSONObject obtains the real top-level keys using:

keys := result.Get("@keys").Array()

but for the "a.b" row it then evaluates:

value := result.Get("a.b")

GJSON treats that as the nested path a -> b, so the row for the literal top-level key "a.b" can display "nested-value" instead of "literal-value".

The literal value can disappear from pretty output entirely even though the underlying JSON is correct.

Root cause

The renderer mixes two different key models:

  • @keys returns literal JSON object member names;
  • Result.Get(string) interprets the supplied string as GJSON path syntax.

Those are equivalent only for keys that contain no GJSON path metacharacters.

Expected behavior

Once an object key has been enumerated, its value should be looked up as a literal object member. Keys such as "a.b", "a*b", or other names meaningful to GJSON's path grammar must display the value stored under that exact JSON key.

Suggested fix

Build the object's literal map once with result.Map() and index it by the enumerated key:

values := result.Map()
...
value := values[key.Str]

Add a regression containing both a top-level dotted key and a nested object whose path would otherwise collide.

Impact

This is output correctness. --format pretty can present a value from a different JSON location under the wrong key, which is particularly misleading when inspecting API responses with user-defined or metadata keys.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions