1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package proptools
16
17import (
18	"os/exec"
19	"testing"
20)
21
22type escapeTestCase struct {
23	name string
24	in   string
25	out  string
26}
27
28var ninjaEscapeTestCase = []escapeTestCase{
29	{
30		name: "no escaping",
31		in:   `test`,
32		out:  `test`,
33	},
34	{
35		name: "leading $",
36		in:   `$test`,
37		out:  `$$test`,
38	},
39	{
40		name: "trailing $",
41		in:   `test$`,
42		out:  `test$$`,
43	},
44	{
45		name: "leading and trailing $",
46		in:   `$test$`,
47		out:  `$$test$$`,
48	},
49}
50
51var shellEscapeTestCase = []escapeTestCase{
52	{
53		name: "no escaping",
54		in:   `test`,
55		out:  `test`,
56	},
57	{
58		name: "leading $",
59		in:   `$test`,
60		out:  `'$test'`,
61	},
62	{
63		name: "trailing $",
64		in:   `test$`,
65		out:  `'test$'`,
66	},
67	{
68		name: "leading and trailing $",
69		in:   `$test$`,
70		out:  `'$test$'`,
71	},
72	{
73		name: "single quote",
74		in:   `'`,
75		out:  `''\'''`,
76	},
77	{
78		name: "multiple single quote",
79		in:   `''`,
80		out:  `''\'''\'''`,
81	},
82	{
83		name: "double quote",
84		in:   `""`,
85		out:  `'""'`,
86	},
87	{
88		name: "ORIGIN",
89		in:   `-Wl,--rpath,${ORIGIN}/../bionic-loader-test-libs`,
90		out:  `'-Wl,--rpath,${ORIGIN}/../bionic-loader-test-libs'`,
91	},
92}
93
94var shellEscapeIncludingSpacesTestCase = []escapeTestCase{
95	{
96		name: "no escaping",
97		in:   `test`,
98		out:  `test`,
99	},
100	{
101		name: "spacing",
102		in:   `arg1 arg2`,
103		out:  `'arg1 arg2'`,
104	},
105	{
106		name: "single quote",
107		in:   `'arg'`,
108		out:  `''\''arg'\'''`,
109	},
110}
111
112func TestNinjaEscaping(t *testing.T) {
113	for _, testCase := range ninjaEscapeTestCase {
114		got := NinjaEscape(testCase.in)
115		if got != testCase.out {
116			t.Errorf("%s: expected `%s` got `%s`", testCase.name, testCase.out, got)
117		}
118	}
119}
120
121func TestShellEscaping(t *testing.T) {
122	for _, testCase := range shellEscapeTestCase {
123		got := ShellEscape(testCase.in)
124		if got != testCase.out {
125			t.Errorf("%s: expected `%s` got `%s`", testCase.name, testCase.out, got)
126		}
127	}
128}
129
130func TestShellEscapeIncludingSpaces(t *testing.T) {
131	for _, testCase := range shellEscapeIncludingSpacesTestCase {
132		got := ShellEscapeIncludingSpaces(testCase.in)
133		if got != testCase.out {
134			t.Errorf("%s: expected `%s` got `%s`", testCase.name, testCase.out, got)
135		}
136	}
137}
138
139func TestExternalShellEscaping(t *testing.T) {
140	if testing.Short() {
141		return
142	}
143	for _, testCase := range shellEscapeTestCase {
144		cmd := "echo -n " + ShellEscape(testCase.in)
145		got, err := exec.Command("/bin/sh", "-c", cmd).Output()
146		if err != nil {
147			t.Error(err)
148		}
149		if string(got) != testCase.in {
150			t.Errorf("%s: expected `%s` got `%s`", testCase.name, testCase.in, got)
151		}
152	}
153}
154
155func TestExternalShellEscapeIncludingSpaces(t *testing.T) {
156	if testing.Short() {
157		return
158	}
159	for _, testCase := range shellEscapeIncludingSpacesTestCase {
160		cmd := "echo -n " + ShellEscapeIncludingSpaces(testCase.in)
161		got, err := exec.Command("/bin/sh", "-c", cmd).Output()
162		if err != nil {
163			t.Error(err)
164		}
165		if string(got) != testCase.in {
166			t.Errorf("%s: expected `%s` got `%s`", testCase.name, testCase.in, got)
167		}
168	}
169}
170