@@ -16,31 +16,36 @@ func TestParseFormInt(t *testing.T) {
1616 maximum := 100
1717
1818 cases := []struct {
19- name string
20- query string
21- field string
22- def int
23- want int
24- maximum int
19+ name string
20+ query string
21+ want int
2522 }{
26- {"valid" , "/?downloads=5" , "downloads" ,
27- def , 5 , maximum },
28- {"space" , "/?downloads= 5 " , "downloads" ,
29- def , 5 , maximum },
30- {"missing" , "/" , "downloads" ,
31- def , 1 , maximum },
32- {"invalid" , "/?downloads=none" , "downloads" ,
33- def , 1 , maximum },
34- {"zero" , "/?downloads=0" , "downloads" ,
35- def , def , maximum },
36- {"negative" , "/?downloads=-1" , "downloads" ,
37- def , def , maximum },
38- {"fraction" , "/?downloads=3.5" , "downloads" ,
39- def , def , maximum },
40- {"large" , "/?downloads=101" , "downloads" ,
41- def , maximum , maximum },
23+ {"valid" , "/?downloads=5" , 5 },
24+ {"space" , "/?downloads= 5 " , 5 },
25+ {"unencoded" , "/?downloads=+5" , 5 },
26+ {"encoded" , "/?downloads=%2B5" , 5 },
27+ {"leading-zeros" , "/?downloads=005" , 5 },
28+ {"padded" , "/?downloads=%C2%A05%C2%A0" , 5 },
29+ {"missing" , "/" , def },
30+ {"invalid" , "/?downloads=none" , def },
31+ {"empty" , "/?downloads=" , def },
32+ {"zero" , "/?downloads=0" , def },
33+ {"negative" , "/?downloads=-1" , def },
34+ {"fraction" , "/?downloads=3.5" , def },
35+ {"hex" , "/?downloads=0x5" , def },
36+ {"trailing" , "/?downloads=5abc" , def },
37+ {"leading" , "/?downloads=abc5" , def },
38+ {"non-ascii" , "/?downloads=%EF%BC%95" , def },
39+ {"exceed max" , "/?downloads=1000" , maximum },
40+ {"underscore" , "/?downloads=1_000" , def },
41+ {"with-space" , "/?downloads=1 000" , def },
42+ {"only-spaces" , "/?downloads= " , def },
43+ {"empty-duplicate" , "/?downloads=&downloads=5" , def },
44+ {"valid-duplicate" , "/?downloads=5&downloads=10" , 5 },
45+ {"upper-case" , "/?Downloads=5" , def },
46+ {"multiple" , "/?duration=5m&downloads=10" , 10 },
4247 {"xlarge" , "/?downloads=999999999999999999999" ,
43- "downloads" , def , def , maximum }, // overflows int64
48+ def }, // overflows int64
4449 }
4550
4651 for _ , tc := range cases {
@@ -52,7 +57,8 @@ func TestParseFormInt(t *testing.T) {
5257 if err != nil {
5358 t .Fatal (err )
5459 }
55- got := parseFormInt (req , tc .field , tc .def , tc .maximum )
60+ got := parseFormInt (
61+ req , formFieldDownloads , def , maximum )
5662 if got != tc .want {
5763 t .Fatalf ("parseFormInt(%q) = %d; want %d" ,
5864 tc .query , got , tc .want )
@@ -69,37 +75,58 @@ func TestParseFormDuration(t *testing.T) {
6975 maximum := 8 * 24 * time .Hour
7076
7177 cases := []struct {
72- name string
73- query string
74- field string
75- def time.Duration
76- want time.Duration
77- maximum time.Duration
78+ name string
79+ query string
80+ want time.Duration
7881 }{
79- {"valid" , "/?duration=1h30m" , "duration" ,
80- def , 90 * time .Minute , maximum },
81- {"space" , "/?duration= 15m " , "duration" ,
82- def , 15 * time .Minute , maximum },
83- {"missing" , "/" , "duration" ,
84- def , def , maximum },
85- {"invalid" , "/?duration=none" , "duration" ,
86- def , def , maximum },
87- {"zero" , "/?duration=0s" , "duration" ,
88- def , def , maximum },
89- {"negative" , "/?duration=-1h" , "duration" ,
90- def , def , maximum },
91- {"fraction" , "/?duration=1.5h" , "duration" ,
92- def , 90 * time .Minute , maximum },
93- {"no-unit" , "/?duration=3333" , "duration" ,
94- def , def , maximum },
95- {"bad-unit" , "/duration=8h" , "duration" ,
96- def , def , maximum },
97- {"large" , "/?duration=9999h" , "duration" ,
98- def , maximum , maximum },
99- {"xlarge" , "/?duration=99999999999h" , "duration" ,
100- def , def , maximum }, // overflows int64
101- {"encoded" , "/?duration=%32%34%68" , "duration" ,
102- def , 24 * time .Hour , maximum }, // "24h" encoded
82+ {"valid" , "/?duration=1h30m" , 90 * time .Minute },
83+ {"space" , "/?duration= 15m " , 15 * time .Minute },
84+ {"missing" , "/" , def },
85+ {"invalid" , "/?duration=none" , def },
86+ {"zero" , "/?duration=0s" , def },
87+ {"negative" , "/?duration=-1h" , def },
88+ {"fraction" , "/?duration=1.5h" , 90 * time .Minute },
89+ {"no-unit" , "/?duration=3333" , def },
90+ {"bad-unit" , "/duration=8h" , def },
91+ {"large" , "/?duration=9999h" , maximum },
92+ {"xlarge" , "/?duration=99999999999h" ,
93+ def }, // overflows int64
94+ {"encoded" , "/?duration=%32%34%68" ,
95+ 24 * time .Hour }, // "24h" encoded
96+ {"encoded-plus" ,
97+ "/?duration=1h%2B30m" , def }, // "1h+30m"
98+ {"unicode-microseconds" ,
99+ "/?duration=1500%C2%B5s" , def }, // below 1s min
100+ {"microseconds" ,
101+ "/?duration=1500us" , def }, // below 1s min
102+ {"leading-decimal" ,
103+ "/?duration=.5s" , def }, // below 1s min
104+ {"overflow-boundary" ,
105+ "/?duration=2562047h47m16.854775807s" , maximum },
106+ {"overflow-one-nanosecond" ,
107+ "/?duration=2562047h47m16.854775808s" , def },
108+ {"tabs-and-newlines" ,
109+ "/?duration=%09%0A15m%0D%0A" , 15 * time .Minute },
110+ {"plus-as-space" ,
111+ "/?duration=+15m+" , 15 * time .Minute },
112+ {"duplicate-first-valid" ,
113+ "/?duration=15m&duration=2h" , 15 * time .Minute },
114+ {"duplicate-first-invalid" ,
115+ "/?duration=invalid&duration=15m" , def },
116+ {"compound-fraction" ,
117+ "/?duration=1h0.5m" , time .Hour + 30 * time .Second },
118+ {"minimum" , "/?duration=1s" , time .Second },
119+ {"below-minimum" , "/?duration=999ms" , def },
120+ {"subsecond" , "/?duration=1ns" , def },
121+ {"at-maximum" , "/?duration=192h" , maximum },
122+ {"case-sensitive-unit" , "/?duration=15M" , def },
123+ {"just-over-maximum" , "/?duration=192h1ns" , maximum },
124+ {"unsupported-days" , "/?duration=1d" , def },
125+ {"plus-zero" , "/?duration=+0s" , def },
126+ {"negative-zero" , "/?duration=-0s" , def },
127+ {"mixed-sign" , "/?duration=1h-30m" , def },
128+ {"embedded-nul" , "/?duration=15m%00ignored" , def },
129+ {"html" , "/?duration=%3Cscript%3Ealert(1)%3C%2Fscript%3E" , def },
103130 }
104131
105132 for _ , tc := range cases {
@@ -112,8 +139,8 @@ func TestParseFormDuration(t *testing.T) {
112139 t .Fatal (err )
113140 }
114141
115- got := parseFormDuration (req , tc . field , tc . def ,
116- settings.Duration {Duration : tc . maximum })
142+ got := parseFormDuration (req , formFieldDuration , def ,
143+ settings.Duration {Duration : maximum })
117144 if got != tc .want {
118145 t .Fatalf ("parseFormDuration(%q) = %v; want %v" ,
119146 tc .query , got , tc .want )
0 commit comments