You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Gin receives HTTP GET call like 127.0.0.1:8000/foo?a=.1, where a is expected to be decimal number. The handling part has defined a struct with a decimal.Decimal field to receive this a. (URL being "a=0.1" vs "a=.1", the result will be different.)
the actual part to look into is BindQuery, the calling chain is a bit long, i think the important functions are
funcsetByForm(value reflect.Value, field reflect.StructField, formmap[string][]string, tagValuestring, optsetOptions) (isSetbool, errerror) {
(Try to parse ".1" and assign to the destination field)
In the setByForm fn, it goes to default branch, and attempt of trySetCustom is not effective, so finally go to setWithProperType:
the receiving/destination variable is decimal.Decimal, which is a struct, so go to case reflect.Struct in setWithProperType,
then json.Unmarshal
THE BAD THING is .1 is not a valid JSONstring. (0.1 or ".1" are valid JSONstring)
I note inside case reflect.Struct, 2 struct types are specially handled. so regarding my use case, is it a typical one where trySetCustom is supposed to be used? Or, passing query a=.1 is bad practice?
The setByForm function calls trySetCustom to check if the binding fields implement the BindUnmarshaler interface. However, decimal.Decimal does not implement this interface by default.
Fortunately, you can still implement the interface BindUnmarshaler on your own.
// BindUnmarshaler is the interface used to wrap the UnmarshalParam method.typeBindUnmarshalerinterface {
// UnmarshalParam decodes and assigns a value from an form or query param.UnmarshalParam(paramstring) error
}
Description
Gin receives HTTP GET call like
127.0.0.1:8000/foo?a=.1
, wherea
is expected to be decimal number. The handling part has defined a struct with a decimal.Decimal field to receive thisa
. (URL being "a=0.1" vs "a=.1", the result will be different.)the actual part to look into is
BindQuery
, the calling chain is a bit long, i think the important functions arehttps://github.com/gin-gonic/gin/blob/c8a3adc65703d8958265c07689662e54f037038c/binding/query.go (Parse URL to
{"a":[".1"]}
map)gin/binding/form_mapping.go
Line 225 in c8a3adc
In the
setByForm
fn, it goes to default branch, and attempt oftrySetCustom
is not effective, so finally go tosetWithProperType
:the receiving/destination variable is decimal.Decimal, which is a struct, so go to
case reflect.Struct
insetWithProperType
,then json.Unmarshal
THE BAD THING is
.1
is not a valid JSONstring. (0.1
or".1"
are valid JSONstring)I note inside
case reflect.Struct
, 2 struct types are specially handled. so regarding my use case, is it a typical one wheretrySetCustom
is supposed to be used? Or, passing querya=.1
is bad practice?How to reproduce
Gin code:
127.0.0.1:8000/foo?a=.1
Expectations
no error
Actual result
error
Environment
The text was updated successfully, but these errors were encountered: