Home | History | Annotate | Download | only in template
      1 // Copyright 2011 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package template
      6 
      7 import (
      8 	"testing"
      9 )
     10 
     11 func TestURLNormalizer(t *testing.T) {
     12 	tests := []struct {
     13 		url, want string
     14 	}{
     15 		{"", ""},
     16 		{
     17 			"http://example.com:80/foo/bar?q=foo%20&bar=x+y#frag",
     18 			"http://example.com:80/foo/bar?q=foo%20&bar=x+y#frag",
     19 		},
     20 		{" ", "%20"},
     21 		{"%7c", "%7c"},
     22 		{"%7C", "%7C"},
     23 		{"%2", "%252"},
     24 		{"%", "%25"},
     25 		{"%z", "%25z"},
     26 		{"/foo|bar/%5c\u1234", "/foo%7cbar/%5c%e1%88%b4"},
     27 	}
     28 	for _, test := range tests {
     29 		if got := urlNormalizer(test.url); test.want != got {
     30 			t.Errorf("%q: want\n\t%q\nbut got\n\t%q", test.url, test.want, got)
     31 		}
     32 		if test.want != urlNormalizer(test.want) {
     33 			t.Errorf("not idempotent: %q", test.want)
     34 		}
     35 	}
     36 }
     37 
     38 func TestURLFilters(t *testing.T) {
     39 	input := ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f" +
     40 		"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
     41 		` !"#$%&'()*+,-./` +
     42 		`0123456789:;<=>?` +
     43 		`@ABCDEFGHIJKLMNO` +
     44 		`PQRSTUVWXYZ[\]^_` +
     45 		"`abcdefghijklmno" +
     46 		"pqrstuvwxyz{|}~\x7f" +
     47 		"\u00A0\u0100\u2028\u2029\ufeff\U0001D11E")
     48 
     49 	tests := []struct {
     50 		name    string
     51 		escaper func(...interface{}) string
     52 		escaped string
     53 	}{
     54 		{
     55 			"urlEscaper",
     56 			urlEscaper,
     57 			"%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f" +
     58 				"%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f" +
     59 				"%20%21%22%23%24%25%26%27%28%29%2a%2b%2c-.%2f" +
     60 				"0123456789%3a%3b%3c%3d%3e%3f" +
     61 				"%40ABCDEFGHIJKLMNO" +
     62 				"PQRSTUVWXYZ%5b%5c%5d%5e_" +
     63 				"%60abcdefghijklmno" +
     64 				"pqrstuvwxyz%7b%7c%7d~%7f" +
     65 				"%c2%a0%c4%80%e2%80%a8%e2%80%a9%ef%bb%bf%f0%9d%84%9e",
     66 		},
     67 		{
     68 			"urlNormalizer",
     69 			urlNormalizer,
     70 			"%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f" +
     71 				"%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f" +
     72 				"%20!%22#$%25&%27%28%29*+,-./" +
     73 				"0123456789:;%3c=%3e?" +
     74 				"@ABCDEFGHIJKLMNO" +
     75 				"PQRSTUVWXYZ[%5c]%5e_" +
     76 				"%60abcdefghijklmno" +
     77 				"pqrstuvwxyz%7b%7c%7d~%7f" +
     78 				"%c2%a0%c4%80%e2%80%a8%e2%80%a9%ef%bb%bf%f0%9d%84%9e",
     79 		},
     80 	}
     81 
     82 	for _, test := range tests {
     83 		if s := test.escaper(input); s != test.escaped {
     84 			t.Errorf("%s: want\n\t%q\ngot\n\t%q", test.name, test.escaped, s)
     85 			continue
     86 		}
     87 	}
     88 }
     89 
     90 func TestSrcsetFilter(t *testing.T) {
     91 	tests := []struct {
     92 		name  string
     93 		input string
     94 		want  string
     95 	}{
     96 		{
     97 			"one ok",
     98 			"http://example.com/img.png",
     99 			"http://example.com/img.png",
    100 		},
    101 		{
    102 			"one ok with metadata",
    103 			" /img.png 200w",
    104 			" /img.png 200w",
    105 		},
    106 		{
    107 			"one bad",
    108 			"javascript:alert(1) 200w",
    109 			"#ZgotmplZ",
    110 		},
    111 		{
    112 			"two ok",
    113 			"foo.png, bar.png",
    114 			"foo.png, bar.png",
    115 		},
    116 		{
    117 			"left bad",
    118 			"javascript:alert(1), /foo.png",
    119 			"#ZgotmplZ, /foo.png",
    120 		},
    121 		{
    122 			"right bad",
    123 			"/bogus#, javascript:alert(1)",
    124 			"/bogus#,#ZgotmplZ",
    125 		},
    126 	}
    127 
    128 	for _, test := range tests {
    129 		if got := srcsetFilterAndEscaper(test.input); got != test.want {
    130 			t.Errorf("%s: srcsetFilterAndEscaper(%q) want %q != %q", test.name, test.input, test.want, got)
    131 		}
    132 	}
    133 }
    134 
    135 func BenchmarkURLEscaper(b *testing.B) {
    136 	for i := 0; i < b.N; i++ {
    137 		urlEscaper("http://example.com:80/foo?q=bar%20&baz=x+y#frag")
    138 	}
    139 }
    140 
    141 func BenchmarkURLEscaperNoSpecials(b *testing.B) {
    142 	for i := 0; i < b.N; i++ {
    143 		urlEscaper("TheQuickBrownFoxJumpsOverTheLazyDog.")
    144 	}
    145 }
    146 
    147 func BenchmarkURLNormalizer(b *testing.B) {
    148 	for i := 0; i < b.N; i++ {
    149 		urlNormalizer("The quick brown fox jumps over the lazy dog.\n")
    150 	}
    151 }
    152 
    153 func BenchmarkURLNormalizerNoSpecials(b *testing.B) {
    154 	for i := 0; i < b.N; i++ {
    155 		urlNormalizer("http://example.com:80/foo?q=bar%20&baz=x+y#frag")
    156 	}
    157 }
    158 
    159 func BenchmarkSrcsetFilter(b *testing.B) {
    160 	for i := 0; i < b.N; i++ {
    161 		srcsetFilterAndEscaper(" /foo/bar.png 200w, /baz/boo(1).png")
    162 	}
    163 }
    164 
    165 func BenchmarkSrcsetFilterNoSpecials(b *testing.B) {
    166 	for i := 0; i < b.N; i++ {
    167 		srcsetFilterAndEscaper("http://example.com:80/foo?q=bar%20&baz=x+y#frag")
    168 	}
    169 }
    170