xref: /PHP-7.2/ext/pcre/pcrelib/pcre_get.c (revision 8a287c0e)
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            Copyright (c) 1997-2012 University of Cambridge
10 
11 -----------------------------------------------------------------------------
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14 
15     * Redistributions of source code must retain the above copyright notice,
16       this list of conditions and the following disclaimer.
17 
18     * Redistributions in binary form must reproduce the above copyright
19       notice, this list of conditions and the following disclaimer in the
20       documentation and/or other materials provided with the distribution.
21 
22     * Neither the name of the University of Cambridge nor the names of its
23       contributors may be used to endorse or promote products derived from
24       this software without specific prior written permission.
25 
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 POSSIBILITY OF SUCH DAMAGE.
37 -----------------------------------------------------------------------------
38 */
39 
40 
41 /* This module contains some convenience functions for extracting substrings
42 from the subject string after a regex match has succeeded. The original idea
43 for these functions came from Scott Wimer. */
44 
45 
46 #ifdef HAVE_CONFIG_H
47 #include "config.h"
48 #endif
49 
50 #include "pcre_internal.h"
51 
52 
53 /*************************************************
54 *           Find number for named string         *
55 *************************************************/
56 
57 /* This function is used by the get_first_set() function below, as well
58 as being generally available. It assumes that names are unique.
59 
60 Arguments:
61   code        the compiled regex
62   stringname  the name whose number is required
63 
64 Returns:      the number of the named parentheses, or a negative number
65                 (PCRE_ERROR_NOSUBSTRING) if not found
66 */
67 
68 #if defined COMPILE_PCRE8
69 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_stringnumber(const pcre * code,const char * stringname)70 pcre_get_stringnumber(const pcre *code, const char *stringname)
71 #elif defined COMPILE_PCRE16
72 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
73 pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname)
74 #elif defined COMPILE_PCRE32
75 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
76 pcre32_get_stringnumber(const pcre32 *code, PCRE_SPTR32 stringname)
77 #endif
78 {
79 int rc;
80 int entrysize;
81 int top, bot;
82 pcre_uchar *nametable;
83 
84 #ifdef COMPILE_PCRE8
85 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
86   return rc;
87 if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
88 
89 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
90   return rc;
91 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
92   return rc;
93 #endif
94 #ifdef COMPILE_PCRE16
95 if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
96   return rc;
97 if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
98 
99 if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
100   return rc;
101 if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
102   return rc;
103 #endif
104 #ifdef COMPILE_PCRE32
105 if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
106   return rc;
107 if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
108 
109 if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
110   return rc;
111 if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
112   return rc;
113 #endif
114 
115 bot = 0;
116 while (top > bot)
117   {
118   int mid = (top + bot) / 2;
119   pcre_uchar *entry = nametable + entrysize*mid;
120   int c = STRCMP_UC_UC((pcre_uchar *)stringname,
121     (pcre_uchar *)(entry + IMM2_SIZE));
122   if (c == 0) return GET2(entry, 0);
123   if (c > 0) bot = mid + 1; else top = mid;
124   }
125 
126 return PCRE_ERROR_NOSUBSTRING;
127 }
128 
129 
130 
131 /*************************************************
132 *     Find (multiple) entries for named string   *
133 *************************************************/
134 
135 /* This is used by the get_first_set() function below, as well as being
136 generally available. It is used when duplicated names are permitted.
137 
138 Arguments:
139   code        the compiled regex
140   stringname  the name whose entries required
141   firstptr    where to put the pointer to the first entry
142   lastptr     where to put the pointer to the last entry
143 
144 Returns:      the length of each entry, or a negative number
145                 (PCRE_ERROR_NOSUBSTRING) if not found
146 */
147 
148 #if defined COMPILE_PCRE8
149 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_stringtable_entries(const pcre * code,const char * stringname,char ** firstptr,char ** lastptr)150 pcre_get_stringtable_entries(const pcre *code, const char *stringname,
151   char **firstptr, char **lastptr)
152 #elif defined COMPILE_PCRE16
153 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
154 pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname,
155   PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr)
156 #elif defined COMPILE_PCRE32
157 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
158 pcre32_get_stringtable_entries(const pcre32 *code, PCRE_SPTR32 stringname,
159   PCRE_UCHAR32 **firstptr, PCRE_UCHAR32 **lastptr)
160 #endif
161 {
162 int rc;
163 int entrysize;
164 int top, bot;
165 pcre_uchar *nametable, *lastentry;
166 
167 #ifdef COMPILE_PCRE8
168 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
169   return rc;
170 if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
171 
172 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
173   return rc;
174 if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
175   return rc;
176 #endif
177 #ifdef COMPILE_PCRE16
178 if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
179   return rc;
180 if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
181 
182 if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
183   return rc;
184 if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
185   return rc;
186 #endif
187 #ifdef COMPILE_PCRE32
188 if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
189   return rc;
190 if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
191 
192 if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
193   return rc;
194 if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
195   return rc;
196 #endif
197 
198 lastentry = nametable + entrysize * (top - 1);
199 bot = 0;
200 while (top > bot)
201   {
202   int mid = (top + bot) / 2;
203   pcre_uchar *entry = nametable + entrysize*mid;
204   int c = STRCMP_UC_UC((pcre_uchar *)stringname,
205     (pcre_uchar *)(entry + IMM2_SIZE));
206   if (c == 0)
207     {
208     pcre_uchar *first = entry;
209     pcre_uchar *last = entry;
210     while (first > nametable)
211       {
212       if (STRCMP_UC_UC((pcre_uchar *)stringname,
213         (pcre_uchar *)(first - entrysize + IMM2_SIZE)) != 0) break;
214       first -= entrysize;
215       }
216     while (last < lastentry)
217       {
218       if (STRCMP_UC_UC((pcre_uchar *)stringname,
219         (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break;
220       last += entrysize;
221       }
222 #if defined COMPILE_PCRE8
223     *firstptr = (char *)first;
224     *lastptr = (char *)last;
225 #elif defined COMPILE_PCRE16
226     *firstptr = (PCRE_UCHAR16 *)first;
227     *lastptr = (PCRE_UCHAR16 *)last;
228 #elif defined COMPILE_PCRE32
229     *firstptr = (PCRE_UCHAR32 *)first;
230     *lastptr = (PCRE_UCHAR32 *)last;
231 #endif
232     return entrysize;
233     }
234   if (c > 0) bot = mid + 1; else top = mid;
235   }
236 
237 return PCRE_ERROR_NOSUBSTRING;
238 }
239 
240 
241 
242 /*************************************************
243 *    Find first set of multiple named strings    *
244 *************************************************/
245 
246 /* This function allows for duplicate names in the table of named substrings.
247 It returns the number of the first one that was set in a pattern match.
248 
249 Arguments:
250   code         the compiled regex
251   stringname   the name of the capturing substring
252   ovector      the vector of matched substrings
253   stringcount  number of captured substrings
254 
255 Returns:       the number of the first that is set,
256                or the number of the last one if none are set,
257                or a negative number on error
258 */
259 
260 #if defined COMPILE_PCRE8
261 static int
get_first_set(const pcre * code,const char * stringname,int * ovector,int stringcount)262 get_first_set(const pcre *code, const char *stringname, int *ovector,
263   int stringcount)
264 #elif defined COMPILE_PCRE16
265 static int
266 get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector,
267   int stringcount)
268 #elif defined COMPILE_PCRE32
269 static int
270 get_first_set(const pcre32 *code, PCRE_SPTR32 stringname, int *ovector,
271   int stringcount)
272 #endif
273 {
274 const REAL_PCRE *re = (const REAL_PCRE *)code;
275 int entrysize;
276 pcre_uchar *entry;
277 #if defined COMPILE_PCRE8
278 char *first, *last;
279 #elif defined COMPILE_PCRE16
280 PCRE_UCHAR16 *first, *last;
281 #elif defined COMPILE_PCRE32
282 PCRE_UCHAR32 *first, *last;
283 #endif
284 
285 #if defined COMPILE_PCRE8
286 if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
287   return pcre_get_stringnumber(code, stringname);
288 entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
289 #elif defined COMPILE_PCRE16
290 if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
291   return pcre16_get_stringnumber(code, stringname);
292 entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last);
293 #elif defined COMPILE_PCRE32
294 if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
295   return pcre32_get_stringnumber(code, stringname);
296 entrysize = pcre32_get_stringtable_entries(code, stringname, &first, &last);
297 #endif
298 if (entrysize <= 0) return entrysize;
299 for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize)
300   {
301   int n = GET2(entry, 0);
302   if (n < stringcount && ovector[n*2] >= 0) return n;
303   }
304 return GET2(entry, 0);
305 }
306 
307 
308 
309 
310 /*************************************************
311 *      Copy captured string to given buffer      *
312 *************************************************/
313 
314 /* This function copies a single captured substring into a given buffer.
315 Note that we use memcpy() rather than strncpy() in case there are binary zeros
316 in the string.
317 
318 Arguments:
319   subject        the subject string that was matched
320   ovector        pointer to the offsets table
321   stringcount    the number of substrings that were captured
322                    (i.e. the yield of the pcre_exec call, unless
323                    that was zero, in which case it should be 1/3
324                    of the offset table size)
325   stringnumber   the number of the required substring
326   buffer         where to put the substring
327   size           the size of the buffer
328 
329 Returns:         if successful:
330                    the length of the copied string, not including the zero
331                    that is put on the end; can be zero
332                  if not successful:
333                    PCRE_ERROR_NOMEMORY (-6) buffer too small
334                    PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
335 */
336 
337 #if defined COMPILE_PCRE8
338 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_copy_substring(const char * subject,int * ovector,int stringcount,int stringnumber,char * buffer,int size)339 pcre_copy_substring(const char *subject, int *ovector, int stringcount,
340   int stringnumber, char *buffer, int size)
341 #elif defined COMPILE_PCRE16
342 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
343 pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
344   int stringnumber, PCRE_UCHAR16 *buffer, int size)
345 #elif defined COMPILE_PCRE32
346 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
347 pcre32_copy_substring(PCRE_SPTR32 subject, int *ovector, int stringcount,
348   int stringnumber, PCRE_UCHAR32 *buffer, int size)
349 #endif
350 {
351 int yield;
352 if (stringnumber < 0 || stringnumber >= stringcount)
353   return PCRE_ERROR_NOSUBSTRING;
354 stringnumber *= 2;
355 yield = ovector[stringnumber+1] - ovector[stringnumber];
356 if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
357 memcpy(buffer, subject + ovector[stringnumber], IN_UCHARS(yield));
358 buffer[yield] = 0;
359 return yield;
360 }
361 
362 
363 
364 /*************************************************
365 *   Copy named captured string to given buffer   *
366 *************************************************/
367 
368 /* This function copies a single captured substring into a given buffer,
369 identifying it by name. If the regex permits duplicate names, the first
370 substring that is set is chosen.
371 
372 Arguments:
373   code           the compiled regex
374   subject        the subject string that was matched
375   ovector        pointer to the offsets table
376   stringcount    the number of substrings that were captured
377                    (i.e. the yield of the pcre_exec call, unless
378                    that was zero, in which case it should be 1/3
379                    of the offset table size)
380   stringname     the name of the required substring
381   buffer         where to put the substring
382   size           the size of the buffer
383 
384 Returns:         if successful:
385                    the length of the copied string, not including the zero
386                    that is put on the end; can be zero
387                  if not successful:
388                    PCRE_ERROR_NOMEMORY (-6) buffer too small
389                    PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
390 */
391 
392 #if defined COMPILE_PCRE8
393 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_copy_named_substring(const pcre * code,const char * subject,int * ovector,int stringcount,const char * stringname,char * buffer,int size)394 pcre_copy_named_substring(const pcre *code, const char *subject,
395   int *ovector, int stringcount, const char *stringname,
396   char *buffer, int size)
397 #elif defined COMPILE_PCRE16
398 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
399 pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
400   int *ovector, int stringcount, PCRE_SPTR16 stringname,
401   PCRE_UCHAR16 *buffer, int size)
402 #elif defined COMPILE_PCRE32
403 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
404 pcre32_copy_named_substring(const pcre32 *code, PCRE_SPTR32 subject,
405   int *ovector, int stringcount, PCRE_SPTR32 stringname,
406   PCRE_UCHAR32 *buffer, int size)
407 #endif
408 {
409 int n = get_first_set(code, stringname, ovector, stringcount);
410 if (n <= 0) return n;
411 #if defined COMPILE_PCRE8
412 return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
413 #elif defined COMPILE_PCRE16
414 return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size);
415 #elif defined COMPILE_PCRE32
416 return pcre32_copy_substring(subject, ovector, stringcount, n, buffer, size);
417 #endif
418 }
419 
420 
421 
422 /*************************************************
423 *      Copy all captured strings to new store    *
424 *************************************************/
425 
426 /* This function gets one chunk of store and builds a list of pointers and all
427 of the captured substrings in it. A NULL pointer is put on the end of the list.
428 
429 Arguments:
430   subject        the subject string that was matched
431   ovector        pointer to the offsets table
432   stringcount    the number of substrings that were captured
433                    (i.e. the yield of the pcre_exec call, unless
434                    that was zero, in which case it should be 1/3
435                    of the offset table size)
436   listptr        set to point to the list of pointers
437 
438 Returns:         if successful: 0
439                  if not successful:
440                    PCRE_ERROR_NOMEMORY (-6) failed to get store
441 */
442 
443 #if defined COMPILE_PCRE8
444 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_substring_list(const char * subject,int * ovector,int stringcount,const char *** listptr)445 pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
446   const char ***listptr)
447 #elif defined COMPILE_PCRE16
448 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
449 pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount,
450   PCRE_SPTR16 **listptr)
451 #elif defined COMPILE_PCRE32
452 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
453 pcre32_get_substring_list(PCRE_SPTR32 subject, int *ovector, int stringcount,
454   PCRE_SPTR32 **listptr)
455 #endif
456 {
457 int i;
458 int size = sizeof(pcre_uchar *);
459 int double_count = stringcount * 2;
460 pcre_uchar **stringlist;
461 pcre_uchar *p;
462 
463 for (i = 0; i < double_count; i += 2)
464   {
465   size += sizeof(pcre_uchar *) + IN_UCHARS(1);
466   if (ovector[i+1] > ovector[i]) size += IN_UCHARS(ovector[i+1] - ovector[i]);
467   }
468 
469 stringlist = (pcre_uchar **)(PUBL(malloc))(size);
470 if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
471 
472 #if defined COMPILE_PCRE8
473 *listptr = (const char **)stringlist;
474 #elif defined COMPILE_PCRE16
475 *listptr = (PCRE_SPTR16 *)stringlist;
476 #elif defined COMPILE_PCRE32
477 *listptr = (PCRE_SPTR32 *)stringlist;
478 #endif
479 p = (pcre_uchar *)(stringlist + stringcount + 1);
480 
481 for (i = 0; i < double_count; i += 2)
482   {
483   int len = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0;
484   memcpy(p, subject + ovector[i], IN_UCHARS(len));
485   *stringlist++ = p;
486   p += len;
487   *p++ = 0;
488   }
489 
490 *stringlist = NULL;
491 return 0;
492 }
493 
494 
495 
496 /*************************************************
497 *   Free store obtained by get_substring_list    *
498 *************************************************/
499 
500 /* This function exists for the benefit of people calling PCRE from non-C
501 programs that can call its functions, but not free() or (PUBL(free))()
502 directly.
503 
504 Argument:   the result of a previous pcre_get_substring_list()
505 Returns:    nothing
506 */
507 
508 #if defined COMPILE_PCRE8
509 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
pcre_free_substring_list(const char ** pointer)510 pcre_free_substring_list(const char **pointer)
511 #elif defined COMPILE_PCRE16
512 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
513 pcre16_free_substring_list(PCRE_SPTR16 *pointer)
514 #elif defined COMPILE_PCRE32
515 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
516 pcre32_free_substring_list(PCRE_SPTR32 *pointer)
517 #endif
518 {
519 (PUBL(free))((void *)pointer);
520 }
521 
522 
523 
524 /*************************************************
525 *      Copy captured string to new store         *
526 *************************************************/
527 
528 /* This function copies a single captured substring into a piece of new
529 store
530 
531 Arguments:
532   subject        the subject string that was matched
533   ovector        pointer to the offsets table
534   stringcount    the number of substrings that were captured
535                    (i.e. the yield of the pcre_exec call, unless
536                    that was zero, in which case it should be 1/3
537                    of the offset table size)
538   stringnumber   the number of the required substring
539   stringptr      where to put a pointer to the substring
540 
541 Returns:         if successful:
542                    the length of the string, not including the zero that
543                    is put on the end; can be zero
544                  if not successful:
545                    PCRE_ERROR_NOMEMORY (-6) failed to get store
546                    PCRE_ERROR_NOSUBSTRING (-7) substring not present
547 */
548 
549 #if defined COMPILE_PCRE8
550 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_substring(const char * subject,int * ovector,int stringcount,int stringnumber,const char ** stringptr)551 pcre_get_substring(const char *subject, int *ovector, int stringcount,
552   int stringnumber, const char **stringptr)
553 #elif defined COMPILE_PCRE16
554 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
555 pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
556   int stringnumber, PCRE_SPTR16 *stringptr)
557 #elif defined COMPILE_PCRE32
558 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
559 pcre32_get_substring(PCRE_SPTR32 subject, int *ovector, int stringcount,
560   int stringnumber, PCRE_SPTR32 *stringptr)
561 #endif
562 {
563 int yield;
564 pcre_uchar *substring;
565 if (stringnumber < 0 || stringnumber >= stringcount)
566   return PCRE_ERROR_NOSUBSTRING;
567 stringnumber *= 2;
568 yield = ovector[stringnumber+1] - ovector[stringnumber];
569 substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1));
570 if (substring == NULL) return PCRE_ERROR_NOMEMORY;
571 memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield));
572 substring[yield] = 0;
573 #if defined COMPILE_PCRE8
574 *stringptr = (const char *)substring;
575 #elif defined COMPILE_PCRE16
576 *stringptr = (PCRE_SPTR16)substring;
577 #elif defined COMPILE_PCRE32
578 *stringptr = (PCRE_SPTR32)substring;
579 #endif
580 return yield;
581 }
582 
583 
584 
585 /*************************************************
586 *   Copy named captured string to new store      *
587 *************************************************/
588 
589 /* This function copies a single captured substring, identified by name, into
590 new store. If the regex permits duplicate names, the first substring that is
591 set is chosen.
592 
593 Arguments:
594   code           the compiled regex
595   subject        the subject string that was matched
596   ovector        pointer to the offsets table
597   stringcount    the number of substrings that were captured
598                    (i.e. the yield of the pcre_exec call, unless
599                    that was zero, in which case it should be 1/3
600                    of the offset table size)
601   stringname     the name of the required substring
602   stringptr      where to put the pointer
603 
604 Returns:         if successful:
605                    the length of the copied string, not including the zero
606                    that is put on the end; can be zero
607                  if not successful:
608                    PCRE_ERROR_NOMEMORY (-6) couldn't get memory
609                    PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
610 */
611 
612 #if defined COMPILE_PCRE8
613 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_named_substring(const pcre * code,const char * subject,int * ovector,int stringcount,const char * stringname,const char ** stringptr)614 pcre_get_named_substring(const pcre *code, const char *subject,
615   int *ovector, int stringcount, const char *stringname,
616   const char **stringptr)
617 #elif defined COMPILE_PCRE16
618 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
619 pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
620   int *ovector, int stringcount, PCRE_SPTR16 stringname,
621   PCRE_SPTR16 *stringptr)
622 #elif defined COMPILE_PCRE32
623 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
624 pcre32_get_named_substring(const pcre32 *code, PCRE_SPTR32 subject,
625   int *ovector, int stringcount, PCRE_SPTR32 stringname,
626   PCRE_SPTR32 *stringptr)
627 #endif
628 {
629 int n = get_first_set(code, stringname, ovector, stringcount);
630 if (n <= 0) return n;
631 #if defined COMPILE_PCRE8
632 return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
633 #elif defined COMPILE_PCRE16
634 return pcre16_get_substring(subject, ovector, stringcount, n, stringptr);
635 #elif defined COMPILE_PCRE32
636 return pcre32_get_substring(subject, ovector, stringcount, n, stringptr);
637 #endif
638 }
639 
640 
641 
642 
643 /*************************************************
644 *       Free store obtained by get_substring     *
645 *************************************************/
646 
647 /* This function exists for the benefit of people calling PCRE from non-C
648 programs that can call its functions, but not free() or (PUBL(free))()
649 directly.
650 
651 Argument:   the result of a previous pcre_get_substring()
652 Returns:    nothing
653 */
654 
655 #if defined COMPILE_PCRE8
656 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
pcre_free_substring(const char * pointer)657 pcre_free_substring(const char *pointer)
658 #elif defined COMPILE_PCRE16
659 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
660 pcre16_free_substring(PCRE_SPTR16 pointer)
661 #elif defined COMPILE_PCRE32
662 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
663 pcre32_free_substring(PCRE_SPTR32 pointer)
664 #endif
665 {
666 (PUBL(free))((void *)pointer);
667 }
668 
669 /* End of pcre_get.c */
670