Skip to content

EachKey using local stack for []byte and unsafe for []byte to string and getting burned #165

@FrankReh

Description

@FrankReh

Only a bug for keys traversed by EachKey that need unescaping. Probably rare. I would never have a key with a newline in it myself ;), but the code tries to handle it so someone might get burned.

Because EachKey wants to use its own stack to store a short key in a buffer when the key needs to be unescaped, and because it does this in a loop as the data structure levels are traversed, an earlier cached key's value can be modified. Here's a small example of a single path that works if there are no newlines in the strings but fails as is because of this bug. Fix for me is to change the array size of the special stack variable to 0 in EachKey, effectively disabling use of the stack, so a []byte buffer is allocated each time there is an unescaped key in a path.

package main

import (
	"fmt"
	"github.com/buger/jsonparser"
)

func ExampleEachKeyBrokenWithBackingStore() {
	raw := `{"a\n":{"b\n":99}}`
	paths := [][]string{
		[]string{"a\n", "b\n"},
	}
	jsonparser.EachKey([]byte(raw),
		func(idx int, value []byte, dataType jsonparser.ValueType, err error) {
			fmt.Println("matches", idx, string(value))
		}, paths...)

	// Output:
	// matches 0 99
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions