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 15 // +build ignore 16 17 #include "strutil.h" 18 19 #include <assert.h> 20 #include <sys/mman.h> 21 #include <unistd.h> 22 23 #include <string> 24 #include <vector> 25 26 #include "string_piece.h" 27 #include "testutil.h" 28 29 using namespace std; 30 31 namespace { 32 33 void TestWordScanner() { 34 vector<StringPiece> ss; 35 for (StringPiece tok : WordScanner("foo bar baz hogeeeeeeeeeeeeeeee")) { 36 ss.push_back(tok); 37 } 38 assert(ss.size() == 4LU); 39 ASSERT_EQ(ss[0], "foo"); 40 ASSERT_EQ(ss[1], "bar"); 41 ASSERT_EQ(ss[2], "baz"); 42 ASSERT_EQ(ss[3], "hogeeeeeeeeeeeeeeee"); 43 } 44 45 void TestHasPrefix() { 46 assert(HasPrefix("foo", "foo")); 47 assert(HasPrefix("foo", "fo")); 48 assert(HasPrefix("foo", "")); 49 assert(!HasPrefix("foo", "fooo")); 50 } 51 52 void TestHasSuffix() { 53 assert(HasSuffix("bar", "bar")); 54 assert(HasSuffix("bar", "ar")); 55 assert(HasSuffix("bar", "")); 56 assert(!HasSuffix("bar", "bbar")); 57 } 58 59 void TestTrimPrefix() { 60 ASSERT_EQ(TrimPrefix("foo", "foo"), ""); 61 ASSERT_EQ(TrimPrefix("foo", "fo"), "o"); 62 ASSERT_EQ(TrimPrefix("foo", ""), "foo"); 63 ASSERT_EQ(TrimPrefix("foo", "fooo"), "foo"); 64 } 65 66 void TestTrimSuffix() { 67 ASSERT_EQ(TrimSuffix("bar", "bar"), ""); 68 ASSERT_EQ(TrimSuffix("bar", "ar"), "b"); 69 ASSERT_EQ(TrimSuffix("bar", ""), "bar"); 70 ASSERT_EQ(TrimSuffix("bar", "bbar"), "bar"); 71 } 72 73 string SubstPattern(StringPiece str, StringPiece pat, StringPiece subst) { 74 string r; 75 Pattern(pat).AppendSubst(str, subst, &r); 76 return r; 77 } 78 79 void TestSubstPattern() { 80 ASSERT_EQ(SubstPattern("x.c", "%.c", "%.o"), "x.o"); 81 ASSERT_EQ(SubstPattern("c.x", "c.%", "o.%"), "o.x"); 82 ASSERT_EQ(SubstPattern("x.c.c", "%.c", "%.o"), "x.c.o"); 83 ASSERT_EQ(SubstPattern("x.x y.c", "%.c", "%.o"), "x.x y.o"); 84 ASSERT_EQ(SubstPattern("x.%.c", "%.%.c", "OK"), "OK"); 85 ASSERT_EQ(SubstPattern("x.c", "x.c", "OK"), "OK"); 86 ASSERT_EQ(SubstPattern("x.c.c", "x.c", "XX"), "x.c.c"); 87 ASSERT_EQ(SubstPattern("x.x.c", "x.c", "XX"), "x.x.c"); 88 } 89 90 void TestNoLineBreak() { 91 assert(NoLineBreak("a\nb") == "a\\nb"); 92 assert(NoLineBreak("a\nb\nc") == "a\\nb\\nc"); 93 } 94 95 void TestHasWord() { 96 assert(HasWord("foo bar baz", "bar")); 97 assert(HasWord("foo bar baz", "foo")); 98 assert(HasWord("foo bar baz", "baz")); 99 assert(!HasWord("foo bar baz", "oo")); 100 assert(!HasWord("foo bar baz", "ar")); 101 assert(!HasWord("foo bar baz", "ba")); 102 assert(!HasWord("foo bar baz", "az")); 103 assert(!HasWord("foo bar baz", "ba")); 104 assert(!HasWord("foo bar baz", "fo")); 105 } 106 107 static string NormalizePath(string s) { 108 ::NormalizePath(&s); 109 return s; 110 } 111 112 void TestNormalizePath() { 113 ASSERT_EQ(NormalizePath(""), ""); 114 ASSERT_EQ(NormalizePath("."), ""); 115 ASSERT_EQ(NormalizePath("/"), "/"); 116 ASSERT_EQ(NormalizePath("/tmp"), "/tmp"); 117 ASSERT_EQ(NormalizePath("////tmp////"), "/tmp"); 118 ASSERT_EQ(NormalizePath("a////b"), "a/b"); 119 ASSERT_EQ(NormalizePath("a//.//b"), "a/b"); 120 ASSERT_EQ(NormalizePath("a////b//../c/////"), "a/c"); 121 ASSERT_EQ(NormalizePath("../foo"), "../foo"); 122 ASSERT_EQ(NormalizePath("./foo"), "foo"); 123 ASSERT_EQ(NormalizePath("x/y/..//../foo"), "foo"); 124 ASSERT_EQ(NormalizePath("x/../../foo"), "../foo"); 125 ASSERT_EQ(NormalizePath("/../foo"), "/foo"); 126 ASSERT_EQ(NormalizePath("/../../foo"), "/foo"); 127 ASSERT_EQ(NormalizePath("/a/../../foo"), "/foo"); 128 ASSERT_EQ(NormalizePath("/a/b/.."), "/a"); 129 ASSERT_EQ(NormalizePath("../../a/b"), "../../a/b"); 130 ASSERT_EQ(NormalizePath("../../../a/b"), "../../../a/b"); 131 ASSERT_EQ(NormalizePath(".././../a/b"), "../../a/b"); 132 ASSERT_EQ(NormalizePath("./../../a/b"), "../../a/b"); 133 } 134 135 string EscapeShell(string s) { 136 ::EscapeShell(&s); 137 return s; 138 } 139 140 void TestEscapeShell() { 141 ASSERT_EQ(EscapeShell(""), ""); 142 ASSERT_EQ(EscapeShell("foo"), "foo"); 143 ASSERT_EQ(EscapeShell("foo$`\\baz\"bar"), "foo\\$\\`\\\\baz\\\"bar"); 144 ASSERT_EQ(EscapeShell("$$"), "\\$$"); 145 ASSERT_EQ(EscapeShell("$$$"), "\\$$\\$"); 146 ASSERT_EQ(EscapeShell("\\\n"), "\\\\\n"); 147 } 148 149 void TestFindEndOfLine() { 150 size_t lf_cnt = 0; 151 ASSERT_EQ(FindEndOfLine("foo", 0, &lf_cnt), 3); 152 char buf[10] = {'f', 'o', '\\', '\0', 'x', 'y'}; 153 ASSERT_EQ(FindEndOfLine(StringPiece(buf, 6), 0, &lf_cnt), 3); 154 ASSERT_EQ(FindEndOfLine(StringPiece(buf, 2), 0, &lf_cnt), 2); 155 } 156 157 // Take a string, and copy it into an allocated buffer where 158 // the byte immediately after the null termination character 159 // is read protected. Useful for testing, but doesn't support 160 // freeing the allocated pages. 161 const char* CreateProtectedString(const char* str) { 162 int pagesize = sysconf(_SC_PAGE_SIZE); 163 void *buffer; 164 char *buffer_str; 165 166 // Allocate two pages of memory 167 if (posix_memalign(&buffer, pagesize, pagesize * 2) != 0) { 168 perror("posix_memalign failed"); 169 assert(false); 170 } 171 172 // Make the second page unreadable 173 buffer_str = (char*)buffer + pagesize; 174 if (mprotect(buffer_str, pagesize, PROT_NONE) != 0) { 175 perror("mprotect failed"); 176 assert(false); 177 } 178 179 // Then move the test string into the very end of the first page 180 buffer_str -= strlen(str) + 1; 181 strcpy(buffer_str, str); 182 183 return buffer_str; 184 } 185 186 void TestWordScannerInvalidAccess() { 187 vector<StringPiece> ss; 188 for (StringPiece tok : WordScanner(CreateProtectedString("0123 456789"))) { 189 ss.push_back(tok); 190 } 191 assert(ss.size() == 2LU); 192 ASSERT_EQ(ss[0], "0123"); 193 ASSERT_EQ(ss[1], "456789"); 194 } 195 196 void TestFindEndOfLineInvalidAccess() { 197 size_t lf_cnt = 0; 198 ASSERT_EQ(FindEndOfLine(CreateProtectedString("a\\"), 0, &lf_cnt), 2); 199 } 200 201 } // namespace 202 203 int main() { 204 TestWordScanner(); 205 TestHasPrefix(); 206 TestHasSuffix(); 207 TestTrimPrefix(); 208 TestTrimSuffix(); 209 TestSubstPattern(); 210 TestNoLineBreak(); 211 TestHasWord(); 212 TestNormalizePath(); 213 TestEscapeShell(); 214 TestFindEndOfLine(); 215 TestWordScannerInvalidAccess(); 216 TestFindEndOfLineInvalidAccess(); 217 assert(!g_failed); 218 } 219