github.com/kovansky/hugo@v0.92.3-0.20220224232819-63076e4ff19f/tpl/internal/go_templates/htmltemplate/url_test.go (about)

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