1 | /************************************************* |
2 | * Perl-Compatible Regular Expressions * |
3 | *************************************************/ |
4 | |
5 | /* PCRE is a library of functions to support regular expressions whose syntax |
6 | and semantics are as close as possible to those of the Perl 5 language. |
7 | |
8 | Written by Philip Hazel |
9 | Original API code Copyright (c) 1997-2012 University of Cambridge |
10 | New API code Copyright (c) 2018-2021 University of Cambridge |
11 | |
12 | ----------------------------------------------------------------------------- |
13 | Redistribution and use in source and binary forms, with or without |
14 | modification, are permitted provided that the following conditions are met: |
15 | |
16 | * Redistributions of source code must retain the above copyright notice, |
17 | this list of conditions and the following disclaimer. |
18 | |
19 | * Redistributions in binary form must reproduce the above copyright |
20 | notice, this list of conditions and the following disclaimer in the |
21 | documentation and/or other materials provided with the distribution. |
22 | |
23 | * Neither the name of the University of Cambridge nor the names of its |
24 | contributors may be used to endorse or promote products derived from |
25 | this software without specific prior written permission. |
26 | |
27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
37 | POSSIBILITY OF SUCH DAMAGE. |
38 | ----------------------------------------------------------------------------- |
39 | */ |
40 | |
41 | /* This module contains internal functions for comparing and finding the length |
42 | of strings. These are used instead of strcmp() etc because the standard |
43 | functions work only on 8-bit data. */ |
44 | |
45 | |
46 | #ifdef HAVE_CONFIG_H |
47 | #include "config.h" |
48 | #endif |
49 | |
50 | #include "pcre2_internal.h" |
51 | |
52 | |
53 | /************************************************* |
54 | * Emulated memmove() for systems without it * |
55 | *************************************************/ |
56 | |
57 | /* This function can make use of bcopy() if it is available. Otherwise do it by |
58 | steam, as there some non-Unix environments that lack both memmove() and |
59 | bcopy(). */ |
60 | |
61 | #if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE) |
62 | void * |
63 | PRIV(memmove)(void *d, const void *s, size_t n) |
64 | { |
65 | #ifdef HAVE_BCOPY |
66 | bcopy(s, d, n); |
67 | return d; |
68 | #else |
69 | size_t i; |
70 | unsigned char *dest = (unsigned char *)d; |
71 | const unsigned char *src = (const unsigned char *)s; |
72 | if (dest > src) |
73 | { |
74 | dest += n; |
75 | src += n; |
76 | for (i = 0; i < n; ++i) *(--dest) = *(--src); |
77 | return (void *)dest; |
78 | } |
79 | else |
80 | { |
81 | for (i = 0; i < n; ++i) *dest++ = *src++; |
82 | return (void *)(dest - n); |
83 | } |
84 | #endif /* not HAVE_BCOPY */ |
85 | } |
86 | #endif /* not VPCOMPAT && not HAVE_MEMMOVE */ |
87 | |
88 | |
89 | /************************************************* |
90 | * Compare two zero-terminated PCRE2 strings * |
91 | *************************************************/ |
92 | |
93 | /* |
94 | Arguments: |
95 | str1 first string |
96 | str2 second string |
97 | |
98 | Returns: 0, 1, or -1 |
99 | */ |
100 | |
101 | int |
102 | PRIV(strcmp)(PCRE2_SPTR str1, PCRE2_SPTR str2) |
103 | { |
104 | PCRE2_UCHAR c1, c2; |
105 | while (*str1 != '\0' || *str2 != '\0') |
106 | { |
107 | c1 = *str1++; |
108 | c2 = *str2++; |
109 | if (c1 != c2) return ((c1 > c2) << 1) - 1; |
110 | } |
111 | return 0; |
112 | } |
113 | |
114 | |
115 | /************************************************* |
116 | * Compare zero-terminated PCRE2 & 8-bit strings * |
117 | *************************************************/ |
118 | |
119 | /* As the 8-bit string is almost always a literal, its type is specified as |
120 | const char *. |
121 | |
122 | Arguments: |
123 | str1 first string |
124 | str2 second string |
125 | |
126 | Returns: 0, 1, or -1 |
127 | */ |
128 | |
129 | int |
130 | PRIV(strcmp_c8)(PCRE2_SPTR str1, const char *str2) |
131 | { |
132 | PCRE2_UCHAR c1, c2; |
133 | while (*str1 != '\0' || *str2 != '\0') |
134 | { |
135 | c1 = *str1++; |
136 | c2 = *str2++; |
137 | if (c1 != c2) return ((c1 > c2) << 1) - 1; |
138 | } |
139 | return 0; |
140 | } |
141 | |
142 | |
143 | /************************************************* |
144 | * Compare two PCRE2 strings, given a length * |
145 | *************************************************/ |
146 | |
147 | /* |
148 | Arguments: |
149 | str1 first string |
150 | str2 second string |
151 | len the length |
152 | |
153 | Returns: 0, 1, or -1 |
154 | */ |
155 | |
156 | int |
157 | PRIV(strncmp)(PCRE2_SPTR str1, PCRE2_SPTR str2, size_t len) |
158 | { |
159 | PCRE2_UCHAR c1, c2; |
160 | for (; len > 0; len--) |
161 | { |
162 | c1 = *str1++; |
163 | c2 = *str2++; |
164 | if (c1 != c2) return ((c1 > c2) << 1) - 1; |
165 | } |
166 | return 0; |
167 | } |
168 | |
169 | |
170 | /************************************************* |
171 | * Compare PCRE2 string to 8-bit string by length * |
172 | *************************************************/ |
173 | |
174 | /* As the 8-bit string is almost always a literal, its type is specified as |
175 | const char *. |
176 | |
177 | Arguments: |
178 | str1 first string |
179 | str2 second string |
180 | len the length |
181 | |
182 | Returns: 0, 1, or -1 |
183 | */ |
184 | |
185 | int |
186 | PRIV(strncmp_c8)(PCRE2_SPTR str1, const char *str2, size_t len) |
187 | { |
188 | PCRE2_UCHAR c1, c2; |
189 | for (; len > 0; len--) |
190 | { |
191 | c1 = *str1++; |
192 | c2 = *str2++; |
193 | if (c1 != c2) return ((c1 > c2) << 1) - 1; |
194 | } |
195 | return 0; |
196 | } |
197 | |
198 | |
199 | /************************************************* |
200 | * Find the length of a PCRE2 string * |
201 | *************************************************/ |
202 | |
203 | /* |
204 | Argument: the string |
205 | Returns: the length |
206 | */ |
207 | |
208 | PCRE2_SIZE |
209 | PRIV(strlen)(PCRE2_SPTR str) |
210 | { |
211 | PCRE2_SIZE c = 0; |
212 | while (*str++ != 0) c++; |
213 | return c; |
214 | } |
215 | |
216 | |
217 | /************************************************* |
218 | * Copy 8-bit 0-terminated string to PCRE2 string * |
219 | *************************************************/ |
220 | |
221 | /* Arguments: |
222 | str1 buffer to receive the string |
223 | str2 8-bit string to be copied |
224 | |
225 | Returns: the number of code units used (excluding trailing zero) |
226 | */ |
227 | |
228 | PCRE2_SIZE |
229 | PRIV(strcpy_c8)(PCRE2_UCHAR *str1, const char *str2) |
230 | { |
231 | PCRE2_UCHAR *t = str1; |
232 | while (*str2 != 0) *t++ = *str2++; |
233 | *t = 0; |
234 | return t - str1; |
235 | } |
236 | |
237 | /* End of pcre2_string_utils.c */ |
238 | |