Home | History | Annotate | Download | only in kati
      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