mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
70a04f6880
commit
91a6a2a30f
4 changed files with 43 additions and 12 deletions
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue