aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/enum.c87
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;