diff options
-rw-r--r-- | main/enum.c | 87 |
1 files changed, 53 insertions, 34 deletions
diff --git a/main/enum.c b/main/enum.c index 3fa0bb977..b7330410a 100644 --- a/main/enum.c +++ b/main/enum.c @@ -125,15 +125,18 @@ static int parse_naptr(char *dst, int dstsize, char *tech, int techsize, unsigne char *p; char regexp[512] = ""; char repl[512] = ""; - char temp[512] = ""; + char tempdst[512] = ""; + char errbuff[512] = ""; char delim; char *delim2; char *pattern, *subst, *d; int res; - int regexp_len, size, backref; - int d_len = sizeof(temp) - 1; + int regexp_len, rc; + int size, matchindex; /* size is the size of the backreference sub. */ + int d_len = sizeof(tempdst) - 1; + static const int max_bt = 10; /* max num of regexp backreference allowed, must remain 10 to guarantee a valid backreference index */ regex_t preg; - regmatch_t pmatch[9]; + regmatch_t pmatch[max_bt]; tech_return[0] = '\0'; @@ -204,65 +207,83 @@ static int parse_naptr(char *dst, int dstsize, char *tech, int techsize, unsigne } } - /* DEDBUGGING STUB - ast_copy_string(regexp, "!^\\+43(.*)$!\\1@bla.fasel!", sizeof(regexp) - 1); - */ - regexp_len = strlen(regexp); if (regexp_len < 7) { ast_log(LOG_WARNING, "Regex too short to be meaningful.\n"); return -1; } - + /* this takes the first character of the regexp (which is a delimiter) + * and uses that character to find the index of the second delimiter */ delim = regexp[0]; delim2 = strchr(regexp + 1, delim); - if ((delim2 == NULL) || (regexp[regexp_len-1] != delim)) { - ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n",regexp); + if ((delim2 == NULL) || (regexp[regexp_len - 1] != delim)) { /* is the second delimiter found, and is the end of the regexp a delimiter */ + ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n", regexp); + return -1; + } else if (strchr((delim2 + 1), delim) == NULL) { /* if the second delimiter is found, make sure there is a third instance. this could be the end one instead of the middle */ + ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n", regexp); return -1; } - - pattern = regexp + 1; - *delim2 = 0; - subst = delim2 + 1; - regexp[regexp_len-1] = 0; + pattern = regexp + 1; /* pattern is the regex without the begining and ending delimiter */ + *delim2 = 0; /* zero out the middle delimiter */ + subst = delim2 + 1; /* dst substring is everything after the second delimiter. */ + regexp[regexp_len - 1] = 0; /* zero out the last delimiter */ /* * now do the regex wizardry. */ if (regcomp(&preg, pattern, REG_EXTENDED | REG_NEWLINE)) { - ast_log(LOG_WARNING, "NAPTR Regex compilation error (regex = \"%s\").\n",regexp); + ast_log(LOG_WARNING, "NAPTR Regex compilation error (regex = \"%s\").\n", regexp); return -1; } - if (preg.re_nsub > 9) { + if (preg.re_nsub > ARRAY_LEN(pmatch)) { ast_log(LOG_WARNING, "NAPTR Regex compilation error: too many subs.\n"); regfree(&preg); return -1; } - - if (regexec(&preg, naptrinput, 9, pmatch, 0)) { - ast_log(LOG_WARNING, "NAPTR Regex match failed.\n"); + /* pmatch is an array containing the substring indexes for the regex backreference sub. + * max_bt is the maximum number of backreferences allowed to be stored in pmatch */ + if ((rc = regexec(&preg, (char *) naptrinput, max_bt, pmatch, 0))) { + regerror(rc, &preg, errbuff, sizeof(errbuff)); + ast_log(LOG_WARNING, "NAPTR Regex match failed. Reason: %s\n", errbuff); regfree(&preg); return -1; } regfree(&preg); - d = temp; + d = tempdst; d_len--; + + /* perform the backreference sub. Search the subst for backreferences, + * when a backreference is found, retrieve the backreferences number. + * use the backreference number as an index for pmatch to retrieve the + * beginning and ending indexes of the substring to insert as the backreference. + * if no backreference is found, continue copying the subst into tempdst */ while (*subst && (d_len > 0)) { - if ((subst[0] == '\\') && isdigit(subst[1]) && (pmatch[subst[1]-'0'].rm_so != -1)) { - backref = subst[1]-'0'; - size = pmatch[backref].rm_eo - pmatch[backref].rm_so; + if ((subst[0] == '\\') && isdigit(subst[1])) { /* is this character the beginning of a backreference */ + matchindex = (int) (subst[1] - '0'); + if (matchindex >= ARRAY_LEN(pmatch)) { + ast_log(LOG_WARNING, "Error during regex substitution. Invalid pmatch index.\n"); + return -1; + } + /* pmatch len is 10. we are garanteed a single char 0-9 is a valid index */ + size = pmatch[matchindex].rm_eo - pmatch[matchindex].rm_so; if (size > d_len) { ast_log(LOG_WARNING, "Not enough space during NAPTR regex substitution.\n"); return -1; - } - memcpy(d, naptrinput + pmatch[backref].rm_so, size); - d += size; - d_len -= size; - subst += 2; + } + /* are the pmatch indexes valid for the input length */ + if ((strlen((char *) naptrinput) >= pmatch[matchindex].rm_eo) && (pmatch[matchindex].rm_so <= pmatch[matchindex].rm_eo)) { + memcpy(d, (naptrinput + (int) pmatch[matchindex].rm_so), size); /* copy input substring into backreference marker */ + d_len -= size; + subst += 2; /* skip over backreference characters to next valid character */ + d += size; + } else { + ast_log(LOG_WARNING, "Error during regex substitution. Invalid backreference index.\n"); + return -1; + } } else if (isprint(*subst)) { *d++ = *subst++; d_len--; @@ -272,9 +293,8 @@ static int parse_naptr(char *dst, int dstsize, char *tech, int techsize, unsigne } } *d = 0; - ast_copy_string(dst, temp, dstsize); + ast_copy_string((char *) dst, tempdst, dstsize); dst[dstsize - 1] = '\0'; - if (*tech != '\0'){ /* check if it is requested NAPTR */ if (!strncasecmp(tech, "ALL", techsize)){ return 1; /* return or count any RR */ @@ -289,7 +309,6 @@ static int parse_naptr(char *dst, int dstsize, char *tech, int techsize, unsigne /* tech was not specified, return first parsed RR */ ast_copy_string(tech, tech_return, techsize); - return 1; } @@ -412,7 +431,7 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds context.tech = tech; context.techlen = techlen; context.options = 0; - context.position = record; + context.position = record > 0 ? record : 1; context.naptr_rrs = NULL; context.naptr_rrs_count = 0; |