diff options
| author | Joe Tsai <joetsai@digital-static.net> | 2017-12-05 22:53:48 -0800 |
|---|---|---|
| committer | Joe Tsai <thebrokentoaster@gmail.com> | 2018-02-14 21:34:26 +0000 |
| commit | 91a6a2a30f95da8ae3fb6329a71c49ed13aa12ad (patch) | |
| tree | 1924c3c82b14e38b9d9e22e2227d7661b8804a77 /src/encoding/json/decode.go | |
| parent | 70a04f6880a2082a76f6282361b607f859db950f (diff) | |
| download | go-91a6a2a30f95da8ae3fb6329a71c49ed13aa12ad.tar.xz | |
encoding/json: make error capture logic in recover more type safe
Rather than only ignoring runtime.Error panics, which are a very
narrow set of possible panic values, switch it such that the json
package only captures panic values that have been properly wrapped
in a jsonError struct. This ensures that only intentional panics
originating from the json package are captured.
Fixes #23012
Change-Id: I5e85200259edd2abb1b0512ce6cc288849151a6d
Reviewed-on: https://go-review.googlesource.com/94019
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/encoding/json/decode.go')
| -rw-r--r-- | src/encoding/json/decode.go | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go index 536f25dc7c..f08b0a1c58 100644 --- a/src/encoding/json/decode.go +++ b/src/encoding/json/decode.go @@ -14,7 +14,6 @@ import ( "errors" "fmt" "reflect" - "runtime" "strconv" "unicode" "unicode/utf16" @@ -168,13 +167,19 @@ func (e *InvalidUnmarshalError) Error() string { return "json: Unmarshal(nil " + e.Type.String() + ")" } +// jsonError is an error wrapper type for internal use only. +// Panics with errors are wrapped in jsonError so that the top-level recover +// can distinguish intentional panics from this package. +type jsonError struct{ error } + func (d *decodeState) unmarshal(v interface{}) (err error) { defer func() { if r := recover(); r != nil { - if _, ok := r.(runtime.Error); ok { + if je, ok := r.(jsonError); ok { + err = je.error + } else { panic(r) } - err = r.(error) } }() @@ -295,9 +300,9 @@ func (d *decodeState) init(data []byte) *decodeState { return d } -// error aborts the decoding by panicking with err. +// error aborts the decoding by panicking with err wrapped in jsonError. func (d *decodeState) error(err error) { - panic(d.addErrorContext(err)) + panic(jsonError{d.addErrorContext(err)}) } // saveError saves the first err it is called with, |
