From 017bfd45b42610d912925b238f8c6ebc72a39239 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Thu, 21 Nov 2019 22:58:03 +0100 Subject: [PATCH] test multipart body paramters --- internal/reqdata/store_test.go | 235 +++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) diff --git a/internal/reqdata/store_test.go b/internal/reqdata/store_test.go index 6866a8f..2694e6b 100644 --- a/internal/reqdata/store_test.go +++ b/internal/reqdata/store_test.go @@ -545,3 +545,238 @@ func TestJsonParameters(t *testing.T) { } } + +func TestMultipartParameters(t *testing.T) { + tests := []struct { + RawMultipart string + + InvalidNames []string + ParamNames []string + ParamValues []interface{} + }{ + // no need to fully check json because it is parsed with the standard library + { + RawMultipart: ``, + InvalidNames: []string{}, + ParamNames: []string{}, + ParamValues: []interface{}{}, + }, + { + RawMultipart: `--xxx + `, + InvalidNames: []string{}, + ParamNames: []string{}, + ParamValues: []interface{}{}, + }, + { + RawMultipart: `--xxx +--xxx--`, + InvalidNames: []string{}, + ParamNames: []string{}, + ParamValues: []interface{}{}, + }, + { + RawMultipart: `--xxx +Content-Disposition: form-data; name="a" + +b +--xxx--`, + InvalidNames: []string{}, + ParamNames: []string{"a"}, + ParamValues: []interface{}{"b"}, + }, + { + RawMultipart: `--xxx +Content-Disposition: form-data; name="a" + +b +--xxx +Content-Disposition: form-data; name="c" + +d +--xxx--`, + InvalidNames: []string{}, + ParamNames: []string{"a", "c"}, + ParamValues: []interface{}{"b", "d"}, + }, + { + RawMultipart: `--xxx +Content-Disposition: form-data; name="_invalid" + +x +--xxx--`, + InvalidNames: []string{"_invalid"}, + ParamNames: []string{"_invalid"}, + ParamValues: []interface{}{nil}, + }, + { + RawMultipart: `--xxx +Content-Disposition: form-data; name="a" + +b +--xxx +Content-Disposition: form-data; name="_invalid" + +x +--xxx--`, + InvalidNames: []string{"_invalid"}, + ParamNames: []string{"a", "_invalid"}, + ParamValues: []interface{}{"b", nil}, + }, + + { + RawMultipart: `--xxx +Content-Disposition: form-data; name="invalid_" + +x +--xxx--`, + InvalidNames: []string{"invalid_"}, + ParamNames: []string{"invalid_"}, + ParamValues: []interface{}{nil}, + }, + { + RawMultipart: `--xxx +Content-Disposition: form-data; name="a" + +b +--xxx +Content-Disposition: form-data; name="invalid_" + +x +--xxx--`, + InvalidNames: []string{"invalid_"}, + ParamNames: []string{"a", "invalid_"}, + ParamValues: []interface{}{"b", nil}, + }, + + { + RawMultipart: `--xxx +Content-Disposition: form-data; name="GET@injection" + +x +--xxx--`, + InvalidNames: []string{"GET@injection"}, + ParamNames: []string{"GET@injection"}, + ParamValues: []interface{}{nil}, + }, + { + RawMultipart: `--xxx +Content-Disposition: form-data; name="a" + +b +--xxx +Content-Disposition: form-data; name="GET@injection" + +x +--xxx--`, + InvalidNames: []string{"GET@injection"}, + ParamNames: []string{"a", "GET@injection"}, + ParamValues: []interface{}{"b", nil}, + }, + + { + RawMultipart: `--xxx +Content-Disposition: form-data; name="URL#injection" + +x +--xxx--`, + InvalidNames: []string{"URL#injection"}, + ParamNames: []string{"URL#injection"}, + ParamValues: []interface{}{nil}, + }, + { + RawMultipart: `--xxx +Content-Disposition: form-data; name="a" + +b +--xxx +Content-Disposition: form-data; name="URL#injection" + +x +--xxx--`, + InvalidNames: []string{"URL#injection"}, + ParamNames: []string{"a", "URL#injection"}, + ParamValues: []interface{}{"b", nil}, + }, + // json parse error + { + RawMultipart: "{ \"a\": \"b\", }", + InvalidNames: []string{}, + ParamNames: []string{}, + ParamValues: []interface{}{}, + }, + } + + for i, test := range tests { + t.Run(fmt.Sprintf("request.%d", i), func(t *testing.T) { + body := bytes.NewBufferString(test.RawMultipart) + req := httptest.NewRequest(http.MethodPost, "http://host.com", body) + req.Header.Add("Content-Type", "multipart/form-data; boundary=xxx") + defer req.Body.Close() + store := New(nil, req) + + if test.ParamNames == nil || test.ParamValues == nil { + if len(store.Set) != 0 { + t.Errorf("expected no JSON parameters and got %d", len(store.Get)) + t.Failed() + } + + // no param to check + return + } + + if len(test.ParamNames) != len(test.ParamValues) { + t.Errorf("invalid test: names and values differ in size (%d vs %d)", len(test.ParamNames), len(test.ParamValues)) + t.Failed() + } + + for pi, pName := range test.ParamNames { + key := pName + value := test.ParamValues[pi] + + isNameValid := true + for _, invalid := range test.InvalidNames { + if pName == invalid { + isNameValid = false + } + } + + t.Run(key, func(t *testing.T) { + + param, isset := store.Set[key] + if !isset { + if isNameValid { + t.Errorf("store should contain element with key '%s'", key) + t.Failed() + } + return + } + + // if should be invalid + if isset && !isNameValid { + t.Errorf("store should NOT contain element with key '%s' (invalid name)", key) + t.Failed() + } + + valueType := reflect.TypeOf(value) + + paramValue := param.Value + paramValueType := reflect.TypeOf(param.Value) + + if valueType != paramValueType { + t.Errorf("should be of type %v (got '%v')", valueType, paramValueType) + t.Failed() + } + + if paramValue != value { + t.Errorf("should return %v (got '%v')", value, paramValue) + t.Failed() + } + + }) + + } + }) + } + +}