Add errchkjson linter (#2362)
This commit is contained in:
parent
fc888cf0cb
commit
55358972d6
@ -137,6 +137,24 @@ linters-settings:
|
||||
- io.Copy(*bytes.Buffer)
|
||||
- io.Copy(os.Stdout)
|
||||
|
||||
errchkjson:
|
||||
# with check-error-free-encoding set to true, errchkjson does warn about errors
|
||||
# from json encoding functions that are safe to be ignored,
|
||||
# because they are not possible to happen (default false)
|
||||
#
|
||||
# if check-error-free-encoding is set to true and errcheck linter is enabled,
|
||||
# it is recommended to add the following exceptions to prevent from false positives:
|
||||
#
|
||||
# linters-settings:
|
||||
# errcheck:
|
||||
# exclude-functions:
|
||||
# - encoding/json.Marshal
|
||||
# - encoding/json.MarshalIndent
|
||||
# - (*encoding/json.Encoder).Encode
|
||||
check-error-free-encoding: false
|
||||
# if report-no-exported is true, encoding a struct without exported fields is reported as issue (default false)
|
||||
report-no-exported: false
|
||||
|
||||
errorlint:
|
||||
# Check whether fmt.Errorf uses the %w verb for formatting errors. See the readme for caveats
|
||||
errorf: true
|
||||
|
1
go.mod
1
go.mod
@ -16,6 +16,7 @@ require (
|
||||
github.com/blizzy78/varnamelen v0.5.0
|
||||
github.com/bombsimon/wsl/v3 v3.3.0
|
||||
github.com/breml/bidichk v0.2.1
|
||||
github.com/breml/errchkjson v0.2.0
|
||||
github.com/butuzov/ireturn v0.1.1
|
||||
github.com/charithe/durationcheck v0.0.9
|
||||
github.com/daixiang0/gci v0.2.9
|
||||
|
2
go.sum
generated
2
go.sum
generated
@ -108,6 +108,8 @@ github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxj
|
||||
github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=
|
||||
github.com/breml/bidichk v0.2.1 h1:SRNtZuLdfkxtocj+xyHXKC1Uv3jVi6EPYx+NHSTNQvE=
|
||||
github.com/breml/bidichk v0.2.1/go.mod h1:zbfeitpevDUGI7V91Uzzuwrn4Vls8MoBMrwtt78jmso=
|
||||
github.com/breml/errchkjson v0.2.0 h1:5XK9tXXqahYiPHuJ5Asx9a5ucpASxLMxq3EvQyLb26c=
|
||||
github.com/breml/errchkjson v0.2.0/go.mod h1:jZEATw/jF69cL1iy7//Yih8yp/mXp2CBoBr9GJwCAsY=
|
||||
github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY=
|
||||
github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
|
@ -89,6 +89,7 @@ type LintersSettings struct {
|
||||
Dogsled DogsledSettings
|
||||
Dupl DuplSettings
|
||||
Errcheck ErrcheckSettings
|
||||
ErrChkJSON ErrChkJSONSettings
|
||||
ErrorLint ErrorLintSettings
|
||||
Exhaustive ExhaustiveSettings
|
||||
ExhaustiveStruct ExhaustiveStructSettings
|
||||
@ -165,6 +166,11 @@ type Cyclop struct {
|
||||
SkipTests bool `mapstructure:"skip-tests"`
|
||||
}
|
||||
|
||||
type ErrChkJSONSettings struct {
|
||||
CheckErrorFreeEncoding bool `mapstructure:"check-error-free-encoding"`
|
||||
ReportNoExported bool `mapstructure:"report-no-exported"`
|
||||
}
|
||||
|
||||
type DepGuardSettings struct {
|
||||
ListType string `mapstructure:"list-type"`
|
||||
Packages []string
|
||||
|
33
pkg/golinters/errchkjson.go
Normal file
33
pkg/golinters/errchkjson.go
Normal file
@ -0,0 +1,33 @@
|
||||
package golinters
|
||||
|
||||
import (
|
||||
"github.com/breml/errchkjson"
|
||||
"golang.org/x/tools/go/analysis"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg/config"
|
||||
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
|
||||
)
|
||||
|
||||
func NewErrChkJSONFuncName(cfg *config.ErrChkJSONSettings) *goanalysis.Linter {
|
||||
a := errchkjson.NewAnalyzer()
|
||||
|
||||
cfgMap := map[string]map[string]interface{}{}
|
||||
cfgMap[a.Name] = map[string]interface{}{
|
||||
"omit-safe": true,
|
||||
}
|
||||
if cfg != nil {
|
||||
cfgMap[a.Name] = map[string]interface{}{
|
||||
"omit-safe": !cfg.CheckErrorFreeEncoding,
|
||||
"report-no-exported": cfg.ReportNoExported,
|
||||
}
|
||||
}
|
||||
|
||||
return goanalysis.NewLinter(
|
||||
"errchkjson",
|
||||
"Checks types passed to the json encoding functions. "+
|
||||
"Reports unsupported types and optionally reports occations, "+
|
||||
"where the check for the returned error can be omitted.",
|
||||
[]*analysis.Analyzer{a},
|
||||
cfgMap,
|
||||
).WithLoadMode(goanalysis.LoadModeTypesInfo)
|
||||
}
|
@ -102,6 +102,7 @@ func enableLinterConfigs(lcs []*linter.Config, isEnabled func(lc *linter.Config)
|
||||
func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
||||
var bidichkCfg *config.BiDiChkSettings
|
||||
var cyclopCfg *config.Cyclop
|
||||
var errchkjsonCfg *config.ErrChkJSONSettings
|
||||
var errorlintCfg *config.ErrorLintSettings
|
||||
var exhaustiveCfg *config.ExhaustiveSettings
|
||||
var exhaustiveStructCfg *config.ExhaustiveStructSettings
|
||||
@ -129,6 +130,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
||||
if m.cfg != nil {
|
||||
bidichkCfg = &m.cfg.LintersSettings.BiDiChk
|
||||
cyclopCfg = &m.cfg.LintersSettings.Cyclop
|
||||
errchkjsonCfg = &m.cfg.LintersSettings.ErrChkJSON
|
||||
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
|
||||
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
|
||||
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
|
||||
@ -548,6 +550,11 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
||||
WithSince("1.43.0").
|
||||
WithPresets(linter.PresetBugs).
|
||||
WithURL("https://github.com/breml/bidichk"),
|
||||
linter.NewConfig(golinters.NewErrChkJSONFuncName(errchkjsonCfg)).
|
||||
WithSince("1.44.0").
|
||||
WithPresets(linter.PresetBugs).
|
||||
WithLoadForGoAnalysis().
|
||||
WithURL("https://github.com/breml/errchkjson"),
|
||||
|
||||
// nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
|
||||
linter.NewConfig(golinters.NewNoLintLint()).
|
||||
|
2
test/testdata/configs/errchkjson.yml
vendored
Normal file
2
test/testdata/configs/errchkjson.yml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
issues:
|
||||
max-issues-per-linter: 100
|
5
test/testdata/configs/errchkjson_check_error_free_encoding.yml
vendored
Normal file
5
test/testdata/configs/errchkjson_check_error_free_encoding.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
issues:
|
||||
max-issues-per-linter: 100
|
||||
linters-settings:
|
||||
errchkjson:
|
||||
check-error-free-encoding: true
|
3
test/testdata/configs/errchkjson_no_exported.yml
vendored
Normal file
3
test/testdata/configs/errchkjson_no_exported.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
linters-settings:
|
||||
errchkjson:
|
||||
report-no-exported: true
|
641
test/testdata/errchkjson.go
vendored
Normal file
641
test/testdata/errchkjson.go
vendored
Normal file
@ -0,0 +1,641 @@
|
||||
// args: -Eerrchkjson
|
||||
// config_path: testdata/configs/errchkjson.yml
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type marshalText struct{}
|
||||
|
||||
func (mt marshalText) MarshalText() ([]byte, error) {
|
||||
return []byte(`mt`), nil
|
||||
}
|
||||
|
||||
var _ encoding.TextMarshaler = marshalText(struct{}{})
|
||||
|
||||
// JSONMarshalSafeTypesWithNoSafe contains a multitude of test cases to marshal different combinations of types to JSON,
|
||||
// that are safe, that is, they will never return an error, if these types are marshaled to JSON.
|
||||
func JSONMarshalSafeTypesWithNoSafe() {
|
||||
var err error
|
||||
|
||||
_, _ = json.Marshal(nil) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
json.Marshal(nil) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(nil) // nil is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
_, _ = json.MarshalIndent(nil, "", " ") // ERROR "Error return value of `encoding/json.MarshalIndent` is not checked"
|
||||
json.MarshalIndent(nil, "", " ") // ERROR "Error return value of `encoding/json.MarshalIndent` is not checked"
|
||||
_, err = json.MarshalIndent(nil, "", " ") // nil is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
enc := json.NewEncoder(ioutil.Discard)
|
||||
_ = enc.Encode(nil) // ERROR "Error return value of `\\([*]encoding/json.Encoder\\).Encode` is not checked"
|
||||
enc.Encode(nil) // ERROR "Error return value of `\\([*]encoding/json.Encoder\\).Encode` is not checked"
|
||||
err = enc.Encode(nil) // nil is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var b bool
|
||||
_, _ = json.Marshal(b) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(b) // bool is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var i int
|
||||
_, _ = json.Marshal(i) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(i) // int is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var i8 int8
|
||||
_, _ = json.Marshal(i8) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(i8) // int8 is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var i16 int16
|
||||
_, _ = json.Marshal(i16) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(i16) // int16 is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var i32 int32
|
||||
_, _ = json.Marshal(i32) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(i32) // int32 / rune is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var i64 int64
|
||||
_, _ = json.Marshal(i64) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(i64) // int64 is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var ui uint
|
||||
_, _ = json.Marshal(ui) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(ui) // uint is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var ui8 uint8
|
||||
_, _ = json.Marshal(ui8) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(ui8) // uint8 is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var ui16 uint16
|
||||
_, _ = json.Marshal(ui16) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(ui16) // uint16 is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var ui32 uint32
|
||||
_, _ = json.Marshal(ui32) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(ui32) // uint32 is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var ui64 uint64
|
||||
_, _ = json.Marshal(ui64) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(ui64) // uint64 is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var uiptr uintptr
|
||||
_, _ = json.Marshal(uiptr) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(uiptr) // uintptr is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var str string
|
||||
_, _ = json.Marshal(str) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(str) // string is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var strSlice []string
|
||||
_, _ = json.Marshal(strSlice) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(strSlice) // []string is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var intSlice []int
|
||||
_, _ = json.Marshal(intSlice) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(intSlice) // []int is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var boolSlice []bool
|
||||
_, _ = json.Marshal(boolSlice) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(boolSlice) // []bool is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var strArray [10]string
|
||||
_, _ = json.Marshal(strArray) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(strArray) // [10]string is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var intArray [10]int
|
||||
_, _ = json.Marshal(intArray) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(intArray) // [10]int is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var boolArray [10]bool
|
||||
_, _ = json.Marshal(boolArray) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(boolArray) // [10]bool is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var basicStruct struct {
|
||||
Bool bool
|
||||
Int int
|
||||
Int8 int8
|
||||
Int16 int16
|
||||
Int32 int32 // also rune
|
||||
Int64 int64
|
||||
Uint uint
|
||||
Uint8 uint8 // also byte
|
||||
Uint16 uint16
|
||||
Uint32 uint32
|
||||
Uint64 uint64
|
||||
Uintptr uintptr
|
||||
String string
|
||||
}
|
||||
_, _ = json.Marshal(basicStruct) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(basicStruct) // struct containing only safe basic types is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var ptrStruct struct {
|
||||
Bool *bool
|
||||
Int *int
|
||||
Int8 *int8
|
||||
Int16 *int16
|
||||
Int32 *int32
|
||||
Int64 *int64
|
||||
Uint *uint
|
||||
Uint8 *uint8
|
||||
Uint16 *uint16
|
||||
Uint32 *uint32
|
||||
Uint64 *uint64
|
||||
Uintptr *uintptr
|
||||
String *string
|
||||
}
|
||||
_, _ = json.Marshal(ptrStruct) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(ptrStruct) // struct containing pointer to only safe basic types is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var mapStrStr map[string]string
|
||||
_, _ = json.Marshal(mapStrStr) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(mapStrStr) // map[string]string is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var mapStrInt map[string]int
|
||||
_, _ = json.Marshal(mapStrInt) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(mapStrInt) // map[string]int is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var mapStrBool map[string]bool
|
||||
_, _ = json.Marshal(mapStrBool) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(mapStrBool) // map[string]bool is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var mapIntStr map[int]string
|
||||
_, _ = json.Marshal(mapIntStr) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(mapIntStr) // map[int]string is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var mapIntInt map[int]int
|
||||
_, _ = json.Marshal(mapIntInt) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(mapIntInt) // map[int]int is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
var mapIntBool map[int]bool
|
||||
_, _ = json.Marshal(mapIntBool) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(mapIntBool) // map[int]bool is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
|
||||
type innerStruct struct {
|
||||
Bool bool
|
||||
Int int
|
||||
String string
|
||||
|
||||
StrSlice []string
|
||||
IntSlice []int
|
||||
BoolSlice []bool
|
||||
|
||||
StrArray [10]string
|
||||
IntArray [10]int
|
||||
BoolArray [10]bool
|
||||
|
||||
MapStrStr map[string]string
|
||||
MapStrInt map[string]int
|
||||
MapStrBool map[string]bool
|
||||
|
||||
MapIntStr map[int]string
|
||||
MapIntInt map[int]int
|
||||
MapIntBool map[int]bool
|
||||
}
|
||||
var outerStruct struct {
|
||||
Bool bool
|
||||
Int int
|
||||
String string
|
||||
|
||||
StrSlice []string
|
||||
IntSlice []int
|
||||
BoolSlice []bool
|
||||
|
||||
StrArray [10]string
|
||||
IntArray [10]int
|
||||
BoolArray [10]bool
|
||||
|
||||
MapStrStr map[string]string
|
||||
MapStrInt map[string]int
|
||||
MapStrBool map[string]bool
|
||||
|
||||
MapIntStr map[int]string
|
||||
MapIntInt map[int]int
|
||||
MapIntBool map[int]bool
|
||||
|
||||
InnerStruct innerStruct
|
||||
}
|
||||
_, _ = json.Marshal(outerStruct) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(outerStruct) // struct with only safe types is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
}
|
||||
|
||||
type (
|
||||
structKey struct{ id int }
|
||||
ExportedUnsafeAndInvalidStruct struct { // unsafe unexported but omitted
|
||||
F64 float64
|
||||
F64Ptr *float64
|
||||
F64Slice []float64
|
||||
F64Array [10]float64
|
||||
MapStrF64 map[string]float64
|
||||
MapEIStr map[interface{}]string
|
||||
Number json.Number
|
||||
NumberPtr *json.Number
|
||||
NumberSlice []json.Number
|
||||
MapNumberStr map[json.Number]string
|
||||
Ei interface{}
|
||||
Stringer fmt.Stringer
|
||||
Mt marshalText
|
||||
MapMarshalTextString map[marshalText]string
|
||||
|
||||
C128 complex128
|
||||
C128Ptr *complex128
|
||||
C128Slice []complex128
|
||||
C128Array [10]complex128
|
||||
MapBoolStr map[bool]string
|
||||
MapF64Str map[float64]string
|
||||
F func()
|
||||
Ch chan struct{}
|
||||
UnsafePtr unsafe.Pointer
|
||||
MapStructStr map[structKey]string
|
||||
}
|
||||
)
|
||||
|
||||
// JSONMarshalSafeStructWithUnexportedFieldsWithNoSafe contains a struct with unexported, unsafe fields.
|
||||
func JSONMarshalSaveStructWithUnexportedFieldsWithNoSafe() {
|
||||
var err error
|
||||
|
||||
var unexportedInStruct struct {
|
||||
Bool bool // safe exported
|
||||
|
||||
f64 float64 // unsafe unexported
|
||||
f64Ptr *float64 // unsafe unexported
|
||||
f64Slice []float64 // unsafe unexported
|
||||
f64Array [10]float64 // unsafe unexported
|
||||
mapStrF64 map[string]float64 // unsafe unexported
|
||||
mapEIStr map[interface{}]string // unsafe unexported
|
||||
number json.Number // unsafe unexported
|
||||
numberPtr *json.Number // unsafe unexported
|
||||
numberSlice []json.Number // unsafe unexported
|
||||
mapNumberStr map[json.Number]string // unsafe unexported
|
||||
ei interface{} // unsafe unexported
|
||||
stringer fmt.Stringer // unsafe unexported
|
||||
mt marshalText // unsafe unexported
|
||||
mapMarshalTextString map[marshalText]string // unsafe unexported
|
||||
unexportedStruct ExportedUnsafeAndInvalidStruct // unsafe unexported
|
||||
unexportedStructPtr *ExportedUnsafeAndInvalidStruct // unsafe unexported
|
||||
|
||||
c128 complex128 // invalid unexported
|
||||
c128Slice []complex128 // invalid unexported
|
||||
c128Array [10]complex128 // invalid unexported
|
||||
mapBoolStr map[bool]string // invalid unexported
|
||||
mapF64Str map[float64]string // invalid unexported
|
||||
f func() // invalid unexported
|
||||
ch chan struct{} // invalid unexported
|
||||
unsafePtr unsafe.Pointer // invalid unexported
|
||||
mapStructStr map[structKey]string // invalid unexported
|
||||
}
|
||||
_ = unexportedInStruct.f64
|
||||
_ = unexportedInStruct.f64Ptr
|
||||
_ = unexportedInStruct.f64Slice
|
||||
_ = unexportedInStruct.f64Array
|
||||
_ = unexportedInStruct.mapStrF64
|
||||
_ = unexportedInStruct.mapEIStr
|
||||
_ = unexportedInStruct.number
|
||||
_ = unexportedInStruct.numberPtr
|
||||
_ = unexportedInStruct.numberSlice
|
||||
_ = unexportedInStruct.mapNumberStr
|
||||
_ = unexportedInStruct.ei
|
||||
_ = unexportedInStruct.stringer
|
||||
_ = unexportedInStruct.mt
|
||||
_ = unexportedInStruct.mapMarshalTextString
|
||||
_ = unexportedInStruct.unexportedStruct
|
||||
_ = unexportedInStruct.unexportedStructPtr
|
||||
|
||||
_ = unexportedInStruct.c128
|
||||
_ = unexportedInStruct.c128Slice
|
||||
_ = unexportedInStruct.c128Array
|
||||
_ = unexportedInStruct.mapBoolStr
|
||||
_ = unexportedInStruct.mapF64Str
|
||||
_ = unexportedInStruct.f
|
||||
_ = unexportedInStruct.ch
|
||||
_ = unexportedInStruct.unsafePtr
|
||||
_ = unexportedInStruct.mapStructStr[structKey{1}]
|
||||
_, _ = json.Marshal(unexportedInStruct) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(unexportedInStruct) // struct containing unsafe but unexported fields is safe
|
||||
_ = err
|
||||
}
|
||||
|
||||
// JSONMarshalSafeStructWithOmittedFieldsWithNoSafe contains a struct with omitted, unsafe fields.
|
||||
func JSONMarshalSaveStructWithOmittedFieldsWithNoSafe() {
|
||||
var err error
|
||||
|
||||
var omitInStruct struct {
|
||||
Bool bool // safe exported
|
||||
|
||||
F64 float64 `json:"-"` // unsafe exported but omitted
|
||||
F64Ptr *float64 `json:"-"` // unsafe exported but omitted
|
||||
F64Slice []float64 `json:"-"` // unsafe exported but omitted
|
||||
F64Array [10]float64 `json:"-"` // unsafe exported but omitted
|
||||
MapStrF64 map[string]float64 `json:"-"` // unsafe exported but omitted
|
||||
MapEIStr map[interface{}]string `json:"-"` // unsafe exported but omitted
|
||||
Number json.Number `json:"-"` // unsafe exported but omitted
|
||||
NumberPtr *json.Number `json:"-"` // unsafe exported but omitted
|
||||
NumberSlice []json.Number `json:"-"` // unsafe exported but omitted
|
||||
MapNumberStr map[json.Number]string `json:"-"` // unsafe exported but omitted
|
||||
Ei interface{} `json:"-"` // unsafe exported but omitted
|
||||
Stringer fmt.Stringer `json:"-"` // unsafe exported but omitted
|
||||
Mt marshalText `json:"-"` // unsafe exported but omitted
|
||||
MapMarshalTextString map[marshalText]string `json:"-"` // unsafe exported but omitted
|
||||
ExportedStruct ExportedUnsafeAndInvalidStruct `json:"-"` // unsafe exported but omitted
|
||||
ExportedStructPtr *ExportedUnsafeAndInvalidStruct `json:"-"` // unsafe exported but omitted
|
||||
|
||||
C128 complex128 `json:"-"` // invalid exported but omitted
|
||||
C128Slice []complex128 `json:"-"` // invalid exported but omitted
|
||||
C128Array [10]complex128 `json:"-"` // invalid exported but omitted
|
||||
MapBoolStr map[bool]string `json:"-"` // invalid exported but omitted
|
||||
MapF64Str map[float64]string `json:"-"` // invalid exported but omitted
|
||||
F func() `json:"-"` // invalid exported but omitted
|
||||
Ch chan struct{} `json:"-"` // invalid exported but omitted
|
||||
UnsafePtr unsafe.Pointer `json:"-"` // invalid exported but omitted
|
||||
MapStructStr map[structKey]string `json:"-"` // invalid exported but omitted
|
||||
}
|
||||
_ = omitInStruct.MapStructStr[structKey{1}]
|
||||
_, _ = json.Marshal(omitInStruct) // ERROR "Error return value of `encoding/json.Marshal` is not checked"
|
||||
_, err = json.Marshal(omitInStruct) // struct containing unsafe but omitted, exported fields is safe and check-error-free-encoding is false
|
||||
_ = err
|
||||
}
|
||||
|
||||
// JSONMarshalUnsafeTypes contains a multitude of test cases to marshal different combinations of types to JSON,
|
||||
// that can potentially lead to json.Marshal returning an error.
|
||||
func JSONMarshalUnsafeTypes() {
|
||||
var err error
|
||||
|
||||
var f32 float32
|
||||
json.Marshal(f32) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, _ = json.Marshal(f32) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, err = json.Marshal(f32) // err is checked
|
||||
_ = err
|
||||
|
||||
var f64 float64
|
||||
_, _ = json.Marshal(f64) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
|
||||
_, err = json.Marshal(f64) // err is checked
|
||||
_ = err
|
||||
|
||||
var f32Slice []float32
|
||||
_, _ = json.Marshal(f32Slice) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, err = json.Marshal(f32Slice) // err is checked
|
||||
_ = err
|
||||
|
||||
var f64Slice []float64
|
||||
_, _ = json.Marshal(f64Slice) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
|
||||
_, err = json.Marshal(f64Slice) // err is checked
|
||||
_ = err
|
||||
|
||||
var f32Array [10]float32
|
||||
_, _ = json.Marshal(f32Array) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, err = json.Marshal(f32Array) // err is checked
|
||||
_ = err
|
||||
|
||||
var f64Array [10]float64
|
||||
_, _ = json.Marshal(f64Array) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
|
||||
_, err = json.Marshal(f64Array) // err is checked
|
||||
_ = err
|
||||
|
||||
var structPtrF32 struct {
|
||||
F32 *float32
|
||||
}
|
||||
_, _ = json.Marshal(structPtrF32) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, err = json.Marshal(structPtrF32) // err is checked
|
||||
_ = err
|
||||
|
||||
var structPtrF64 struct {
|
||||
F64 *float64
|
||||
}
|
||||
_, _ = json.Marshal(structPtrF64) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
|
||||
_, err = json.Marshal(structPtrF64) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapStrF32 map[string]float32
|
||||
_, _ = json.Marshal(mapStrF32) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, err = json.Marshal(mapStrF32) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapStrF64 map[string]float64
|
||||
_, _ = json.Marshal(mapStrF64) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
|
||||
_, err = json.Marshal(mapStrF64) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapEIStr map[interface{}]string
|
||||
_, _ = json.Marshal(mapEIStr) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` as map key found"
|
||||
_, err = json.Marshal(mapEIStr) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapStringerStr map[fmt.Stringer]string
|
||||
_, _ = json.Marshal(mapStringerStr) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `fmt.Stringer` as map key found"
|
||||
_, err = json.Marshal(mapStringerStr) // err is checked
|
||||
_ = err
|
||||
|
||||
var number json.Number
|
||||
_, _ = json.Marshal(number) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
|
||||
_, err = json.Marshal(number) // err is checked
|
||||
_ = err
|
||||
|
||||
var numberSlice []json.Number
|
||||
_, _ = json.Marshal(numberSlice) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
|
||||
_, err = json.Marshal(numberSlice) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapNumberStr map[json.Number]string
|
||||
_, _ = json.Marshal(mapNumberStr) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` as map key found"
|
||||
_, err = json.Marshal(mapNumberStr) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapStrNumber map[string]json.Number
|
||||
_, _ = json.Marshal(mapStrNumber) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
|
||||
_, err = json.Marshal(mapStrNumber) // err is checked
|
||||
_ = err
|
||||
|
||||
var ei interface{}
|
||||
_, _ = json.Marshal(ei) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found"
|
||||
_, err = json.Marshal(ei) // err is checked
|
||||
_ = err
|
||||
|
||||
var eiptr *interface{}
|
||||
_, _ = json.Marshal(eiptr) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `*interface{}` found"
|
||||
_, err = json.Marshal(eiptr) // err is checked
|
||||
_ = err
|
||||
|
||||
var stringer fmt.Stringer
|
||||
_, _ = json.Marshal(stringer) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `fmt.Stringer` found"
|
||||
_, err = json.Marshal(stringer) // err is checked
|
||||
_ = err
|
||||
|
||||
var structWithEmptyInterface struct {
|
||||
EmptyInterface interface{}
|
||||
}
|
||||
_, _ = json.Marshal(structWithEmptyInterface) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found"
|
||||
_, err = json.Marshal(structWithEmptyInterface) // err is checked
|
||||
_ = err
|
||||
|
||||
var mt marshalText
|
||||
_, _ = json.Marshal(mt) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `[a-z-]+.marshalText` found"
|
||||
_, err = json.Marshal(mt) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapMarshalTextString map[marshalText]string
|
||||
_, _ = json.Marshal(mapMarshalTextString) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `[a-z-]+.marshalText` as map key found"
|
||||
_, err = json.Marshal(mapMarshalTextString) // err is checked
|
||||
_ = err
|
||||
}
|
||||
|
||||
// JSONMarshalInvalidTypes contains a multitude of test cases to marshal different combinations of types to JSON,
|
||||
// that are invalid and not supported by json.Marshal, that is they will always return an error, if these types used
|
||||
// with json.Marshal.
|
||||
func JSONMarshalInvalidTypes() {
|
||||
var err error
|
||||
|
||||
var c64 complex64
|
||||
json.Marshal(c64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_, _ = json.Marshal(c64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_, err = json.Marshal(c64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_ = err
|
||||
|
||||
var c128 complex128
|
||||
_, _ = json.Marshal(c128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_, err = json.Marshal(c128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_ = err
|
||||
|
||||
var sliceC64 []complex64
|
||||
_, _ = json.Marshal(sliceC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_, err = json.Marshal(sliceC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_ = err
|
||||
|
||||
var sliceC128 []complex128
|
||||
_, _ = json.Marshal(sliceC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_, err = json.Marshal(sliceC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_ = err
|
||||
|
||||
var arrayC64 []complex64
|
||||
_, _ = json.Marshal(arrayC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_, err = json.Marshal(arrayC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_ = err
|
||||
|
||||
var arrayC128 []complex128
|
||||
_, _ = json.Marshal(arrayC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_, err = json.Marshal(arrayC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_ = err
|
||||
|
||||
var structPtrC64 struct {
|
||||
C64 *complex64
|
||||
}
|
||||
_, _ = json.Marshal(structPtrC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_, err = json.Marshal(structPtrC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_ = err
|
||||
|
||||
var structPtrC128 struct {
|
||||
C128 *complex128
|
||||
}
|
||||
_, _ = json.Marshal(structPtrC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_, err = json.Marshal(structPtrC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_ = err
|
||||
|
||||
var mapBoolStr map[bool]string
|
||||
_, _ = json.Marshal(mapBoolStr) // ERROR "`encoding/json.Marshal` for unsupported type `bool` as map key found"
|
||||
_, err = json.Marshal(mapBoolStr) // ERROR "`encoding/json.Marshal` for unsupported type `bool` as map key found"
|
||||
_ = err
|
||||
|
||||
var mapF32Str map[float32]string
|
||||
_, _ = json.Marshal(mapF32Str) // ERROR "`encoding/json.Marshal` for unsupported type `float32` as map key found"
|
||||
_, err = json.Marshal(mapF32Str) // ERROR "`encoding/json.Marshal` for unsupported type `float32` as map key found"
|
||||
_ = err
|
||||
|
||||
var mapF64Str map[float64]string
|
||||
_, _ = json.Marshal(mapF64Str) // ERROR "`encoding/json.Marshal` for unsupported type `float64` as map key found"
|
||||
_, err = json.Marshal(mapF64Str) // ERROR "`encoding/json.Marshal` for unsupported type `float64` as map key found"
|
||||
_ = err
|
||||
|
||||
var mapC64Str map[complex64]string
|
||||
_, _ = json.Marshal(mapC64Str) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` as map key found"
|
||||
_, err = json.Marshal(mapC64Str) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` as map key found"
|
||||
_ = err
|
||||
|
||||
var mapC128Str map[complex128]string
|
||||
_, _ = json.Marshal(mapC128Str) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` as map key found"
|
||||
_, err = json.Marshal(mapC128Str) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` as map key found"
|
||||
_ = err
|
||||
|
||||
mapStructStr := map[structKey]string{structKey{1}: "str"}
|
||||
_, _ = json.Marshal(mapStructStr) // ERROR "`encoding/json.Marshal` for unsupported type `[a-z-]+.structKey` as map key found"
|
||||
_, err = json.Marshal(mapStructStr) // ERROR "`encoding/json.Marshal` for unsupported type `[a-z-]+.structKey` as map key found"
|
||||
_ = err
|
||||
|
||||
f := func() {}
|
||||
_, _ = json.Marshal(f) // ERROR "`encoding/json.Marshal` for unsupported type `func\\(\\)` found"
|
||||
_, err = json.Marshal(f) // ERROR "`encoding/json.Marshal` for unsupported type `func\\(\\)` found"
|
||||
_ = err
|
||||
|
||||
var ch chan struct{} = make(chan struct{})
|
||||
_, _ = json.Marshal(ch) // ERROR "`encoding/json.Marshal` for unsupported type `chan struct{}` found"
|
||||
_, err = json.Marshal(ch) // ERROR "`encoding/json.Marshal` for unsupported type `chan struct{}` found"
|
||||
_ = err
|
||||
|
||||
var unsafePtr unsafe.Pointer
|
||||
_, _ = json.Marshal(unsafePtr) // ERROR "`encoding/json.Marshal` for unsupported type `unsafe.Pointer` found"
|
||||
_, err = json.Marshal(unsafePtr) // ERROR "`encoding/json.Marshal` for unsupported type `unsafe.Pointer` found"
|
||||
_ = err
|
||||
}
|
||||
|
||||
// NotJSONMarshal contains other go ast node types, that are not considered by errchkjson
|
||||
func NotJSONMarshal() {
|
||||
s := fmt.Sprintln("I am not considered by errchkjson")
|
||||
_ = s
|
||||
f := func() bool { return false }
|
||||
_ = f()
|
||||
}
|
||||
|
||||
// JSONMarshalStructWithoutExportedFields contains a struct without exported fields.
|
||||
func JSONMarshalStructWithoutExportedFields() {
|
||||
var err error
|
||||
|
||||
var withoutExportedFields struct {
|
||||
privateField bool
|
||||
ExportedButOmittedField bool `json:"-"`
|
||||
}
|
||||
_, err = json.Marshal(withoutExportedFields) // want "Error argument passed to `encoding/json.Marshal` does not contain any exported field"
|
||||
_ = err
|
||||
}
|
||||
|
||||
// JSONMarshalStructWithoutExportedFields contains a struct without exported fields.
|
||||
func JSONMarshalStructWithNestedStructWithoutExportedFields() {
|
||||
var err error
|
||||
|
||||
var withNestedStructWithoutExportedFields struct {
|
||||
ExportedStruct struct {
|
||||
privatField bool
|
||||
}
|
||||
}
|
||||
_, err = json.Marshal(withNestedStructWithoutExportedFields)
|
||||
_ = err
|
||||
}
|
616
test/testdata/errchkjson_check_error_free_encoding.go
vendored
Normal file
616
test/testdata/errchkjson_check_error_free_encoding.go
vendored
Normal file
@ -0,0 +1,616 @@
|
||||
// args: -Eerrchkjson
|
||||
// config_path: testdata/configs/errchkjson_check_error_free_encoding.yml
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type marshalText struct{}
|
||||
|
||||
func (mt marshalText) MarshalText() ([]byte, error) {
|
||||
return []byte(`mt`), nil
|
||||
}
|
||||
|
||||
var _ encoding.TextMarshaler = marshalText(struct{}{})
|
||||
|
||||
// JSONMarshalSafeTypes contains a multitude of test cases to marshal different combinations of types to JSON,
|
||||
// that are safe, that is, they will never return an error, if these types are marshaled to JSON.
|
||||
func JSONMarshalSafeTypes() {
|
||||
var err error
|
||||
|
||||
_, _ = json.Marshal(nil) // nil is safe
|
||||
json.Marshal(nil) // nil is safe
|
||||
_, err = json.Marshal(nil) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
_, _ = json.MarshalIndent(nil, "", " ") // nil is safe
|
||||
json.MarshalIndent(nil, "", " ") // nil is safe
|
||||
_, err = json.MarshalIndent(nil, "", " ") // ERROR "Error return value of `encoding/json.MarshalIndent` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
enc := json.NewEncoder(ioutil.Discard)
|
||||
_ = enc.Encode(nil) // nil is safe
|
||||
enc.Encode(nil) // nil is safe
|
||||
err = enc.Encode(nil) // ERROR "Error return value of `\\([*]encoding/json.Encoder\\).Encode` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var b bool
|
||||
_, _ = json.Marshal(b) // bool is safe
|
||||
_, err = json.Marshal(b) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var i int
|
||||
_, _ = json.Marshal(i) // int is safe
|
||||
_, err = json.Marshal(i) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var i8 int8
|
||||
_, _ = json.Marshal(i8) // int8 is safe
|
||||
_, err = json.Marshal(i8) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var i16 int16
|
||||
_, _ = json.Marshal(i16) // int16 is safe
|
||||
_, err = json.Marshal(i16) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var i32 int32
|
||||
_, _ = json.Marshal(i32) // int32 / rune is safe
|
||||
_, err = json.Marshal(i32) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var i64 int64
|
||||
_, _ = json.Marshal(i64) // int64 is safe
|
||||
_, err = json.Marshal(i64) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var ui uint
|
||||
_, _ = json.Marshal(ui) // uint is safe
|
||||
_, err = json.Marshal(ui) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var ui8 uint8
|
||||
_, _ = json.Marshal(ui8) // uint8 / byte is safe
|
||||
_, err = json.Marshal(ui8) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var ui16 uint16
|
||||
_, _ = json.Marshal(ui16) // uint16 is safe
|
||||
_, err = json.Marshal(ui16) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var ui32 uint32
|
||||
_, _ = json.Marshal(ui32) // uint32 / rune is safe
|
||||
_, err = json.Marshal(ui32) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var ui64 uint64
|
||||
_, _ = json.Marshal(ui64) // uint64 is safe
|
||||
_, err = json.Marshal(ui64) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var uiptr uintptr
|
||||
_, _ = json.Marshal(uiptr) // uintptr is safe
|
||||
_, err = json.Marshal(uiptr) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var str string
|
||||
_, _ = json.Marshal(str) // string is safe
|
||||
_, err = json.Marshal(str) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var strSlice []string
|
||||
_, _ = json.Marshal(strSlice) // []string is safe
|
||||
_, err = json.Marshal(strSlice) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var intSlice []int
|
||||
_, _ = json.Marshal(intSlice) // []int is safe
|
||||
_, err = json.Marshal(intSlice) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var boolSlice []bool
|
||||
_, _ = json.Marshal(boolSlice) // []bool is safe
|
||||
_, err = json.Marshal(boolSlice) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var strArray [10]string
|
||||
_, _ = json.Marshal(strArray) // [10]string is safe
|
||||
_, err = json.Marshal(strArray) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var intArray [10]int
|
||||
_, _ = json.Marshal(intArray) // [10]int is safe
|
||||
_, err = json.Marshal(intArray) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var boolArray [10]bool
|
||||
_, _ = json.Marshal(boolArray) // [10]bool is safe
|
||||
_, err = json.Marshal(boolArray) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var basicStruct struct {
|
||||
Bool bool
|
||||
Int int
|
||||
Int8 int8
|
||||
Int16 int16
|
||||
Int32 int32 // also rune
|
||||
Int64 int64
|
||||
Uint uint
|
||||
Uint8 uint8 // also byte
|
||||
Uint16 uint16
|
||||
Uint32 uint32
|
||||
Uint64 uint64
|
||||
Uintptr uintptr
|
||||
String string
|
||||
}
|
||||
_, _ = json.Marshal(basicStruct) // struct containing only safe basic types is safe
|
||||
_, err = json.Marshal(basicStruct) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var ptrStruct struct {
|
||||
Bool *bool
|
||||
Int *int
|
||||
Int8 *int8
|
||||
Int16 *int16
|
||||
Int32 *int32
|
||||
Int64 *int64
|
||||
Uint *uint
|
||||
Uint8 *uint8
|
||||
Uint16 *uint16
|
||||
Uint32 *uint32
|
||||
Uint64 *uint64
|
||||
Uintptr *uintptr
|
||||
String *string
|
||||
}
|
||||
_, _ = json.Marshal(ptrStruct) // struct containing pointer to only safe basic types is safe
|
||||
_, err = json.Marshal(ptrStruct) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var mapStrStr map[string]string
|
||||
_, _ = json.Marshal(mapStrStr) // map[string]string is safe
|
||||
_, err = json.Marshal(mapStrStr) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var mapStrInt map[string]int
|
||||
_, _ = json.Marshal(mapStrInt) // map[string]int is safe
|
||||
_, err = json.Marshal(mapStrInt) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var mapStrBool map[string]bool
|
||||
_, _ = json.Marshal(mapStrBool) // map[string]bool is safe
|
||||
_, err = json.Marshal(mapStrBool) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var mapIntStr map[int]string
|
||||
_, _ = json.Marshal(mapIntStr) // map[int]string is safe
|
||||
_, err = json.Marshal(mapIntStr) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var mapIntInt map[int]int
|
||||
_, _ = json.Marshal(mapIntInt) // map[int]int is safe
|
||||
_, err = json.Marshal(mapIntInt) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
var mapIntBool map[int]bool
|
||||
_, _ = json.Marshal(mapIntBool) // map[int]bool is safe
|
||||
_, err = json.Marshal(mapIntBool) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
|
||||
type innerStruct struct {
|
||||
Bool bool
|
||||
Int int
|
||||
String string
|
||||
|
||||
StrSlice []string
|
||||
IntSlice []int
|
||||
BoolSlice []bool
|
||||
|
||||
StrArray [10]string
|
||||
IntArray [10]int
|
||||
BoolArray [10]bool
|
||||
|
||||
MapStrStr map[string]string
|
||||
MapStrInt map[string]int
|
||||
MapStrBool map[string]bool
|
||||
|
||||
MapIntStr map[int]string
|
||||
MapIntInt map[int]int
|
||||
MapIntBool map[int]bool
|
||||
}
|
||||
var outerStruct struct {
|
||||
Bool bool
|
||||
Int int
|
||||
String string
|
||||
|
||||
StrSlice []string
|
||||
IntSlice []int
|
||||
BoolSlice []bool
|
||||
|
||||
StrArray [10]string
|
||||
IntArray [10]int
|
||||
BoolArray [10]bool
|
||||
|
||||
MapStrStr map[string]string
|
||||
MapStrInt map[string]int
|
||||
MapStrBool map[string]bool
|
||||
|
||||
MapIntStr map[int]string
|
||||
MapIntInt map[int]int
|
||||
MapIntBool map[int]bool
|
||||
|
||||
InnerStruct innerStruct
|
||||
}
|
||||
_, _ = json.Marshal(outerStruct) // struct with only safe types
|
||||
_, err = json.Marshal(outerStruct) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
}
|
||||
|
||||
type (
|
||||
structKey struct{ id int }
|
||||
ExportedUnsafeAndInvalidStruct struct { // unsafe unexported but omitted
|
||||
F64 float64
|
||||
F64Ptr *float64
|
||||
F64Slice []float64
|
||||
F64Array [10]float64
|
||||
MapStrF64 map[string]float64
|
||||
MapEIStr map[interface{}]string
|
||||
Number json.Number
|
||||
NumberPtr *json.Number
|
||||
NumberSlice []json.Number
|
||||
MapNumberStr map[json.Number]string
|
||||
Ei interface{}
|
||||
Stringer fmt.Stringer
|
||||
Mt marshalText
|
||||
MapMarshalTextString map[marshalText]string
|
||||
|
||||
C128 complex128
|
||||
C128Ptr *complex128
|
||||
C128Slice []complex128
|
||||
C128Array [10]complex128
|
||||
MapBoolStr map[bool]string
|
||||
MapF64Str map[float64]string
|
||||
F func()
|
||||
Ch chan struct{}
|
||||
UnsafePtr unsafe.Pointer
|
||||
MapStructStr map[structKey]string
|
||||
}
|
||||
)
|
||||
|
||||
// JSONMarshalSaveStructWithUnexportedFields contains a struct with unexported, unsafe fields.
|
||||
func JSONMarshalSaveStructWithUnexportedFields() {
|
||||
var err error
|
||||
|
||||
var unexportedInStruct struct {
|
||||
Bool bool // safe exported
|
||||
|
||||
f64 float64 // unsafe unexported
|
||||
f64Ptr *float64 // unsafe unexported
|
||||
f64Slice []float64 // unsafe unexported
|
||||
f64Array [10]float64 // unsafe unexported
|
||||
mapStrF64 map[string]float64 // unsafe unexported
|
||||
mapEIStr map[interface{}]string // unsafe unexported
|
||||
number json.Number // unsafe unexported
|
||||
numberPtr *json.Number // unsafe unexported
|
||||
numberSlice []json.Number // unsafe unexported
|
||||
mapNumberStr map[json.Number]string // unsafe unexported
|
||||
ei interface{} // unsafe unexported
|
||||
stringer fmt.Stringer // unsafe unexported
|
||||
mt marshalText // unsafe unexported
|
||||
mapMarshalTextString map[marshalText]string // unsafe unexported
|
||||
unexportedStruct ExportedUnsafeAndInvalidStruct // unsafe unexported
|
||||
unexportedStructPtr *ExportedUnsafeAndInvalidStruct // unsafe unexported
|
||||
|
||||
c128 complex128 // invalid unexported
|
||||
c128Slice []complex128 // invalid unexported
|
||||
c128Array [10]complex128 // invalid unexported
|
||||
mapBoolStr map[bool]string // invalid unexported
|
||||
mapF64Str map[float64]string // invalid unexported
|
||||
f func() // invalid unexported
|
||||
ch chan struct{} // invalid unexported
|
||||
unsafePtr unsafe.Pointer // invalid unexported
|
||||
mapStructStr map[structKey]string // invalid unexported
|
||||
}
|
||||
_ = unexportedInStruct.f64
|
||||
_ = unexportedInStruct.f64Ptr
|
||||
_ = unexportedInStruct.f64Slice
|
||||
_ = unexportedInStruct.f64Array
|
||||
_ = unexportedInStruct.mapStrF64
|
||||
_ = unexportedInStruct.mapEIStr
|
||||
_ = unexportedInStruct.number
|
||||
_ = unexportedInStruct.numberPtr
|
||||
_ = unexportedInStruct.numberSlice
|
||||
_ = unexportedInStruct.mapNumberStr
|
||||
_ = unexportedInStruct.ei
|
||||
_ = unexportedInStruct.stringer
|
||||
_ = unexportedInStruct.mt
|
||||
_ = unexportedInStruct.mapMarshalTextString
|
||||
_ = unexportedInStruct.unexportedStruct
|
||||
_ = unexportedInStruct.unexportedStructPtr
|
||||
|
||||
_ = unexportedInStruct.c128
|
||||
_ = unexportedInStruct.c128Slice
|
||||
_ = unexportedInStruct.c128Array
|
||||
_ = unexportedInStruct.mapBoolStr
|
||||
_ = unexportedInStruct.mapF64Str
|
||||
_ = unexportedInStruct.f
|
||||
_ = unexportedInStruct.ch
|
||||
_ = unexportedInStruct.unsafePtr
|
||||
_ = unexportedInStruct.mapStructStr[structKey{1}]
|
||||
_, _ = json.Marshal(unexportedInStruct) // struct containing unsafe but unexported fields is safe
|
||||
_, err = json.Marshal(unexportedInStruct) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
}
|
||||
|
||||
// JSONMarshalSaveStructWithOmittedFields contains a struct with omitted, unsafe fields.
|
||||
func JSONMarshalSaveStructWithOmittedFields() {
|
||||
var err error
|
||||
|
||||
var omitInStruct struct {
|
||||
Bool bool // safe exported
|
||||
|
||||
F64 float64 `json:"-"` // unsafe exported but omitted
|
||||
F64Ptr *float64 `json:"-"` // unsafe exported but omitted
|
||||
F64Slice []float64 `json:"-"` // unsafe exported but omitted
|
||||
F64Array [10]float64 `json:"-"` // unsafe exported but omitted
|
||||
MapStrF64 map[string]float64 `json:"-"` // unsafe exported but omitted
|
||||
MapEIStr map[interface{}]string `json:"-"` // unsafe exported but omitted
|
||||
Number json.Number `json:"-"` // unsafe exported but omitted
|
||||
NumberPtr *json.Number `json:"-"` // unsafe exported but omitted
|
||||
NumberSlice []json.Number `json:"-"` // unsafe exported but omitted
|
||||
MapNumberStr map[json.Number]string `json:"-"` // unsafe exported but omitted
|
||||
Ei interface{} `json:"-"` // unsafe exported but omitted
|
||||
Stringer fmt.Stringer `json:"-"` // unsafe exported but omitted
|
||||
Mt marshalText `json:"-"` // unsafe exported but omitted
|
||||
MapMarshalTextString map[marshalText]string `json:"-"` // unsafe exported but omitted
|
||||
ExportedStruct ExportedUnsafeAndInvalidStruct `json:"-"` // unsafe exported but omitted
|
||||
ExportedStructPtr *ExportedUnsafeAndInvalidStruct `json:"-"` // unsafe exported but omitted
|
||||
|
||||
C128 complex128 `json:"-"` // invalid exported but omitted
|
||||
C128Slice []complex128 `json:"-"` // invalid exported but omitted
|
||||
C128Array [10]complex128 `json:"-"` // invalid exported but omitted
|
||||
MapBoolStr map[bool]string `json:"-"` // invalid exported but omitted
|
||||
MapF64Str map[float64]string `json:"-"` // invalid exported but omitted
|
||||
F func() `json:"-"` // invalid exported but omitted
|
||||
Ch chan struct{} `json:"-"` // invalid exported but omitted
|
||||
UnsafePtr unsafe.Pointer `json:"-"` // invalid exported but omitted
|
||||
MapStructStr map[structKey]string `json:"-"` // invalid exported but omitted
|
||||
}
|
||||
_ = omitInStruct.MapStructStr[structKey{1}]
|
||||
_, _ = json.Marshal(omitInStruct) // struct containing unsafe but omitted, exported fields is safe
|
||||
_, err = json.Marshal(omitInStruct) // ERROR "Error return value of `encoding/json.Marshal` is checked but passed argument is safe"
|
||||
_ = err
|
||||
}
|
||||
|
||||
// JSONMarshalUnsafeTypes contains a multitude of test cases to marshal different combinations of types to JSON,
|
||||
// that can potentially lead to json.Marshal returning an error.
|
||||
func JSONMarshalUnsafeTypes() {
|
||||
var err error
|
||||
|
||||
var f32 float32
|
||||
json.Marshal(f32) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, _ = json.Marshal(f32) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, err = json.Marshal(f32) // err is checked
|
||||
_ = err
|
||||
|
||||
var f64 float64
|
||||
_, _ = json.Marshal(f64) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
|
||||
_, err = json.Marshal(f64) // err is checked
|
||||
_ = err
|
||||
|
||||
var f32Slice []float32
|
||||
_, _ = json.Marshal(f32Slice) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, err = json.Marshal(f32Slice) // err is checked
|
||||
_ = err
|
||||
|
||||
var f64Slice []float64
|
||||
_, _ = json.Marshal(f64Slice) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
|
||||
_, err = json.Marshal(f64Slice) // err is checked
|
||||
_ = err
|
||||
|
||||
var f32Array [10]float32
|
||||
_, _ = json.Marshal(f32Array) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, err = json.Marshal(f32Array) // err is checked
|
||||
_ = err
|
||||
|
||||
var f64Array [10]float64
|
||||
_, _ = json.Marshal(f64Array) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
|
||||
_, err = json.Marshal(f64Array) // err is checked
|
||||
_ = err
|
||||
|
||||
var structPtrF32 struct {
|
||||
F32 *float32
|
||||
}
|
||||
_, _ = json.Marshal(structPtrF32) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, err = json.Marshal(structPtrF32) // err is checked
|
||||
_ = err
|
||||
|
||||
var structPtrF64 struct {
|
||||
F64 *float64
|
||||
}
|
||||
_, _ = json.Marshal(structPtrF64) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
|
||||
_, err = json.Marshal(structPtrF64) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapStrF32 map[string]float32
|
||||
_, _ = json.Marshal(mapStrF32) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float32` found"
|
||||
_, err = json.Marshal(mapStrF32) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapStrF64 map[string]float64
|
||||
_, _ = json.Marshal(mapStrF64) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `float64` found"
|
||||
_, err = json.Marshal(mapStrF64) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapEIStr map[interface{}]string
|
||||
_, _ = json.Marshal(mapEIStr) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` as map key found"
|
||||
_, err = json.Marshal(mapEIStr) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapStringerStr map[fmt.Stringer]string
|
||||
_, _ = json.Marshal(mapStringerStr) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `fmt.Stringer` as map key found"
|
||||
_, err = json.Marshal(mapStringerStr) // err is checked
|
||||
_ = err
|
||||
|
||||
var number json.Number
|
||||
_, _ = json.Marshal(number) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
|
||||
_, err = json.Marshal(number) // err is checked
|
||||
_ = err
|
||||
|
||||
var numberSlice []json.Number
|
||||
_, _ = json.Marshal(numberSlice) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
|
||||
_, err = json.Marshal(numberSlice) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapNumberStr map[json.Number]string
|
||||
_, _ = json.Marshal(mapNumberStr) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` as map key found"
|
||||
_, err = json.Marshal(mapNumberStr) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapStrNumber map[string]json.Number
|
||||
_, _ = json.Marshal(mapStrNumber) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.Number` found"
|
||||
_, err = json.Marshal(mapStrNumber) // err is checked
|
||||
_ = err
|
||||
|
||||
var ei interface{}
|
||||
_, _ = json.Marshal(ei) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found"
|
||||
_, err = json.Marshal(ei) // err is checked
|
||||
_ = err
|
||||
|
||||
var eiptr *interface{}
|
||||
_, _ = json.Marshal(eiptr) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `*interface{}` found"
|
||||
_, err = json.Marshal(eiptr) // err is checked
|
||||
_ = err
|
||||
|
||||
var stringer fmt.Stringer
|
||||
_, _ = json.Marshal(stringer) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `fmt.Stringer` found"
|
||||
_, err = json.Marshal(stringer) // err is checked
|
||||
_ = err
|
||||
|
||||
var structWithEmptyInterface struct {
|
||||
EmptyInterface interface{}
|
||||
}
|
||||
_, _ = json.Marshal(structWithEmptyInterface) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found"
|
||||
_, err = json.Marshal(structWithEmptyInterface) // err is checked
|
||||
_ = err
|
||||
|
||||
var mt marshalText
|
||||
_, _ = json.Marshal(mt) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `[a-z-]+.marshalText` found"
|
||||
_, err = json.Marshal(mt) // err is checked
|
||||
_ = err
|
||||
|
||||
var mapMarshalTextString map[marshalText]string
|
||||
_, _ = json.Marshal(mapMarshalTextString) // ERROR "Error return value of `encoding/json.Marshal` is not checked: unsafe type `[a-z-]+.marshalText` as map key found"
|
||||
_, err = json.Marshal(mapMarshalTextString) // err is checked
|
||||
_ = err
|
||||
}
|
||||
|
||||
// JSONMarshalInvalidTypes contains a multitude of test cases to marshal different combinations of types to JSON,
|
||||
// that are invalid and not supported by json.Marshal, that is they will always return an error, if these types used
|
||||
// with json.Marshal.
|
||||
func JSONMarshalInvalidTypes() {
|
||||
var err error
|
||||
|
||||
var c64 complex64
|
||||
json.Marshal(c64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_, _ = json.Marshal(c64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_, err = json.Marshal(c64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_ = err
|
||||
|
||||
var c128 complex128
|
||||
_, _ = json.Marshal(c128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_, err = json.Marshal(c128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_ = err
|
||||
|
||||
var sliceC64 []complex64
|
||||
_, _ = json.Marshal(sliceC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_, err = json.Marshal(sliceC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_ = err
|
||||
|
||||
var sliceC128 []complex128
|
||||
_, _ = json.Marshal(sliceC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_, err = json.Marshal(sliceC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_ = err
|
||||
|
||||
var arrayC64 []complex64
|
||||
_, _ = json.Marshal(arrayC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_, err = json.Marshal(arrayC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_ = err
|
||||
|
||||
var arrayC128 []complex128
|
||||
_, _ = json.Marshal(arrayC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_, err = json.Marshal(arrayC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_ = err
|
||||
|
||||
var structPtrC64 struct {
|
||||
C64 *complex64
|
||||
}
|
||||
_, _ = json.Marshal(structPtrC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_, err = json.Marshal(structPtrC64) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` found"
|
||||
_ = err
|
||||
|
||||
var structPtrC128 struct {
|
||||
C128 *complex128
|
||||
}
|
||||
_, _ = json.Marshal(structPtrC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_, err = json.Marshal(structPtrC128) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` found"
|
||||
_ = err
|
||||
|
||||
var mapBoolStr map[bool]string
|
||||
_, _ = json.Marshal(mapBoolStr) // ERROR "`encoding/json.Marshal` for unsupported type `bool` as map key found"
|
||||
_, err = json.Marshal(mapBoolStr) // ERROR "`encoding/json.Marshal` for unsupported type `bool` as map key found"
|
||||
_ = err
|
||||
|
||||
var mapF32Str map[float32]string
|
||||
_, _ = json.Marshal(mapF32Str) // ERROR "`encoding/json.Marshal` for unsupported type `float32` as map key found"
|
||||
_, err = json.Marshal(mapF32Str) // ERROR "`encoding/json.Marshal` for unsupported type `float32` as map key found"
|
||||
_ = err
|
||||
|
||||
var mapF64Str map[float64]string
|
||||
_, _ = json.Marshal(mapF64Str) // ERROR "`encoding/json.Marshal` for unsupported type `float64` as map key found"
|
||||
_, err = json.Marshal(mapF64Str) // ERROR "`encoding/json.Marshal` for unsupported type `float64` as map key found"
|
||||
_ = err
|
||||
|
||||
var mapC64Str map[complex64]string
|
||||
_, _ = json.Marshal(mapC64Str) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` as map key found"
|
||||
_, err = json.Marshal(mapC64Str) // ERROR "`encoding/json.Marshal` for unsupported type `complex64` as map key found"
|
||||
_ = err
|
||||
|
||||
var mapC128Str map[complex128]string
|
||||
_, _ = json.Marshal(mapC128Str) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` as map key found"
|
||||
_, err = json.Marshal(mapC128Str) // ERROR "`encoding/json.Marshal` for unsupported type `complex128` as map key found"
|
||||
_ = err
|
||||
|
||||
mapStructStr := map[structKey]string{structKey{1}: "str"}
|
||||
_, _ = json.Marshal(mapStructStr) // ERROR "`encoding/json.Marshal` for unsupported type `[a-z-]+.structKey` as map key found"
|
||||
_, err = json.Marshal(mapStructStr) // ERROR "`encoding/json.Marshal` for unsupported type `[a-z-]+.structKey` as map key found"
|
||||
_ = err
|
||||
|
||||
f := func() {}
|
||||
_, _ = json.Marshal(f) // ERROR "`encoding/json.Marshal` for unsupported type `func\\(\\)` found"
|
||||
_, err = json.Marshal(f) // ERROR "`encoding/json.Marshal` for unsupported type `func\\(\\)` found"
|
||||
_ = err
|
||||
|
||||
var ch chan struct{} = make(chan struct{})
|
||||
_, _ = json.Marshal(ch) // ERROR "`encoding/json.Marshal` for unsupported type `chan struct{}` found"
|
||||
_, err = json.Marshal(ch) // ERROR "`encoding/json.Marshal` for unsupported type `chan struct{}` found"
|
||||
_ = err
|
||||
|
||||
var unsafePtr unsafe.Pointer
|
||||
_, _ = json.Marshal(unsafePtr) // ERROR "`encoding/json.Marshal` for unsupported type `unsafe.Pointer` found"
|
||||
_, err = json.Marshal(unsafePtr) // ERROR "`encoding/json.Marshal` for unsupported type `unsafe.Pointer` found"
|
||||
_ = err
|
||||
}
|
||||
|
||||
// NotJSONMarshal contains other go ast node types, that are not considered by errchkjson
|
||||
func NotJSONMarshal() {
|
||||
s := fmt.Sprintln("I am not considered by errchkjson")
|
||||
_ = s
|
||||
f := func() bool { return false }
|
||||
_ = f()
|
||||
}
|
28
test/testdata/errchkjson_no_exported.go
vendored
Normal file
28
test/testdata/errchkjson_no_exported.go
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// args: -Eerrchkjson
|
||||
// config_path: testdata/configs/errchkjson_no_exported.yml
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// JSONMarshalStructWithoutExportedFields contains a struct without exported fields.
|
||||
func JSONMarshalStructWithoutExportedFields() {
|
||||
var withoutExportedFields struct {
|
||||
privateField bool
|
||||
ExportedButOmittedField bool `json:"-"`
|
||||
}
|
||||
_, err := json.Marshal(withoutExportedFields) // ERROR "Error argument passed to `encoding/json.Marshal` does not contain any exported field"
|
||||
_ = err
|
||||
}
|
||||
|
||||
// JSONMarshalStructWithNestedStructWithoutExportedFields contains a struct without exported fields.
|
||||
func JSONMarshalStructWithNestedStructWithoutExportedFields() {
|
||||
var withNestedStructWithoutExportedFields struct {
|
||||
ExportedStruct struct {
|
||||
privatField bool
|
||||
}
|
||||
}
|
||||
_, err := json.Marshal(withNestedStructWithoutExportedFields)
|
||||
_ = err
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user