Repository: swaggest/rest
Pull request #18 (2021-01-11 20:39:56)

Fix index out of range for decoder.in

github-actions[bot]: ### Unit Test Coverage
total:	(statements)	81.5%
<details><summary>Coverage diff with base branch</summary>

```diff

```
</details>
<!-- Sticky Pull Request Commentunit-test -->
codecov[bot]: # [Codecov](https://codecov.io/gh/swaggest/rest/pull/18?src=pr&el=h1) Report
> Merging [#18](https://codecov.io/gh/swaggest/rest/pull/18?src=pr&el=desc) (91764e4) into [master](https://codecov.io/gh/swaggest/rest/commit/0ba9ab81bd75ef60cf37859e718424f754884c65?el=desc) (0ba9ab8) will **increase** coverage by `0.01%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/swaggest/rest/pull/18/graphs/tree.svg?width=650&height=150&src=pr&token=OpLHxxPdmn)](https://codecov.io/gh/swaggest/rest/pull/18?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master      #18      +/-   ##
==========================================
+ Coverage   73.88%   73.90%   +0.01%     
==========================================
  Files          26       26              
  Lines        1463     1464       +1     
==========================================
+ Hits         1081     1082       +1     
  Misses        241      241              
  Partials      141      141              
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `73.90% <100.00%> (+0.01%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/swaggest/rest/pull/18?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [request/factory.go](https://codecov.io/gh/swaggest/rest/pull/18/diff?src=pr&el=tree#diff-cmVxdWVzdC9mYWN0b3J5Lmdv) | `82.35% <100.00%> (+0.21%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/swaggest/rest/pull/18?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/swaggest/rest/pull/18?src=pr&el=footer). Last update [0ba9ab8...91764e4](https://codecov.io/gh/swaggest/rest/pull/18?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

github-actions[bot]: ### Benchmark Result
<details><summary>Benchmark diff with base branch</summary>

```
Using vendor
name                                    old time/op    new time/op    delta
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-2    1.63µs ± 1%    1.65µs ± 2%   +1.47%  (p=0.048 n=5+5)
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-2                           890ns ± 3%     945ns ± 3%   +6.18%  (p=0.016 n=5+5)
DecoderFunc_Decode-2                      2.50µs ± 1%    2.58µs ± 3%   +2.95%  (p=0.032 n=5+5)
Decoder_Decode_json-2                     30.2µs ± 5%    29.7µs ± 2%     ~     (p=0.310 n=5+5)
Decoder_Decode_queryObject-2              6.14µs ± 1%    6.75µs ± 1%  +10.00%  (p=0.008 n=5+5)
Decoder_Decode_jsonParam-2                2.31µs ± 4%    2.42µs ± 1%   +4.46%  (p=0.016 n=5+5)
DecoderFactory_SetDecoderFunc-2           2.03µs ± 4%    2.09µs ± 1%     ~     (p=0.056 n=5+5)
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-2                              13.8µs ± 1%    15.1µs ± 1%   +9.59%  (p=0.008 n=5+5)
Middleware_control-2                      4.27µs ± 2%    4.14µs ± 2%   -3.02%  (p=0.032 n=5+5)

name                                    old alloc/op   new alloc/op   delta
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-2    2.50kB ± 0%    2.50kB ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-2                            448B ± 0%      448B ± 0%     ~     (all equal)
DecoderFunc_Decode-2                      1.51kB ± 0%    1.51kB ± 0%     ~     (all equal)
Decoder_Decode_json-2                     12.4kB ± 0%    12.4kB ± 0%     ~     (all equal)
Decoder_Decode_queryObject-2              2.00kB ± 0%    2.00kB ± 0%     ~     (all equal)
Decoder_Decode_jsonParam-2                  752B ± 0%      752B ± 0%     ~     (all equal)
DecoderFactory_SetDecoderFunc-2           1.02kB ± 0%    1.02kB ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-2                              1.12kB ± 3%    1.13kB ± 2%     ~     (p=0.365 n=5+5)
Middleware_control-2                      11.2kB ± 0%    11.2kB ± 0%     ~     (all equal)

name                                    old allocs/op  new allocs/op  delta
pkg:github.com/swaggest/rest/jsonschema goos:linux goarch:amd64
RequestValidator_ValidateRequestData-2      8.00 ± 0%      8.00 ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/request goos:linux goarch:amd64
Decoder_Decode-2                            4.00 ± 0%      4.00 ± 0%     ~     (all equal)
DecoderFunc_Decode-2                        12.0 ± 0%      12.0 ± 0%     ~     (all equal)
Decoder_Decode_json-2                        169 ± 0%       169 ± 0%     ~     (all equal)
Decoder_Decode_queryObject-2                36.0 ± 0%      36.0 ± 0%     ~     (all equal)
Decoder_Decode_jsonParam-2                  12.0 ± 0%      12.0 ± 0%     ~     (all equal)
DecoderFactory_SetDecoderFunc-2             16.0 ± 0%      16.0 ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/response/gzip goos:linux goarch:amd64
Middleware-2                                11.0 ± 0%      11.0 ± 0%     ~     (all equal)
Middleware_control-2                        9.00 ± 0%      9.00 ± 0%     ~     (all equal)
```
</details>

### Examples Benchmark Result
<details><summary>Benchmark diff with base branch</summary>

```
Using vendor
name                    old time/op    new time/op    delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2             37.2µs ± 1%    27.1µs ± 3%  -27.11%  (p=0.008 n=5+5)
_directGzipHead-2         36.3µs ± 3%    27.7µs ± 2%  -23.80%  (p=0.008 n=5+5)
_noDirectGzip-2            164µs ± 2%     149µs ± 3%   -8.78%  (p=0.008 n=5+5)
_directGzip_decode-2       583µs ± 3%     555µs ± 3%   -4.87%  (p=0.016 n=5+5)
_noDirectGzip_decode-2     161µs ± 2%     152µs ± 4%   -6.10%  (p=0.008 n=5+5)
_jsonBody-2               44.8µs ± 1%    33.7µs ± 4%  -24.78%  (p=0.008 n=5+5)
_jsonBodyValidation-2     69.1µs ± 2%    58.0µs ± 1%  -16.11%  (p=0.008 n=5+5)
_outputHeaders-2          35.4µs ± 2%    25.8µs ± 1%  -27.03%  (p=0.008 n=5+5)
_validation-2             66.3µs ± 3%    51.8µs ± 3%  -21.85%  (p=0.008 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2            47.6µs ± 2%    33.8µs ± 3%  -29.16%  (p=0.008 n=5+5)
_ok-2                     48.8µs ± 3%    35.4µs ± 2%  -27.44%  (p=0.008 n=5+5)
_invalidBody-2            65.5µs ± 4%    48.7µs ± 2%  -25.61%  (p=0.008 n=5+5)

name                    old B:rcvd/op  new B:rcvd/op  delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2                639 ± 0%       639 ± 0%     ~     (all equal)
_directGzipHead-2            183 ± 0%       183 ± 0%     ~     (all equal)
_noDirectGzip-2            1.04k ± 0%     1.04k ± 0%     ~     (all equal)
_directGzip_decode-2         639 ± 0%       639 ± 0%     ~     (all equal)
_noDirectGzip_decode-2     1.04k ± 0%     1.04k ± 0%     ~     (all equal)
_jsonBody-2                  194 ± 0%       194 ± 0%     ~     (all equal)
_jsonBodyValidation-2        194 ± 0%       194 ± 0%     ~     (all equal)
_outputHeaders-2             155 ± 0%       155 ± 0%     ~     (all equal)
_validation-2                177 ± 0%       177 ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2               337 ± 0%       337 ± 0%     ~     (all equal)
_ok-2                        359 ± 0%       359 ± 0%     ~     (all equal)
_invalidBody-2               435 ± 0%       435 ± 0%     ~     (all equal)

name                    old B:sent/op  new B:sent/op  delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2                103 ± 0%       103 ± 0%     ~     (all equal)
_directGzipHead-2            104 ± 0%       104 ± 0%     ~     (all equal)
_noDirectGzip-2              117 ± 0%       117 ± 0%     ~     (all equal)
_directGzip_decode-2         116 ± 0%       116 ± 0%     ~     (all equal)
_noDirectGzip_decode-2       130 ± 0%       130 ± 0%     ~     (all equal)
_jsonBody-2                  181 ± 0%       181 ± 0%     ~     (all equal)
_jsonBodyValidation-2        192 ± 0%       192 ± 0%     ~     (all equal)
_outputHeaders-2            77.0 ± 0%      77.0 ± 0%     ~     (all equal)
_validation-2                170 ± 0%       170 ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2              74.0 ± 0%      74.0 ± 0%     ~     (all equal)
_ok-2                       74.0 ± 0%      74.0 ± 0%     ~     (all equal)
_invalidBody-2               137 ± 0%       137 ± 0%     ~     (all equal)

name                    old rps        new rps        delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2              26.9k ± 1%     36.9k ± 3%  +37.26%  (p=0.008 n=5+5)
_directGzipHead-2          27.5k ± 3%     36.1k ± 2%  +31.20%  (p=0.008 n=5+5)
_noDirectGzip-2            6.10k ± 2%     6.69k ± 3%   +9.63%  (p=0.008 n=5+5)
_directGzip_decode-2       1.72k ± 3%     1.80k ± 3%   +5.11%  (p=0.016 n=5+5)
_noDirectGzip_decode-2     6.20k ± 2%     6.60k ± 4%   +6.55%  (p=0.008 n=5+5)
_jsonBody-2                22.3k ± 1%     29.7k ± 4%  +32.99%  (p=0.008 n=5+5)
_jsonBodyValidation-2      14.5k ± 2%     17.3k ± 2%  +19.20%  (p=0.008 n=5+5)
_outputHeaders-2           28.2k ± 2%     38.7k ± 1%  +37.02%  (p=0.008 n=5+5)
_validation-2              15.1k ± 3%     19.3k ± 2%  +27.95%  (p=0.008 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2             21.0k ± 2%     29.6k ± 3%  +41.16%  (p=0.008 n=5+5)
_ok-2                      20.5k ± 3%     28.2k ± 2%  +37.80%  (p=0.008 n=5+5)
_invalidBody-2             15.3k ± 4%     20.5k ± 2%  +34.33%  (p=0.008 n=5+5)

name                    old alloc/op   new alloc/op   delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2             3.87kB ± 0%    3.86kB ± 0%   -0.20%  (p=0.000 n=4+5)
_directGzipHead-2         3.86kB ± 0%    3.86kB ± 0%   -0.17%  (p=0.008 n=5+5)
_noDirectGzip-2           6.24kB ±26%    6.14kB ±21%     ~     (p=0.841 n=5+5)
_directGzip_decode-2       403kB ± 0%     403kB ± 0%     ~     (p=0.056 n=5+5)
_noDirectGzip_decode-2    5.25kB ± 9%    5.30kB ± 9%     ~     (p=0.690 n=5+5)
_jsonBody-2               5.99kB ± 0%    5.98kB ± 0%   -0.17%  (p=0.008 n=5+5)
_jsonBodyValidation-2     18.2kB ± 0%    18.2kB ± 0%   -0.05%  (p=0.016 n=5+5)
_outputHeaders-2          3.64kB ± 0%    3.64kB ± 0%   -0.20%  (p=0.016 n=4+5)
_validation-2             16.2kB ± 0%    16.2kB ± 0%   -0.06%  (p=0.032 n=5+5)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2            5.65kB ± 0%    5.65kB ± 0%   -0.09%  (p=0.008 n=5+5)
_ok-2                     5.56kB ± 0%    5.56kB ± 0%     ~     (p=0.086 n=4+4)
_invalidBody-2            9.59kB ± 3%    9.47kB ± 0%     ~     (p=0.111 n=5+4)

name                    old allocs/op  new allocs/op  delta
pkg:github.com/swaggest/rest/_examples/advanced goos:linux goarch:amd64
_directGzip-2               40.0 ± 0%      40.0 ± 0%     ~     (all equal)
_directGzipHead-2           40.0 ± 0%      40.0 ± 0%     ~     (all equal)
_noDirectGzip-2             47.8 ± 4%      47.8 ± 4%     ~     (p=1.000 n=5+5)
_directGzip_decode-2         498 ± 0%       497 ± 0%     ~     (p=0.095 n=5+4)
_noDirectGzip_decode-2      48.0 ± 0%      48.0 ± 0%     ~     (all equal)
_jsonBody-2                 57.0 ± 0%      57.0 ± 0%     ~     (all equal)
_jsonBodyValidation-2        144 ± 0%       144 ± 0%     ~     (all equal)
_outputHeaders-2            35.0 ± 0%      35.0 ± 0%     ~     (all equal)
_validation-2                131 ± 0%       131 ± 0%     ~     (all equal)
pkg:github.com/swaggest/rest/_examples/task-api/internal/infra/nethttp goos:linux goarch:amd64
_notFoundSrv-2              63.0 ± 0%      63.0 ± 0%     ~     (all equal)
_ok-2                       59.0 ± 0%      59.0 ± 0%     ~     (all equal)
_invalidBody-2               110 ± 2%       109 ± 0%     ~     (p=0.333 n=5+4)
```
</details>
<!-- Sticky Pull Request Commentbench -->

Patch:
diff --git a/request/factory.go b/request/factory.go
index 770a024..0b8a2e3 100644
--- a/request/factory.go
+++ b/request/factory.go
@@ -186,6 +186,7 @@ func (df *DecoderFactory) makeDefaultDecoder(input interface{}, m *decoder) {
 	m.decoders = append(m.decoders, func(r *http.Request, v interface{}, validator rest.Validator) error {
 		return dec.Decode(v, defaults)
 	})
+	m.in = append(m.in, defaultTag)
 }
 
 func (df *DecoderFactory) makeCustomMappingDecoder(customMapping rest.RequestMapping, m *decoder) {


Test patch:
diff --git a/request/decoder_test.go b/request/decoder_test.go
index d4cfb8d..5a5dcb3 100644
--- a/request/decoder_test.go
+++ b/request/decoder_test.go
@@ -334,3 +334,23 @@ func BenchmarkDecoder_Decode_jsonParam(b *testing.B) {
 	assert.Equal(b, 123, v.Filter.A)
 	assert.Equal(b, "abc", v.Filter.B)
 }
+
+func TestDecoder_Decode_error(t *testing.T) {
+	type req struct {
+		Q int `default:"100" query:"q"`
+	}
+
+	df := request.NewDecoderFactory()
+	df.ApplyDefaults = true
+
+	d := df.MakeDecoder(http.MethodGet, new(req), nil)
+	r, err := http.NewRequest(http.MethodGet, "?q=undefined", nil)
+	require.NoError(t, err)
+
+	in := new(req)
+	err = d.Decode(r, in, nil)
+	assert.EqualError(t, err, "bad request")
+	assert.Equal(t, rest.RequestErrors{"query:q": []string{
+		"#: Invalid Integer Value 'undefined' Type 'int' Namespace 'q'",
+	}}, err)
+}