mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-25 07:01:09 +00:00
Merged revisions 180532 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r180532 | dvossel | 2009-03-06 11:19:55 -0600 (Fri, 06 Mar 2009) | 9 lines Fix handling of backreferences for ENUM lookups enum.c did not handle regex backtraces correctly. The '\1' in the regex is a backreference that requires a pattern match to be inserted. The way the code used to work is that it would find the backreference and insert the entire input string minus the '+'. This is incorrect. The regexec() function takes in a variable called pmatch which is an array of structs containing the start and end indexes for each backreference substring. The original code actually passed the pmatch array pointer into regexec but never did anything with it. Now when a backtrace is found, the backtrace number is looked up in the pmatch array and the correct substring is inserted. (closes issue #14576) Reported by: chris-mac Review: http://reviewboard.digium.com/r/187/ ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@180534 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
75
main/enum.c
75
main/enum.c
@@ -393,17 +393,18 @@ static int parse_naptr(unsigned char *dst, int dstsize, char *tech, int techsize
|
|||||||
char *p;
|
char *p;
|
||||||
char regexp[512] = "";
|
char regexp[512] = "";
|
||||||
char repl[512] = "";
|
char repl[512] = "";
|
||||||
char temp[512] = "";
|
char tempdst[512] = "";
|
||||||
char errbuff[512] = "";
|
char errbuff[512] = "";
|
||||||
char delim;
|
char delim;
|
||||||
char *delim2;
|
char *delim2;
|
||||||
char *pattern, *subst, *d, *number;
|
char *pattern, *subst, *d;
|
||||||
int res;
|
int res;
|
||||||
int regexp_len, rc;
|
int regexp_len, rc;
|
||||||
int size;
|
static const int max_bt = 10; /* max num of regexp backreference allowed, must remain 10 to guarantee a valid backreference index */
|
||||||
int d_len = sizeof(temp) - 1;
|
int size, matchindex; /* size is the size of the backreference sub. */
|
||||||
|
size_t d_len = sizeof(tempdst) - 1;
|
||||||
regex_t preg;
|
regex_t preg;
|
||||||
regmatch_t pmatch[9];
|
regmatch_t pmatch[max_bt];
|
||||||
|
|
||||||
tech_return[0] = '\0';
|
tech_return[0] = '\0';
|
||||||
dst[0] = '\0';
|
dst[0] = '\0';
|
||||||
@@ -474,28 +475,27 @@ static int parse_naptr(unsigned char *dst, int dstsize, char *tech, int techsize
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DEDBUGGING STUB
|
|
||||||
ast_copy_string(regexp, "!^\\+43(.*)$!\\1@bla.fasel!", sizeof(regexp) - 1);
|
|
||||||
*/
|
|
||||||
|
|
||||||
regexp_len = strlen(regexp);
|
regexp_len = strlen(regexp);
|
||||||
if (regexp_len < 7) {
|
if (regexp_len < 7) {
|
||||||
ast_log(LOG_WARNING, "Regex too short to be meaningful.\n");
|
ast_log(LOG_WARNING, "Regex too short to be meaningful.\n");
|
||||||
return -1;
|
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];
|
delim = regexp[0];
|
||||||
delim2 = strchr(regexp + 1, delim);
|
delim2 = strchr(regexp + 1, delim);
|
||||||
if ((delim2 == NULL) || (regexp[regexp_len - 1] != delim)) {
|
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);
|
ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n", regexp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
pattern = regexp + 1; /* pattern is the regex without the begining and ending delimiter */
|
||||||
pattern = regexp + 1;
|
*delim2 = 0; /* zero out the middle delimiter */
|
||||||
*delim2 = 0;
|
subst = delim2 + 1; /* dst substring is everything after the second delimiter. */
|
||||||
subst = delim2 + 1;
|
regexp[regexp_len - 1] = 0; /* zero out the last delimiter */
|
||||||
regexp[regexp_len - 1] = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now do the regex wizardry.
|
* now do the regex wizardry.
|
||||||
@@ -506,13 +506,14 @@ static int parse_naptr(unsigned char *dst, int dstsize, char *tech, int techsize
|
|||||||
return -1;
|
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");
|
ast_log(LOG_WARNING, "NAPTR Regex compilation error: too many subs.\n");
|
||||||
regfree(&preg);
|
regfree(&preg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/* pmatch is an array containing the substring indexes for the regex backreference sub.
|
||||||
if (0 != (rc = regexec(&preg, (char *)naptrinput, 0, pmatch, 0))) {
|
* 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));
|
regerror(rc, &preg, errbuff, sizeof(errbuff));
|
||||||
ast_log(LOG_WARNING, "NAPTR Regex match failed. Reason: %s\n", errbuff);
|
ast_log(LOG_WARNING, "NAPTR Regex match failed. Reason: %s\n", errbuff);
|
||||||
regfree(&preg);
|
regfree(&preg);
|
||||||
@@ -520,24 +521,37 @@ static int parse_naptr(unsigned char *dst, int dstsize, char *tech, int techsize
|
|||||||
}
|
}
|
||||||
regfree(&preg);
|
regfree(&preg);
|
||||||
|
|
||||||
d = temp;
|
d = tempdst;
|
||||||
|
|
||||||
number = (char *)(naptrinput + (*naptrinput == '+'));
|
|
||||||
|
|
||||||
d_len--;
|
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)) {
|
while (*subst && (d_len > 0)) {
|
||||||
if ((subst[0] == '\\' && isdigit(subst[1]))) {
|
if ((subst[0] == '\\') && isdigit(subst[1])) { /* is this character the beginning of a backreference */
|
||||||
size = strlen(number);
|
matchindex = (int) (subst[1] - '0');
|
||||||
//ast_log(LOG_WARNING, "size:%d: offset:%s: temp:%s:\n",size,offset,temp);
|
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) {
|
if (size > d_len) {
|
||||||
ast_log(LOG_WARNING, "Not enough space during NAPTR regex substitution.\n");
|
ast_log(LOG_WARNING, "Not enough space during NAPTR regex substitution.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(d, number, size);
|
/* 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;
|
d_len -= size;
|
||||||
subst += 2;
|
subst += 2; /* skip over backreference characters to next valid character */
|
||||||
d += size;
|
d += size;
|
||||||
//ast_log(LOG_WARNING, "after dlen:%d: temp:%s:\n",d_len,temp);
|
} else {
|
||||||
|
ast_log(LOG_WARNING, "Error during regex substitution. Invalid backreference index.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else if (isprint(*subst)) {
|
} else if (isprint(*subst)) {
|
||||||
*d++ = *subst++;
|
*d++ = *subst++;
|
||||||
d_len--;
|
d_len--;
|
||||||
@@ -547,9 +561,8 @@ static int parse_naptr(unsigned char *dst, int dstsize, char *tech, int techsize
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*d = 0;
|
*d = 0;
|
||||||
ast_copy_string((char *)dst, temp,dstsize);
|
ast_copy_string((char *) dst, tempdst, dstsize);
|
||||||
dst[dstsize - 1] = '\0';
|
dst[dstsize - 1] = '\0';
|
||||||
// ast_log(LOG_WARNING, "after dst:%s: temp:%s:\n",dst,temp);
|
|
||||||
|
|
||||||
if (*tech != '\0'){ /* check if it is requested NAPTR */
|
if (*tech != '\0'){ /* check if it is requested NAPTR */
|
||||||
if (!strncasecmp(tech, "ALL", techsize)){
|
if (!strncasecmp(tech, "ALL", techsize)){
|
||||||
|
Reference in New Issue
Block a user