Changeset: 0ad4a6d4f1b1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0ad4a6d4f1b1
Modified Files:
monetdb5/modules/mal/pcre.c
Branch: default
Log Message:
Add some bounds checks, and make it work if the replacement starts with a
backreference.
diffs (103 lines):
diff --git a/monetdb5/modules/mal/pcre.c b/monetdb5/modules/mal/pcre.c
--- a/monetdb5/modules/mal/pcre.c
+++ b/monetdb5/modules/mal/pcre.c
@@ -563,7 +563,6 @@ pcre_replace(str *res, const char *origi
pcre *pcre_code = NULL;
pcre_extra *extra;
char *tmpres;
- char tmpbackref[4]; /* enough for 0 to 999 */
int i, j, k, m, len, errpos = 0, offset = 0;
int compile_options = PCRE_UTF8, exec_options = PCRE_NOTEMPTY;
int *ovector, ovecsize;
@@ -635,7 +634,7 @@ pcre_replace(str *res, const char *origi
offset, exec_options, ovector,
ovecsize);
if (j > 0) {
ncaptures = 0;
- for (i=0; (i < j) && (ncaptures < MAX_NR_CAPTURES);
i++) {
+ for (i = 0; i < j && i < MAX_NR_MATCHES && ncaptures <
MAX_NR_CAPTURES; i++) {
capture_offsets[nmatches][i*2] = ovector[i*2];
capture_offsets[nmatches][i*2+1] =
ovector[i*2+1];
ncaptures++;
@@ -650,21 +649,18 @@ pcre_replace(str *res, const char *origi
if (nmatches > 0) {
/* identify back references in the replacement string */
- for (i=0; i<len_replacement; i++) {
+ for (i = 0; i < len_replacement && nbackrefs < MAX_NR_CAPTURES;
i++) {
if (replacement[i] == '$' || replacement[i] == '\\') {
- if (i>0 && replacement[i-1] != '\\') {
- for (k=0; i+k+1<len_replacement; k++) {
- if (!isdigit((unsigned
char)replacement[i+k+1]))
- break;
- }
- if (k>0) {
- strncpy(tmpbackref,
replacement+i+1, k);
- tmpbackref[i+1+k] = '\0';
- backrefs[nbackrefs] =
atoi(tmpbackref);
- backref_offsets[nbackrefs*2] =
i;
- backref_offsets[nbackrefs*2+1]
= i+k+1;
- nbackrefs++;
- }
+ char *endptr;
+ backrefs[nbackrefs] = strtol(replacement + i +
1, &endptr, 10);
+ if (endptr > replacement + i + 1) {
+ k = (int) (endptr - (replacement + i +
1));
+ backref_offsets[nbackrefs * 2] = i;
+ backref_offsets[nbackrefs * 2 + 1] = i
+ k + 1;
+ nbackrefs++;
+ } else if (replacement[i] == '\\') {
+ /* skip quoted character */
+ i++;
}
}
}
@@ -749,7 +745,6 @@ pcre_replace_bat(BAT **res, BAT *origin_
BATiter origin_strsi = bat_iterator(origin_strs);
const char *err_p = NULL;
char *tmpres, *tmps;
- char tmpbackref[4]; /* enough for 0 to 999 */
int i, j, k, m, len, errpos = 0, offset = 0;
int compile_options = PCRE_UTF8, exec_options = PCRE_NOTEMPTY;
pcre *pcre_code = NULL;
@@ -817,21 +812,18 @@ pcre_replace_bat(BAT **res, BAT *origin_
}
/* identify back references in the replacement string */
- for (i = 0; i < len_replacement; i++) {
+ for (i = 0; i < len_replacement && nbackrefs < MAX_NR_CAPTURES; i++) {
if (replacement[i] == '$' || replacement[i] == '\\') {
- if (i > 0 && replacement[i - 1] != '\\') {
- for (k = 0; i + k + 1 < len_replacement; k++) {
- if (!isdigit((unsigned
char)replacement[i + k + 1]))
- break;
- }
- if (k > 0) {
- strncpy(tmpbackref, replacement + i +
1, k);
- tmpbackref[i + 1 + k] = '\0';
- backrefs[nbackrefs] = atoi(tmpbackref);
- backref_offsets[nbackrefs * 2] = i;
- backref_offsets[nbackrefs * 2 + 1] = i
+ k + 1;
- nbackrefs++;
- }
+ char *endptr;
+ backrefs[nbackrefs] = strtol(replacement + i + 1,
&endptr, 10);
+ if (endptr > replacement + i + 1) {
+ k = (int) (endptr - (replacement + i + 1));
+ backref_offsets[nbackrefs * 2] = i;
+ backref_offsets[nbackrefs * 2 + 1] = i + k + 1;
+ nbackrefs++;
+ } else if (replacement[i] == '\\') {
+ /* skip quoted character */
+ i++;
}
}
}
@@ -863,7 +855,7 @@ pcre_replace_bat(BAT **res, BAT *origin_
offset, exec_options,
ovector, ovecsize);
if (j > 0) {
ncaptures = 0;
- for (i = 0; i < j && ncaptures <
MAX_NR_CAPTURES; i++) {
+ for (i = 0; i < j && i < MAX_NR_MATCHES &&
ncaptures < MAX_NR_CAPTURES; i++) {
capture_offsets[nmatches][i * 2] =
ovector[i * 2];
capture_offsets[nmatches][i * 2 + 1] =
ovector[i * 2 + 1];
ncaptures++;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list