1 // Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
2 // Revel Framework source code and usage is governed by a MIT style
3 // license that can be found in the LICENSE file.
9 "github.com/revel/revel"
19 errorsMessage = "validation for %s should not be satisfied with %s\n"
20 noErrorsMessage = "validation for %s should be satisfied with %s\n"
29 func performTests(validator revel.Validator, tests []Expect, t *testing.T) {
30 for _, test := range tests {
31 if validator.IsSatisfied(test.input) != test.expectedResult {
32 if test.expectedResult {
33 t.Errorf(noErrorsMessage, reflect.TypeOf(validator), test.errorMessage)
35 t.Errorf(errorsMessage, reflect.TypeOf(validator), test.errorMessage)
41 func TestRequired(t *testing.T) {
43 {nil, false, "nil data"},
44 {"Testing", true, "non-empty string"},
45 {"", false, "empty string"},
46 {true, true, "true boolean"},
47 {false, false, "false boolean"},
48 {1, true, "positive integer"},
49 {-1, true, "negative integer"},
50 {0, false, "0 integer"},
51 {time.Now(), true, "current time"},
52 {time.Time{}, false, "a zero time"},
53 {func() {}, true, "other non-nil data types"},
54 {net.IP(""), false, "empty IP address"},
57 // testing both the struct and the helper method
58 for _, required := range []revel.Required{{}, revel.ValidRequired()} {
59 performTests(required, tests, t)
63 func TestMin(t *testing.T) {
65 {11, true, "val > min"},
66 {10, true, "val == min"},
67 {9, false, "val < min"},
68 {true, false, "TypeOf(val) != int"},
70 for _, min := range []revel.Min{{10}, revel.ValidMin(10)} {
71 performTests(min, tests, t)
75 func TestMax(t *testing.T) {
77 {9, true, "val < max"},
78 {10, true, "val == max"},
79 {11, false, "val > max"},
80 {true, false, "TypeOf(val) != int"},
82 for _, max := range []revel.Max{{10}, revel.ValidMax(10)} {
83 performTests(max, tests, t)
87 func TestRange(t *testing.T) {
89 {50, true, "min <= val <= max"},
90 {10, true, "val == min"},
91 {100, true, "val == max"},
92 {9, false, "val < min"},
93 {101, false, "val > max"},
96 goodValidators := []revel.Range{
97 {revel.Min{10}, revel.Max{100}},
98 revel.ValidRange(10, 100),
100 for _, rangeValidator := range goodValidators {
101 performTests(rangeValidator, tests, t)
104 testsFloat := []Expect{
105 {50, true, "min <= val <= max"},
106 {10.25, true, "val == min"},
107 {100, true, "val == max"},
108 {9, false, "val < min"},
109 {101, false, "val > max"},
111 goodValidatorsFloat := []revel.Range{
112 {revel.Min{10.25}, revel.Max{100.5}},
113 revel.ValidRangeFloat(10.25, 100.5),
115 for _, rangeValidator := range goodValidatorsFloat {
116 performTests(rangeValidator, testsFloat, t)
120 {10, true, "min == val == max"},
121 {9, false, "val < min && val < max && min == max"},
122 {11, false, "val > min && val > max && min == max"},
125 goodValidators = []revel.Range{
126 {revel.Min{10}, revel.Max{10}},
127 revel.ValidRange(10, 10),
129 for _, rangeValidator := range goodValidators {
130 performTests(rangeValidator, tests, t)
133 tests = make([]Expect, 7)
134 for i, num := range []int{50, 100, 10, 9, 101, 0, -1} {
141 // these are min/max with values swapped, so the min is the high
142 // and max is the low. rangeValidator.IsSatisfied() should ALWAYS
143 // result in false since val can never be greater than min and less
144 // than max when min > max
145 badValidators := []revel.Range{
146 {revel.Min{100}, revel.Max{10}},
147 revel.ValidRange(100, 10),
149 for _, rangeValidator := range badValidators {
150 performTests(rangeValidator, tests, t)
153 badValidatorsFloat := []revel.Range{
154 {revel.Min{100}, revel.Max{10}},
155 revel.ValidRangeFloat(100, 10),
157 for _, rangeValidator := range badValidatorsFloat {
158 performTests(rangeValidator, tests, t)
162 func TestMinSize(t *testing.T) {
163 greaterThanMessage := "len(val) >= min"
165 {"12", true, greaterThanMessage},
166 {"123", true, greaterThanMessage},
167 {[]int{1, 2}, true, greaterThanMessage},
168 {[]int{1, 2, 3}, true, greaterThanMessage},
169 {"", false, "len(val) <= min"},
170 {"手", false, "len(val) <= min"},
171 {[]int{}, false, "len(val) <= min"},
172 {nil, false, "TypeOf(val) != string && TypeOf(val) != slice"},
175 for _, minSize := range []revel.MinSize{{2}, revel.ValidMinSize(2)} {
176 performTests(minSize, tests, t)
180 func TestMaxSize(t *testing.T) {
181 lessThanMessage := "len(val) <= max"
183 {"", true, lessThanMessage},
184 {"12", true, lessThanMessage},
185 {"ルビー", true, lessThanMessage},
186 {[]int{}, true, lessThanMessage},
187 {[]int{1, 2}, true, lessThanMessage},
188 {[]int{1, 2, 3}, true, lessThanMessage},
189 {"1234", false, "len(val) >= max"},
190 {[]int{1, 2, 3, 4}, false, "len(val) >= max"},
192 for _, maxSize := range []revel.MaxSize{{3}, revel.ValidMaxSize(3)} {
193 performTests(maxSize, tests, t)
197 func TestLength(t *testing.T) {
199 {"12", true, "len(val) == length"},
200 {"火箭", true, "len(val) == length"},
201 {[]int{1, 2}, true, "len(val) == length"},
202 {"123", false, "len(val) > length"},
203 {[]int{1, 2, 3}, false, "len(val) > length"},
204 {"1", false, "len(val) < length"},
205 {[]int{1}, false, "len(val) < length"},
206 {nil, false, "TypeOf(val) != string && TypeOf(val) != slice"},
208 for _, length := range []revel.Length{{2}, revel.ValidLength(2)} {
209 performTests(length, tests, t)
213 func TestMatch(t *testing.T) {
215 {"bca123", true, `"[abc]{3}\d*" matches "bca123"`},
216 {"bc123", false, `"[abc]{3}\d*" does not match "bc123"`},
217 {"", false, `"[abc]{3}\d*" does not match ""`},
219 regex := regexp.MustCompile(`[abc]{3}\d*`)
220 for _, match := range []revel.Match{{regex}, revel.ValidMatch(regex)} {
221 performTests(match, tests, t)
225 func TestEmail(t *testing.T) {
226 // unicode char included
227 validStartingCharacters := strings.Split("!#$%^&*_+1234567890abcdefghijklmnopqrstuvwxyzñ", "")
228 invalidCharacters := strings.Split(" ()", "")
230 definiteInvalidDomains := []string{
231 "", // any empty string (x@)
232 ".com", // only the TLD (x@.com)
233 ".", // only the . (x@.)
234 ".*", // TLD containing symbol (x@.*)
236 "a!@#$%^&*()+_.com", // characters which are not ASCII/0-9/dash(-) in a domain
237 "-a.com", // host starting with any symbol
238 "a-.com", // host ending with any symbol
239 "aå.com", // domain containing unicode (however, unicode domains do exist in the state of xn--<POINT>.com e.g. å.com = xn--5ca.com)
242 // Email pattern is not exposed
243 emailPattern := regexp.MustCompile("^[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?$")
244 for _, email := range []revel.Email{{revel.Match{emailPattern}}, revel.ValidEmail()} {
245 var currentEmail string
247 // test invalid starting chars
248 for _, startingChar := range validStartingCharacters {
249 currentEmail = fmt.Sprintf("%sñbc+123@do-main.com", startingChar)
250 if email.IsSatisfied(currentEmail) {
251 t.Errorf(noErrorsMessage, "starting characters", fmt.Sprintf("email = %s", currentEmail))
254 // validation should fail because of multiple @ symbols
255 currentEmail = fmt.Sprintf("%s@ñbc+123@do-main.com", startingChar)
256 if email.IsSatisfied(currentEmail) {
257 t.Errorf(errorsMessage, "starting characters with multiple @ symbols", fmt.Sprintf("email = %s", currentEmail))
260 // should fail simply because of the invalid char
261 for _, invalidChar := range invalidCharacters {
262 currentEmail = fmt.Sprintf("%sñbc%s+123@do-main.com", startingChar, invalidChar)
263 if email.IsSatisfied(currentEmail) {
264 t.Errorf(errorsMessage, "invalid starting characters", fmt.Sprintf("email = %s", currentEmail))
269 // test invalid domains
270 for _, invalidDomain := range definiteInvalidDomains {
271 currentEmail = fmt.Sprintf("a@%s", invalidDomain)
272 if email.IsSatisfied(currentEmail) {
273 t.Errorf(errorsMessage, "invalid domain", fmt.Sprintf("email = %s", currentEmail))
277 // should always be satisfied
278 if !email.IsSatisfied("t0.est+email123@1abc0-def.com") {
279 t.Errorf(noErrorsMessage, "guaranteed valid email", fmt.Sprintf("email = %s", "t0.est+email123@1abc0-def.com"))
282 // should never be satisfied (this is redundant given the loops above)
283 if email.IsSatisfied("a@xcom") {
284 t.Errorf(noErrorsMessage, "guaranteed invalid email", fmt.Sprintf("email = %s", "a@xcom"))
286 if email.IsSatisfied("a@@x.com") {
287 t.Errorf(noErrorsMessage, "guaranteed invalid email", fmt.Sprintf("email = %s", "a@@x.com"))
292 func runIPAddrTestfunc(t *testing.T, test_type int, ipaddr_list map[string]bool, msg_fmt string) {
294 // generate dataset for test
295 test_ipaddr_list := []Expect{}
296 for ipaddr, expected := range ipaddr_list {
297 test_ipaddr_list = append(test_ipaddr_list, Expect{input: ipaddr, expectedResult: expected, errorMessage: fmt.Sprintf(msg_fmt, ipaddr)})
300 for _, ip_test_list := range []revel.IPAddr{{[]int{test_type}}, revel.ValidIPAddr(test_type)} {
301 performTests(ip_test_list, test_ipaddr_list, t)
305 func TestIPAddr(t *testing.T) {
308 test_ipv4_ipaddrs := map[string]bool{
314 "912.456.123.123": false,
315 "999.999.999.999": false,
316 "192.192.19.999": false,
320 test_ipv4_with_cidr_ipaddrs := map[string]bool{
321 "192.168.1.1/24": true,
322 "127.0.0.1/32": true,
323 "10.10.90.12/8": true,
326 "192.168.1.1/99": false,
327 "127.0.0.1/9999": false,
328 "10.10.90.12/33": false,
329 "8.8.8.8/128": false,
330 "4.4.4.4/256": false,
334 test_ipv6_ipaddrs := map[string]bool{
335 "2607:f0d0:1002:51::4": true,
336 "2607:f0d0:1002:0051:0000:0000:0000:0004": true,
338 "FE80:0000:0000:0000:0202:B3FF:FE1E:8329": true,
339 "FE80::0202:B3FF:FE1E:8329": true,
340 "fe80::202:b3ff:fe1e:8329": true,
341 "fe80:0000:0000:0000:0202:b3ff:fe1e:8329": true,
342 "2001:470:1f09:495::3": true,
343 "2001:470:1f1d:275::1": true,
344 "2600:9000:5304:200::1": true,
345 "2600:9000:5306:d500::1": true,
346 "2600:9000:5301:b600::1": true,
347 "2600:9000:5303:900::1": true,
348 "127:12:12:12:12:12:!2:!2": false,
350 "234:23:23:23:23:23:23": false,
354 test_ipv6_with_cidr_ipaddrs := map[string]bool{
357 "2001:db8::/33": true,
358 "2001:db8::/48": true,
362 //IPv4-Mapped Embedded IPv6 Address
363 test_ipv4_mapped_ipv6_ipaddrs := map[string]bool{
364 "2001:470:1f09:495::3:217.126.185.215": true,
365 "2001:470:1f1d:275::1:213.0.69.132": true,
366 "2600:9000:5304:200::1:205.251.196.2": true,
367 "2600:9000:5306:d500::1:205.251.198.213": true,
368 "2600:9000:5301:b600::1:205.251.193.182": true,
369 "2600:9000:5303:900::1:205.251.195.9": true,
370 "0:0:0:0:0:FFFF:222.1.41.90": true,
371 "::FFFF:222.1.41.90": true,
372 "0000:0000:0000:0000:0000:FFFF:12.155.166.101": true,
373 "12.155.166.101": false,
377 runIPAddrTestfunc(t, revel.IPv4, test_ipv4_ipaddrs, "invalid (%s) IPv4 address")
378 runIPAddrTestfunc(t, revel.IPv4CIDR, test_ipv4_with_cidr_ipaddrs, "invalid (%s) IPv4 with CIDR address")
380 runIPAddrTestfunc(t, revel.IPv6, test_ipv6_ipaddrs, "invalid (%s) IPv6 address")
381 runIPAddrTestfunc(t, revel.IPv6CIDR, test_ipv6_with_cidr_ipaddrs, "invalid (%s) IPv6 with CIDR address")
382 runIPAddrTestfunc(t, revel.IPv4MappedIPv6, test_ipv4_mapped_ipv6_ipaddrs, "invalid (%s) IPv4-Mapped Embedded IPv6 address")
385 func TestMacAddr(t *testing.T) {
387 macaddr_list := map[string]bool{
388 "02:f3:71:eb:9e:4b": true,
389 "02-f3-71-eb-9e-4b": true,
390 "02f3.71eb.9e4b": true,
391 "87:78:6e:3e:90:40": true,
392 "87-78-6e-3e-90-40": true,
393 "8778.6e3e.9040": true,
394 "e7:28:b9:57:ab:36": true,
395 "e7-28-b9-57-ab-36": true,
396 "e728.b957.ab36": true,
397 "eb:f8:2b:d7:e9:62": true,
398 "eb-f8-2b-d7-e9-62": true,
399 "ebf8.2bd7.e962": true,
402 test_macaddr_list := []Expect{}
403 for macaddr, expected := range macaddr_list {
404 test_macaddr_list = append(test_macaddr_list, Expect{input: macaddr, expectedResult: expected, errorMessage: fmt.Sprintf("invalid (%s) MAC address", macaddr)})
407 for _, mac_test_list := range []revel.MacAddr{{}, revel.ValidMacAddr()} {
408 performTests(mac_test_list, test_macaddr_list, t)
412 func TestDomain(t *testing.T) {
414 test_domains := map[string]bool{
415 "대한민국.xn-korea.co.kr": true,
417 "masełkowski.pl": true,
418 "maselkowski.pl": true,
419 "m.maselkowski.pl": true,
420 "www.masełkowski.pl.com": true,
421 "xn--masekowski-d0b.pl": true,
422 "中国互联网络信息中心.中国": true,
423 "masełkowski.pl.": false,
424 "中国互联网络信息中心.xn--masekowski-d0b": false,
430 "qwd-qwdqwd.com": true,
431 "qwd-qwdqwd.co_m": false,
432 "qwd-qwdqwd.c": false,
433 "qwd-qwdqwd.-12": false,
434 "qwd-qwdqwd.1212": false,
435 "qwd-qwdqwd.org": true,
436 "qwd-qwdqwd.ac.kr": true,
437 "qwd-qwdqwd.gov": true,
438 "chicken.beer": true,
440 "google.asn.au": true,
441 "google.com.au": true,
442 "google.net.au": true,
443 "google.priv.at": true,
444 "google.ac.at": true,
445 "google.gv.at": true,
446 "google.avocat.fr": true,
447 "google.geek.nz": true,
448 "google.gen.nz": true,
449 "google.kiwi.nz": true,
450 "google.org.il": true,
451 "google.net.il": true,
452 "www.google.edu.au": true,
453 "www.google.gov.au": true,
454 "www.google.csiro.au": true,
455 "www.google.act.au": true,
456 "www.google.avocat.fr": true,
457 "www.google.aeroport.fr": true,
458 "www.google.co.nz": true,
459 "www.google.geek.nz": true,
460 "www.google.gen.nz": true,
461 "www.google.kiwi.nz": true,
462 "www.google.parliament.nz": true,
463 "www.google.muni.il": true,
464 "www.google.idf.il": true,
469 for domain, expected := range test_domains {
470 tests = append(tests, Expect{input: domain, expectedResult: expected, errorMessage: fmt.Sprintf("invalid (%s) domain", domain)})
473 for _, domain := range []revel.Domain{{}, revel.ValidDomain()} {
474 performTests(domain, tests, t)
478 func TestURL(t *testing.T) {
480 test_urls := map[string]bool{
481 "https://www.google.co.kr/url?sa=t&rct=j&q=&esrc=s&source=web": true,
482 "http://stackoverflow.com/questions/27812164/can-i-import-3rd-party-package-into-golang-playground": true,
483 "https://tour.golang.org/welcome/4": true,
484 "https://revel.github.io/": true,
485 "https://github.com/revel/revel/commit/bd1d083ee4345e919b3bca1e4c42ca682525e395#diff-972a2b2141d27e9d7a8a4149a7e28eef": true,
486 "https://github.com/ndevilla/iniparser/pull/82#issuecomment-261817064": true,
487 "http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=golang": true,
488 "http://www.baidu.com/link?url=DrWkM_beo2M5kB5sLYnItKSQ0Ib3oDhKcPprdtLzAWNfFt_VN5oyD3KwnAKT6Xsk": true,
493 for url, expected := range test_urls {
494 tests = append(tests, Expect{input: url, expectedResult: expected, errorMessage: fmt.Sprintf("invalid (%s) url", url)})
497 for _, url := range []revel.URL{{}, revel.ValidURL()} {
498 performTests(url, tests, t)
503 func TestPureTextNormal(t *testing.T) {
505 test_txts := map[string]bool{
506 `<script ?>qwdpijqwd</script>qd08j123lneqw\t\nqwedojiqwd\rqwdoihjqwd1d[08jaedl;jkqwd\r\nqdolijqdwqwd`: false,
507 `a\r\nb<script ?>qwdpijqwd</script>qd08j123lneqw\t\nqwedojiqwd\rqwdoihjqwd1d[08jaedl;jkqwd\r\nqdolijqdwqwd`: false,
508 `Foo<script type="text/javascript">alert(1337)</script>Bar`: false,
511 `Foo</br>Bar`: false,
512 `Foo <!-- Bar --> Baz`: false,
513 `I <3 Ponies!`: true,
514 `I   like Golang\t\n`: true,
515 `I & like Golang\t\n`: false,
516 `<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration debug="true" xmlns:log4j='http://jakarta.apache.org/log4j/'> <appender name="console" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" /> </layout> </appender> <root> <level value="DEBUG" /> <appender-ref ref="console" /> </root> </log4j:configuration>`: false,
517 `I like Golang\r\n`: true,
518 `I like Golang\r\na`: true,
519 "I   like Golang\t\n": true,
520 "I & like Golang\t\n": false,
521 `ハイレゾ対応ウォークマン®、ヘッドホン、スピーカー「Winter Gift Collection ~Presented by JUJU~」をソニーストアにて販売開始`: true,
522 `VAIOパーソナルコンピューター type T TZシリーズ 無償点検・修理のお知らせとお詫び(2009年10月15日更新)`: true,
523 `把百度设为主页关于百度About Baidu百度推广`: true,
524 `%E6%8A%8A%E7%99%BE%E5%BA%A6%E8%AE%BE%E4%B8%BA%E4%B8%BB%E9%A1%B5%E5%85%B3%E4%BA%8E%E7%99%BE%E5%BA%A6About++Baidu%E7%99%BE%E5%BA%A6%E6%8E%A8%E5%B9%BF`: true,
525 `%E6%8A%8A%E7%99%BE%E5%BA%A6%E8%AE%BE%E4%B8%BA%E4%B8%BB%E9%A1%B5%E5%85%B3%E4%BA%8E%E7%99%BE%E5%BA%A6About%20%20Baidu%E7%99%BE%E5%BA%A6%E6%8E%A8%E5%B9%BF`: true,
526 `abcd/>qwdqwdoijhwer/>qwdojiqwdqwd</>qwdoijqwdoiqjd`: true,
527 `abcd/>qwdqwdoijhwer/>qwdojiqwdqwd</a>qwdoijqwdoiqjd`: false,
532 for txt, expected := range test_txts {
533 tests = append(tests, Expect{input: txt, expectedResult: expected, errorMessage: fmt.Sprintf("invalid (%#v) text", txt)})
537 for _, txt := range []revel.PureText{{revel.NORMAL}, revel.ValidPureText(revel.NORMAL)} {
538 performTests(txt, tests, t)
542 func TestPureTextStrict(t *testing.T) {
544 test_txts := map[string]bool{
545 `<script ?>qwdpijqwd</script>qd08j123lneqw\t\nqwedojiqwd\rqwdoihjqwd1d[08jaedl;jkqwd\r\nqdolijqdwqwd`: false,
546 `a\r\nb<script ?>qwdpijqwd</script>qd08j123lneqw\t\nqwedojiqwd\rqwdoihjqwd1d[08jaedl;jkqwd\r\nqdolijqdwqwd`: false,
547 `Foo<script type="text/javascript">alert(1337)</script>Bar`: false,
550 `Foo</br>Bar`: false,
551 `Foo <!-- Bar --> Baz`: false,
552 `I <3 Ponies!`: true,
553 `I   like Golang\t\n`: true,
554 `I & like Golang\t\n`: false,
555 `<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration debug="true" xmlns:log4j='http://jakarta.apache.org/log4j/'> <ender name="console" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p 1}:%L - %m%n" /> </layout> </appender> <root> <level value="DEBUG" /> <appender-ref ref="console" /> </root> </log4j:configuration>`: false,
556 `I like Golang\r\n`: true,
557 `I like Golang\r\na`: true,
558 "I   like Golang\t\n": true,
559 "I & like Golang\t\n": false,
560 `ハイレゾ対応ウォークマン®、ヘッドホン、スピーカー「Winter Gift Collection ~Presented by JUJU~」をソニーストアにて販売開始`: true,
561 `VAIOパーソナルコンピューター type T TZシリーズ 無償点検・修理のお知らせとお詫び(2009年10月15日更新)`: true,
562 `把百度设为主页关于百度About Baidu百度推广`: true,
563 `%E6%8A%8A%E7%99%BE%E5%BA%A6%E8%AE%BE%E4%B8%BA%E4%B8%BB%E9%A1%B5%E5%85%B3%E4%BA%8E%E7%99%BE%E5%BA%A6About++Baidu%E7%99%BE%E5%BA%A6%E6%8E%A8%E5%B9%BF`: true,
564 `%E6%8A%8A%E7%99%BE%E5%BA%A6%E8%AE%BE%E4%B8%BA%E4%B8%BB%E9%A1%B5%E5%85%B3%E4%BA%8E%E7%99%BE%E5%BA%A6About%20%20Baidu%E7%99%BE%E5%BA%A6%E6%8E%A8%E5%B9%BF`: true,
565 `abcd/>qwdqwdoijhwer/>qwdojiqwdqwd</>qwdoijqwdoiqjd`: true,
566 `abcd/>qwdqwdoijhwer/>qwdojiqwdqwd</a>qwdoijqwdoiqjd`: false,
571 for txt, expected := range test_txts {
572 tests = append(tests, Expect{input: txt, expectedResult: expected, errorMessage: fmt.Sprintf("invalid (%#v) text", txt)})
576 for _, txt := range []revel.PureText{{revel.STRICT}, revel.ValidPureText(revel.STRICT)} {
577 performTests(txt, tests, t)
581 func TestFilePathOnlyFilePath(t *testing.T) {
583 test_filepaths := map[string]bool{
584 "../../qwdqwdqwd/../qwdqwdqwd.txt": false,
586 /qwdqwdqwd.txt`: false,
587 "\t../../qwdqwdqwd/../qwdqwdqwd.txt": false,
588 `
\16../../qwdqwdqwd/../qwdqwdqwd.txt`: false,
589 `../../qwdqwdqwd/..
\ 2/qwdqwdqwd.txt`: false,
590 "../../etc/passwd": false,
591 "a.txt;rm -rf /": false,
592 "sudo rm -rf ../": false,
593 "a-1-s-d-v-we-wd_+qwd-qwd-qwd.txt": false,
594 "a-qwdqwd_qwdqwdqwd-123.txt": true,
596 "a-1-e-r-t-_1_21234_d_1234_qwed_1423_.txt": true,
601 for filepath, expected := range test_filepaths {
602 tests = append(tests, Expect{input: filepath, expectedResult: expected, errorMessage: fmt.Sprintf("unsanitary (%#v) string", filepath)})
605 // filename without relative path
606 for _, filepath := range []revel.FilePath{{revel.ONLY_FILENAME}, revel.ValidFilePath(revel.ONLY_FILENAME)} {
607 performTests(filepath, tests, t)
611 func TestFilePathAllowRelativePath(t *testing.T) {
613 test_filepaths := map[string]bool{
614 "../../qwdqwdqwd/../qwdqwdqwd.txt": true,
616 /qwdqwdqwd.txt`: false,
617 "\t../../qwdqwdqwd/../qwdqwdqwd.txt": false,
618 `
\16../../qwdqwdqwd/../qwdqwdqwd.txt`: false,
619 `../../qwdqwdqwd/..
\ 2/qwdqwdqwd.txt`: false,
620 "../../etc/passwd": true,
621 "a.txt;rm -rf /": false,
622 "sudo rm -rf ../": true,
623 "a-1-s-d-v-we-wd_+qwd-qwd-qwd.txt": false,
624 "a-qwdqwd_qwdqwdqwd-123.txt": true,
626 "a-1-e-r-t-_1_21234_d_1234_qwed_1423_.txt": true,
627 "/asdasd/asdasdasd/qwdqwd_qwdqwd/12-12/a-1-e-r-t-_1_21234_d_1234_qwed_1423_.txt": true,
632 for filepath, expected := range test_filepaths {
633 tests = append(tests, Expect{input: filepath, expectedResult: expected, errorMessage: fmt.Sprintf("unsanitary (%#v) string", filepath)})
636 // filename with relative path
637 for _, filepath := range []revel.FilePath{{revel.ALLOW_RELATIVE_PATH}, revel.ValidFilePath(revel.ALLOW_RELATIVE_PATH)} {
638 performTests(filepath, tests, t)