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