tomnomnom / gron

Make JSON greppable!
MIT License
13.83k stars 327 forks source link

panic with --values #117

Open cben opened 10 months ago

cben commented 10 months ago

I'm probably misunderstanding the purpose of --values flag, but I was trying it on various JSON inputs and saw Go panics in some cases :boom: (and nothing in others).
Here are pretty small reproducers (on latest master), which are weirdly sensitive to whitespace:

$ printf '{"foo": 3}' | ./gron --values
$ printf '{"foo":\n3}' | ./gron --values
$ printf '{"foo":\n  3}' | ./gron --values
panic: runtime error: index out of range [0] with length 0

goroutine 1 [running]:
main.gronValues({0xc000196120?, 0xc00019a010?}, {0xc000192190?, 0x75e498?}, 0x1?)
    /home/beni/gron/main.go:411 +0x2af
main.main()
    /home/beni/gron/main.go:178 +0x6cd
$ printf '{"foo": 3\n}' | ./gron --values
$ printf '{"foo": 3\n  }' | ./gron --values
panic: runtime error: index out of range [0] with length 0

goroutine 1 [running]:
main.gronValues({0xc00007c180?, 0xc000016050?}, {0xc00001a2a8?, 0x75e498?}, 0x1?)
    /home/beni/gron/main.go:411 +0x2af
main.main()
    /home/beni/gron/main.go:178 +0x6cd
kousu commented 5 months ago

I saw this too and was confused. For example if I'm trying to extract some disk details:

$ nvme list -o json | gron -v
panic: runtime error: index out of range [0] with length 0

goroutine 1 [running]:
main.gronValues({0xc000126070?, 0xc00012a010?}, {0xc000142170?, 0x7555d8?}, 0x1?)
    github.com/tomnomnom/gron/main.go:411 +0x27f
main.main()
    github.com/tomnomnom/gron/main.go:178 +0x6bc

The solution is to run gron twice in a row:

$ nvme list -o json | gron | gron -v
/dev/nvme0n1

0
0

1
0
Non-Volatile memory controller: Toshiba Corporation NVMe SSD Controller
1

0
/dev/nvme1n1

1
0

1
0
Non-Volatile memory controller: Toshiba Corporation NVMe SSD Controller
1

0

I think this was probably missed because in practice you'd never use gron by itself, it's meant to be combined with grep, so you'd do something like:

nvme list -o json | gron | grep SerialNumber | gron --values

This is alluded to in the comments:

https://github.com/tomnomnom/gron/blob/badf401da553eb41b7ffde4be6a64809ed0ed846/main.go#L401-L404

but not in the docs and it threw me off too. Maybe it can be explained with an example, or mentioning "Print just the values of gron-format assignments"?

And also it would be better not to panic at all. If the input format is wrong maybe that can become an error message explaining that the format is wrong.