Coverage Report

Created: 2026-09-03 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libgit2/deps/pcre2/pcre2_find_bracket.c
Line
Count
Source
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) 2016-2024 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
42
/* This module contains a single function that scans through a compiled pattern
43
until it finds a capturing bracket with the given number, or, if the number is
44
negative, an instance of OP_REVERSE or OP_VREVERSE for a lookbehind. The
45
function is called from pcre2_compile.c and also from pcre2_study.c when
46
finding the minimum matching length. */
47
48
49
#include "pcre2_internal.h"
50
51
52
53
/*************************************************
54
*    Scan compiled regex for specific bracket    *
55
*************************************************/
56
57
/*
58
Arguments:
59
  code        points to start of expression
60
  utf         TRUE in UTF mode
61
  number      the required bracket number or negative to find a lookbehind
62
63
Returns:      pointer to the opcode for the bracket, or NULL if not found
64
*/
65
66
PCRE2_SPTR
67
PRIV(find_bracket)(PCRE2_SPTR code, BOOL utf, int number)
68
17.2k
{
69
17.2k
for (;;)
70
1.74M
  {
71
1.74M
  PCRE2_UCHAR c = *code;
72
73
1.74M
  if (c == OP_END) return NULL;
74
75
  /* XCLASS is used for classes that cannot be represented just by a bit map.
76
  This includes negated single high-valued characters. ECLASS is used for
77
  classes that use set operations internally. CALLOUT_STR is used for
78
  callouts with string arguments. In each case the length in the table is
79
  zero; the actual length is stored in the compiled code. */
80
81
1.74M
  if (c == OP_XCLASS || c == OP_ECLASS) code += GET(code, 1);
82
1.73M
  else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE);
83
84
  /* Handle lookbehind */
85
86
1.73M
  else if (c == OP_REVERSE || c == OP_VREVERSE)
87
1.31k
    {
88
1.31k
    if (number < 0) return code;
89
1.31k
    code += PRIV(OP_lengths)[c];
90
1.31k
    }
91
92
  /* Handle capturing bracket */
93
94
1.73M
  else if (c == OP_CBRA || c == OP_SCBRA ||
95
1.43M
           c == OP_CBRAPOS || c == OP_SCBRAPOS)
96
301k
    {
97
301k
    int n = (int)GET2(code, 1+LINK_SIZE);
98
301k
    if (n == number) return code;
99
284k
    code += PRIV(OP_lengths)[c];
100
284k
    }
101
102
  /* Otherwise, we can get the item's length from the table, except that for
103
  repeated character types, we have to test for \p and \P, which have an extra
104
  two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
105
  must add in its length. */
106
107
1.43M
  else
108
1.43M
    {
109
1.43M
    switch(c)
110
1.43M
      {
111
296
      case OP_TYPESTAR:
112
1.38k
      case OP_TYPEMINSTAR:
113
4.49k
      case OP_TYPEPLUS:
114
5.51k
      case OP_TYPEMINPLUS:
115
7.29k
      case OP_TYPEQUERY:
116
7.62k
      case OP_TYPEMINQUERY:
117
7.98k
      case OP_TYPEPOSSTAR:
118
11.7k
      case OP_TYPEPOSPLUS:
119
12.0k
      case OP_TYPEPOSQUERY:
120
12.0k
      if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
121
12.0k
      break;
122
123
1.26k
      case OP_TYPEUPTO:
124
1.90k
      case OP_TYPEMINUPTO:
125
2.68k
      case OP_TYPEEXACT:
126
2.91k
      case OP_TYPEPOSUPTO:
127
2.91k
      if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
128
696
        code += 2;
129
2.91k
      break;
130
131
874
      case OP_MARK:
132
1.45k
      case OP_COMMIT_ARG:
133
1.71k
      case OP_PRUNE_ARG:
134
2.03k
      case OP_SKIP_ARG:
135
2.37k
      case OP_THEN_ARG:
136
2.37k
      code += code[1];
137
2.37k
      break;
138
1.43M
      }
139
140
    /* Add in the fixed length from the table */
141
142
1.43M
    code += PRIV(OP_lengths)[c];
143
144
  /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be
145
  followed by a multi-byte character. The length in the table is a minimum, so
146
  we have to arrange to skip the extra bytes. */
147
148
1.43M
#ifdef MAYBE_UTF_MULTI
149
1.43M
    if (utf) switch(c)
150
30.0k
      {
151
7.35k
      case OP_CHAR:
152
7.40k
      case OP_CHARI:
153
7.40k
      case OP_NOT:
154
7.40k
      case OP_NOTI:
155
7.40k
      case OP_EXACT:
156
7.40k
      case OP_EXACTI:
157
7.40k
      case OP_NOTEXACT:
158
7.40k
      case OP_NOTEXACTI:
159
7.40k
      case OP_UPTO:
160
7.40k
      case OP_UPTOI:
161
7.40k
      case OP_NOTUPTO:
162
7.40k
      case OP_NOTUPTOI:
163
7.40k
      case OP_MINUPTO:
164
7.40k
      case OP_MINUPTOI:
165
7.40k
      case OP_NOTMINUPTO:
166
7.40k
      case OP_NOTMINUPTOI:
167
7.40k
      case OP_POSUPTO:
168
7.40k
      case OP_POSUPTOI:
169
7.40k
      case OP_NOTPOSUPTO:
170
7.40k
      case OP_NOTPOSUPTOI:
171
7.40k
      case OP_STAR:
172
7.40k
      case OP_STARI:
173
7.40k
      case OP_NOTSTAR:
174
7.40k
      case OP_NOTSTARI:
175
7.40k
      case OP_MINSTAR:
176
7.40k
      case OP_MINSTARI:
177
7.40k
      case OP_NOTMINSTAR:
178
7.40k
      case OP_NOTMINSTARI:
179
7.40k
      case OP_POSSTAR:
180
7.40k
      case OP_POSSTARI:
181
7.40k
      case OP_NOTPOSSTAR:
182
7.40k
      case OP_NOTPOSSTARI:
183
7.40k
      case OP_PLUS:
184
7.40k
      case OP_PLUSI:
185
7.40k
      case OP_NOTPLUS:
186
7.40k
      case OP_NOTPLUSI:
187
7.40k
      case OP_MINPLUS:
188
7.40k
      case OP_MINPLUSI:
189
7.40k
      case OP_NOTMINPLUS:
190
7.40k
      case OP_NOTMINPLUSI:
191
7.42k
      case OP_POSPLUS:
192
7.42k
      case OP_POSPLUSI:
193
7.42k
      case OP_NOTPOSPLUS:
194
7.42k
      case OP_NOTPOSPLUSI:
195
7.43k
      case OP_QUERY:
196
7.43k
      case OP_QUERYI:
197
7.43k
      case OP_NOTQUERY:
198
7.43k
      case OP_NOTQUERYI:
199
7.43k
      case OP_MINQUERY:
200
7.43k
      case OP_MINQUERYI:
201
7.43k
      case OP_NOTMINQUERY:
202
7.43k
      case OP_NOTMINQUERYI:
203
7.43k
      case OP_POSQUERY:
204
7.43k
      case OP_POSQUERYI:
205
7.43k
      case OP_NOTPOSQUERY:
206
7.43k
      case OP_NOTPOSQUERYI:
207
7.43k
      if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
208
7.43k
      break;
209
30.0k
      }
210
#else
211
    (void)(utf);  /* Keep compiler happy by referencing function argument */
212
#endif  /* MAYBE_UTF_MULTI */
213
1.43M
    }
214
1.74M
  }
215
17.2k
}
216
217
/* End of pcre2_find_bracket.c */