util_test.go 3.34 KB
Newer Older
Kirill Smelkov's avatar
Kirill Smelkov committed
1 2 3 4 5 6 7
// Copyright (C) 2015-2016  Nexedi SA and Contributors.
//                          Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
8 9 10 11 12 13
// You can also Link and Combine this program with other software covered by
// the terms of any of the Free Software licenses or any of the Open Source
// Initiative approved licenses and Convey the resulting work. Corresponding
// source of such a combination shall include the source code for all other
// software used.
//
Kirill Smelkov's avatar
Kirill Smelkov committed
14 15 16 17
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
18
// See https://www.nexedi.com/licensing for rationale and options.
Kirill Smelkov's avatar
Kirill Smelkov committed
19 20 21 22

package main

import (
Kirill Smelkov's avatar
Kirill Smelkov committed
23 24
	"strings"
	"testing"
Kirill Smelkov's avatar
Kirill Smelkov committed
25 26 27
)

func TestPathEscapeUnescape(t *testing.T) {
Kirill Smelkov's avatar
Kirill Smelkov committed
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
	type TestEntry struct { path string; escapedv []string }
	te := func(path string, escaped ...string) TestEntry {
		return TestEntry{path, escaped}
	}
	var tests = []TestEntry{
		//  path           escaped        non-canonical escapes
		te("hello/world", "hello/world", "%68%65%6c%6c%6f%2f%77%6f%72%6c%64"),
		te("hello/мир", "hello/мир"),
		te("hello/ мир", "hello/%20мир"),
		te("hel%lo/мир", "hel%25lo/мир"),
		te(".hello/.world", "%2Ehello/%2Eworld"),
		te("..hello/world.loc", "%2E.hello/world.loc"),
		te("..hello/world.lock", "%2E.hello/world%2Elock"),
		// leading /
		te("/hello/world", "/hello/world"),
		te("//hello///world", "//hello///world"),
		// trailing /
		te("/hello/world/", "/hello/world"),
		te("/hello/world//", "/hello/world"),
Kirill Smelkov's avatar
Kirill Smelkov committed
47

Kirill Smelkov's avatar
Kirill Smelkov committed
48 49 50 51 52
		// trailing ...
		te("/hello/world.", "/hello/world."),
		te("/hello/world..", "/hello/world%2E."),
		te("/hello/world...", "/hello/world%2E%2E."),
		te("/hello/world...git", "/hello/world%2E%2E.git"),
Kirill Smelkov's avatar
Kirill Smelkov committed
53

Kirill Smelkov's avatar
Kirill Smelkov committed
54 55 56 57 58 59 60 61
		// .. anywhere
		te("/hello/./world", "/hello/%2E/world"),
		te("/hello/.a/world", "/hello/%2Ea/world"),
		te("/hello/a./world", "/hello/a./world"),
		te("/hello/../world", "/hello/%2E./world"),
		te("/hello/a..b/world", "/hello/a%2E.b/world"),
		te("/hello/a.c.b/world", "/hello/a.c.b/world"),
		te("/hello/a.c..b/world", "/hello/a.c%2E.b/world"),
Kirill Smelkov's avatar
Kirill Smelkov committed
62

Kirill Smelkov's avatar
Kirill Smelkov committed
63 64
		// special & control characters
		te("/hel lo/wor\tld/a:?[\\^~*@%b/\001\004\n\xc2\xa0", "/hel%20lo/wor%09ld/a%3A%3F%5B%5C%5E%7E%2A%40%25b/%01%04%0A%C2%A0"),
Kirill Smelkov's avatar
Kirill Smelkov committed
65

Kirill Smelkov's avatar
Kirill Smelkov committed
66 67 68
		// utf8 error
		te("a\xc5z", "a%C5z"),
	}
Kirill Smelkov's avatar
Kirill Smelkov committed
69

Kirill Smelkov's avatar
Kirill Smelkov committed
70 71 72 73 74 75 76 77 78 79 80 81 82 83
	for _, tt := range tests {
		escaped := path_refescape(tt.path)
		if escaped != tt.escapedv[0] {
			t.Errorf("path_refescape(%q) -> %q  ; want %q", tt.path, escaped, tt.escapedv[0])
		}
		// also check the decoding
		pathok := strings.TrimRight(tt.path, "/")
		for _, escaped := range tt.escapedv {
			unescaped, err := path_refunescape(escaped)
			if unescaped != pathok || err != nil {
				t.Errorf("path_refunescape(%q) -> %q %v  ; want %q nil", escaped, unescaped, err, tt.path)
			}
		}
	}
Kirill Smelkov's avatar
Kirill Smelkov committed
84 85 86
}

func TestPathUnescapeErr(t *testing.T) {
Kirill Smelkov's avatar
Kirill Smelkov committed
87 88 89 90 91 92
	var tests = []struct{ escaped string }{
		{"%"},
		{"%2"},
		{"%2q"},
		{"hell%2q/world"},
	}
Kirill Smelkov's avatar
Kirill Smelkov committed
93

Kirill Smelkov's avatar
Kirill Smelkov committed
94 95 96 97 98 99
	for _, tt := range tests {
		unescaped, err := path_refunescape(tt.escaped)
		if err == nil || unescaped != "" {
			t.Errorf("path_refunescape(%q) -> %q %v  ; want \"\" err", tt.escaped, unescaped, err)
		}
	}
Kirill Smelkov's avatar
Kirill Smelkov committed
100
}