util_pcre.c revision 7b4064fe3f1bec89f6285d8e4e88133a1dd90226
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/*************************************************
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * Perl-Compatible Regular Expressions *
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor *************************************************/
0a05fab9aadd37834734ffe106fc8ad4488fb3e3rbowen
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/*
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorThis is a library of functions to support regular expressions whose syntax
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorand semantics are as close as possible to those of the Perl 5 language. See
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorthe file Tech.Notes for some information on the internals.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorThis module is a wrapper that provides a POSIX API to the underlying PCRE
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorfunctions.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorWritten by: Philip Hazel <ph10@cam.ac.uk>
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor Copyright (c) 1997-2004 University of Cambridge
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor-----------------------------------------------------------------------------
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorRedistribution and use in source and binary forms, with or without
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzormodification, are permitted provided that the following conditions are met:
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * Redistributions of source code must retain the above copyright notice,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor this list of conditions and the following disclaimer.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * Redistributions in binary form must reproduce the above copyright
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor notice, this list of conditions and the following disclaimer in the
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor documentation and/or other materials provided with the distribution.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * Neither the name of the University of Cambridge nor the names of its
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor contributors may be used to endorse or promote products derived from
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor this software without specific prior written permission.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorPOSSIBILITY OF SUCH DAMAGE.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor-----------------------------------------------------------------------------
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor*/
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#include "httpd.h"
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#include "apr_strings.h"
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#include "apr_tables.h"
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#include "pcre.h"
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#define APR_WANT_STRFUNC
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#include "apr_want.h"
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis#ifndef POSIX_MALLOC_THRESHOLD
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis#define POSIX_MALLOC_THRESHOLD (10)
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis#endif
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/* Table of error strings corresponding to POSIX error codes; must be
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * kept in synch with include/ap_regex.h's AP_REG_E* definitions.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorstatic const char *const pstring[] = {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor "", /* Dummy for value 0 */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor "internal error", /* AP_REG_ASSERT */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor "failed to get memory", /* AP_REG_ESPACE */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor "bad argument", /* AP_REG_INVARG */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor "match failed" /* AP_REG_NOMATCH */
ab426ff784a35bb6e1adf54774557b5e25b4e9b8lgentis};
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
ab426ff784a35bb6e1adf54774557b5e25b4e9b8lgentisAP_DECLARE(apr_size_t) ap_regerror(int errcode, const ap_regex_t *preg,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor char *errbuf, apr_size_t errbuf_size)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor{
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor const char *message, *addmessage;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor apr_size_t length, addlength;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor message = (errcode >= (int)(sizeof(pstring) / sizeof(char *))) ?
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor "unknown error code" : pstring[errcode];
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor length = strlen(message) + 1;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor addmessage = " at offset ";
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor addlength = (preg != NULL && (int)preg->re_erroffset != -1) ?
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor strlen(addmessage) + 6 : 0;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (errbuf_size > 0) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (addlength > 0 && errbuf_size >= length + addlength)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor apr_snprintf(errbuf, errbuf_size, "%s%s%-6d", message, addmessage,
5ed11195e199bfaef4e520a412510b5ad0c158c5lgentis (int)preg->re_erroffset);
5ed11195e199bfaef4e520a412510b5ad0c158c5lgentis else
5ed11195e199bfaef4e520a412510b5ad0c158c5lgentis apr_cpystrn(errbuf, message, errbuf_size);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor }
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return length + addlength;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor}
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/*************************************************
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis * Free store held by a regex *
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor *************************************************/
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorAP_DECLARE(void) ap_regfree(ap_regex_t *preg)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor{
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor (pcre_free)(preg->re_pcre);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor}
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/*************************************************
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * Compile a regular expression *
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor *************************************************/
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/*
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis * Arguments:
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * preg points to a structure for recording the compiled expression
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * pattern the pattern to compile
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * cflags compilation flags
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor *
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * Returns: 0 on success
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * various non-zero codes on failure
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor*/
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorAP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor{
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor const char *errorptr;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor int erroffset;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor int errcode = 0;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor int options = PCRE_DUPNAMES;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if ((cflags & AP_REG_ICASE) != 0)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor options |= PCRE_CASELESS;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if ((cflags & AP_REG_NEWLINE) != 0)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor options |= PCRE_MULTILINE;
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis if ((cflags & AP_REG_DOTALL) != 0)
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis options |= PCRE_DOTALL;
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis preg->re_pcre =
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor pcre_compile2(pattern, options, &errcode, &errorptr, &erroffset, NULL);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor preg->re_erroffset = erroffset;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (preg->re_pcre == NULL) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor /*
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * There doesn't seem to be constants defined for compile time error
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * codes. 21 is "failed to get memory" according to pcreapi(3).
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (errcode == 21)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return AP_REG_ESPACE;
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis return AP_REG_INVARG;
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis }
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor PCRE_INFO_CAPTURECOUNT, &(preg->re_nsub));
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return 0;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor}
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/*************************************************
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * Match a regular expression *
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor *************************************************/
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/* Unfortunately, PCRE requires 3 ints of working space for each captured
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * substring, so we have to get and release working store instead of just using
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * the POSIX structures as was done in earlier releases when PCRE needed only 2
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * ints. However, if the number of possible capturing brackets is small, use a
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor * block of store on the stack, to reduce the use of malloc/free. The threshold
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis * is in a macro that can be changed at configure time.
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor */
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentisAP_DECLARE(int) ap_regexec(const ap_regex_t *preg, const char *string,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor apr_size_t nmatch, ap_regmatch_t *pmatch,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor int eflags)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor{
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return ap_regexec_len(preg, string, strlen(string), nmatch, pmatch,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor eflags);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor}
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzorAP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor apr_size_t len, apr_size_t nmatch,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor ap_regmatch_t *pmatch, int eflags)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor{
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis int rc;
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis int options = 0;
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis int *ovector = NULL;
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis int small_ovector[POSIX_MALLOC_THRESHOLD * 3];
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis int allocated_ovector = 0;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if ((eflags & AP_REG_NOTBOL) != 0)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor options |= PCRE_NOTBOL;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if ((eflags & AP_REG_NOTEOL) != 0)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor options |= PCRE_NOTEOL;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor ((ap_regex_t *)preg)->re_erroffset = (apr_size_t)(-1); /* Only has meaning after compile */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (nmatch > 0) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (nmatch <= POSIX_MALLOC_THRESHOLD) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor ovector = &(small_ovector[0]);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor }
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor else {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor ovector = (int *)malloc(sizeof(int) * nmatch * 3);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (ovector == NULL)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return AP_REG_ESPACE;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor allocated_ovector = 1;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor }
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis }
8202fc9176b3bca8b27ad20737863494e2f244a5lgentis
06e80fa0dffc17ae61bca1715c96e08ea90d53cblgentis rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor 0, options, ovector, nmatch * 3);
1828bbc20654649b007eec284bb0b751fed08b91lgentis
1828bbc20654649b007eec284bb0b751fed08b91lgentis if (rc == 0)
1828bbc20654649b007eec284bb0b751fed08b91lgentis rc = nmatch; /* All captured slots were filled in */
1828bbc20654649b007eec284bb0b751fed08b91lgentis
1828bbc20654649b007eec284bb0b751fed08b91lgentis if (rc >= 0) {
1828bbc20654649b007eec284bb0b751fed08b91lgentis apr_size_t i;
1828bbc20654649b007eec284bb0b751fed08b91lgentis for (i = 0; i < (apr_size_t)rc; i++) {
1828bbc20654649b007eec284bb0b751fed08b91lgentis pmatch[i].rm_so = ovector[i * 2];
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor pmatch[i].rm_eo = ovector[i * 2 + 1];
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor }
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (allocated_ovector)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor free(ovector);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor for (; i < nmatch; i++)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor pmatch[i].rm_so = pmatch[i].rm_eo = -1;
469d179ed70b8abe3730dc1519effdf68a73a343lgentis return 0;
fdd456e363b82501c228e3ca0f74750d9ca1472flgentis }
fdd456e363b82501c228e3ca0f74750d9ca1472flgentis
fdd456e363b82501c228e3ca0f74750d9ca1472flgentis else {
7ddfde8cc1587a70759084db65c83a02e51380d1lgentis if (allocated_ovector)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor free(ovector);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor switch (rc) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor case PCRE_ERROR_NOMATCH:
469d179ed70b8abe3730dc1519effdf68a73a343lgentis return AP_REG_NOMATCH;
5ed11195e199bfaef4e520a412510b5ad0c158c5lgentis case PCRE_ERROR_NULL:
9aa7bfa70153d0811c3004202d9cfeda41c6fe66lgentis return AP_REG_INVARG;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor case PCRE_ERROR_BADOPTION:
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return AP_REG_INVARG;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor case PCRE_ERROR_BADMAGIC:
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return AP_REG_INVARG;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor case PCRE_ERROR_UNKNOWN_NODE:
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return AP_REG_ASSERT;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor case PCRE_ERROR_NOMEMORY:
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return AP_REG_ESPACE;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#ifdef PCRE_ERROR_MATCHLIMIT
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor case PCRE_ERROR_MATCHLIMIT:
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return AP_REG_ESPACE;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#endif
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#ifdef PCRE_ERROR_BADUTF8
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor case PCRE_ERROR_BADUTF8:
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return AP_REG_INVARG;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#endif
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#ifdef PCRE_ERROR_BADUTF8_OFFSET
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor case PCRE_ERROR_BADUTF8_OFFSET:
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return AP_REG_INVARG;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor#endif
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor default:
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return AP_REG_ASSERT;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor }
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor }
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor}
fed05bd9cff037691a12077d6d9d83f9892e70a5lgentis
b2d402bf3e0826117941602dd3c1c5b41a7ed630lgentisAP_DECLARE(int) ap_regname(const ap_regex_t *preg,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor apr_array_header_t *names, const char *prefix,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor int upper)
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor{
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor int namecount;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor int nameentrysize;
fed05bd9cff037691a12077d6d9d83f9892e70a5lgentis int i;
fed05bd9cff037691a12077d6d9d83f9892e70a5lgentis char *nametable;
b2d402bf3e0826117941602dd3c1c5b41a7ed630lgentis
b2d402bf3e0826117941602dd3c1c5b41a7ed630lgentis pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
b2d402bf3e0826117941602dd3c1c5b41a7ed630lgentis PCRE_INFO_NAMECOUNT, &namecount);
b2d402bf3e0826117941602dd3c1c5b41a7ed630lgentis pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor PCRE_INFO_NAMETABLE, &nametable);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor for (i = 0; i < namecount; i++) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor const char *offset = nametable + i * nameentrysize;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor int capture = ((offset[0] << 8) + offset[1]);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor while (names->nelts <= capture) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor apr_array_push(names);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor }
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (upper || prefix) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor char *name = ((char **) names->elts)[capture] =
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor prefix ? apr_pstrcat(names->pool, prefix, offset + 2,
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor NULL) :
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor apr_pstrdup(names->pool, offset + 2);
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor if (upper) {
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor ap_str_toupper(name);
9a2c99c15b21987ac37de808c8ff49f2d02a9c9flgentis }
9a2c99c15b21987ac37de808c8ff49f2d02a9c9flgentis }
9aa7bfa70153d0811c3004202d9cfeda41c6fe66lgentis else {
9aa7bfa70153d0811c3004202d9cfeda41c6fe66lgentis ((const char **)names->elts)[capture] = offset + 2;
9a2c99c15b21987ac37de808c8ff49f2d02a9c9flgentis }
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor }
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor return namecount;
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor}
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor/* End of pcreposix.c */
cc8190433d13f5e9de618c5d7f10c824c0c1919cgryzor