1 // Copyright 2017 The Abseil Authors.
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 //      https://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 // Unit test for memutil.cc
16 
17 #include "absl/strings/internal/memutil.h"
18 
19 #include <cstdlib>
20 
21 #include "gtest/gtest.h"
22 #include "absl/strings/ascii.h"
23 
24 namespace {
25 
memcasechr(const char * s,int c,size_t slen)26 static char* memcasechr(const char* s, int c, size_t slen) {
27   c = absl::ascii_tolower(c);
28   for (; slen; ++s, --slen) {
29     if (absl::ascii_tolower(*s) == c) return const_cast<char*>(s);
30   }
31   return nullptr;
32 }
33 
memcasematch(const char * phaystack,size_t haylen,const char * pneedle,size_t neelen)34 static const char* memcasematch(const char* phaystack, size_t haylen,
35                                 const char* pneedle, size_t neelen) {
36   if (0 == neelen) {
37     return phaystack;  // even if haylen is 0
38   }
39   if (haylen < neelen) return nullptr;
40 
41   const char* match;
42   const char* hayend = phaystack + haylen - neelen + 1;
43   while ((match = static_cast<char*>(
44               memcasechr(phaystack, pneedle[0], hayend - phaystack)))) {
45     if (absl::strings_internal::memcasecmp(match, pneedle, neelen) == 0)
46       return match;
47     else
48       phaystack = match + 1;
49   }
50   return nullptr;
51 }
52 
TEST(MemUtilTest,AllTests)53 TEST(MemUtilTest, AllTests) {
54   // check memutil functions
55   char a[1000];
56   absl::strings_internal::memcat(a, 0, "hello", sizeof("hello") - 1);
57   absl::strings_internal::memcat(a, 5, " there", sizeof(" there") - 1);
58 
59   EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO there",
60                                                sizeof("hello there") - 1),
61             0);
62   EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO therf",
63                                                sizeof("hello there") - 1),
64             -1);
65   EXPECT_EQ(absl::strings_internal::memcasecmp(a, "heLLO therf",
66                                                sizeof("hello there") - 2),
67             0);
68   EXPECT_EQ(absl::strings_internal::memcasecmp(a, "whatever", 0), 0);
69 
70   char* p = absl::strings_internal::memdup("hello", 5);
71   free(p);
72 
73   p = absl::strings_internal::memrchr("hello there", 'e',
74                                       sizeof("hello there") - 1);
75   EXPECT_TRUE(p && p[-1] == 'r');
76   p = absl::strings_internal::memrchr("hello there", 'e',
77                                       sizeof("hello there") - 2);
78   EXPECT_TRUE(p && p[-1] == 'h');
79   p = absl::strings_internal::memrchr("hello there", 'u',
80                                       sizeof("hello there") - 1);
81   EXPECT_TRUE(p == nullptr);
82 
83   int len = absl::strings_internal::memspn("hello there",
84                                            sizeof("hello there") - 1, "hole");
85   EXPECT_EQ(len, sizeof("hello") - 1);
86   len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1,
87                                        "u");
88   EXPECT_EQ(len, 0);
89   len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1,
90                                        "");
91   EXPECT_EQ(len, 0);
92   len = absl::strings_internal::memspn("hello there", sizeof("hello there") - 1,
93                                        "trole h");
94   EXPECT_EQ(len, sizeof("hello there") - 1);
95   len = absl::strings_internal::memspn("hello there!",
96                                        sizeof("hello there!") - 1, "trole h");
97   EXPECT_EQ(len, sizeof("hello there") - 1);
98   len = absl::strings_internal::memspn("hello there!",
99                                        sizeof("hello there!") - 2, "trole h!");
100   EXPECT_EQ(len, sizeof("hello there!") - 2);
101 
102   len = absl::strings_internal::memcspn("hello there",
103                                         sizeof("hello there") - 1, "leho");
104   EXPECT_EQ(len, 0);
105   len = absl::strings_internal::memcspn("hello there",
106                                         sizeof("hello there") - 1, "u");
107   EXPECT_EQ(len, sizeof("hello there") - 1);
108   len = absl::strings_internal::memcspn("hello there",
109                                         sizeof("hello there") - 1, "");
110   EXPECT_EQ(len, sizeof("hello there") - 1);
111   len = absl::strings_internal::memcspn("hello there",
112                                         sizeof("hello there") - 1, " ");
113   EXPECT_EQ(len, 5);
114 
115   p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1,
116                                       "leho");
117   EXPECT_TRUE(p && p[1] == 'e' && p[2] == 'l');
118   p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1,
119                                       "nu");
120   EXPECT_TRUE(p == nullptr);
121   p = absl::strings_internal::mempbrk("hello there!",
122                                       sizeof("hello there!") - 2, "!");
123   EXPECT_TRUE(p == nullptr);
124   p = absl::strings_internal::mempbrk("hello there", sizeof("hello there") - 1,
125                                       " t ");
126   EXPECT_TRUE(p && p[-1] == 'o' && p[1] == 't');
127 
128   {
129     const char kHaystack[] = "0123456789";
130     EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 0, "", 0), kHaystack);
131     EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "012", 3),
132               kHaystack);
133     EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "0xx", 1),
134               kHaystack);
135     EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "789", 3),
136               kHaystack + 7);
137     EXPECT_EQ(absl::strings_internal::memmem(kHaystack, 10, "9xx", 1),
138               kHaystack + 9);
139     EXPECT_TRUE(absl::strings_internal::memmem(kHaystack, 10, "9xx", 3) ==
140                 nullptr);
141     EXPECT_TRUE(absl::strings_internal::memmem(kHaystack, 10, "xxx", 1) ==
142                 nullptr);
143   }
144   {
145     const char kHaystack[] = "aBcDeFgHiJ";
146     EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 0, "", 0),
147               kHaystack);
148     EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "Abc", 3),
149               kHaystack);
150     EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "Axx", 1),
151               kHaystack);
152     EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "hIj", 3),
153               kHaystack + 7);
154     EXPECT_EQ(absl::strings_internal::memcasemem(kHaystack, 10, "jxx", 1),
155               kHaystack + 9);
156     EXPECT_TRUE(absl::strings_internal::memcasemem(kHaystack, 10, "jxx", 3) ==
157                 nullptr);
158     EXPECT_TRUE(absl::strings_internal::memcasemem(kHaystack, 10, "xxx", 1) ==
159                 nullptr);
160   }
161   {
162     const char kHaystack[] = "0123456789";
163     EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 0, "", 0), kHaystack);
164     EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "012", 3),
165               kHaystack);
166     EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "0xx", 1),
167               kHaystack);
168     EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "789", 3),
169               kHaystack + 7);
170     EXPECT_EQ(absl::strings_internal::memmatch(kHaystack, 10, "9xx", 1),
171               kHaystack + 9);
172     EXPECT_TRUE(absl::strings_internal::memmatch(kHaystack, 10, "9xx", 3) ==
173                 nullptr);
174     EXPECT_TRUE(absl::strings_internal::memmatch(kHaystack, 10, "xxx", 1) ==
175                 nullptr);
176   }
177 }
178 
179 }  // namespace
180