| 1 | From f1ec1982725d60045c0d871f3e613f2880046c22 Mon Sep 17 00:00:00 2001
|
| 2 | From: Nicholas Marriott <[email protected]>
|
| 3 | Date: Wed, 1 Feb 2023 15:31:30 +0000
|
| 4 | Subject: [PATCH] Fix bugs in PCRE2 code - don't walk off the end of the match
|
| 5 | list if NOMATCH is returned, and don't stop on empty matches. From Thomas
|
| 6 | Hurst.
|
| 7 |
|
| 8 | ---
|
| 9 | pcre.c | 45 ++++++++++++++++++++++++++-------------------
|
| 10 | 1 file changed, 26 insertions(+), 19 deletions(-)
|
| 11 |
|
| 12 | diff --git a/pcre.c b/pcre.c
|
| 13 | index e9a7f84..8d53532 100644
|
| 14 | |
| 15 | |
| 16 | @@ -66,7 +66,7 @@ int
|
| 17 | re_block(struct re *re, const void *buf, size_t len, struct rmlist *rml,
|
| 18 | char **cause)
|
| 19 | {
|
| 20 | - int res;
|
| 21 | + int res, ret;
|
| 22 | pcre2_match_data *pmd;
|
| 23 | PCRE2_SIZE *ovector;
|
| 24 | u_int i, j;
|
| 25 | @@ -85,27 +85,34 @@ re_block(struct re *re, const void *buf, size_t len, struct rmlist *rml,
|
| 26 | }
|
| 27 |
|
| 28 | pmd = pcre2_match_data_create_from_pattern(re->pcre2, NULL);
|
| 29 | - res = pcre2_match(re->pcre2, buf, len, 0, 0, pmd, NULL);
|
| 30 | - if (res < 0 && res != PCRE2_ERROR_NOMATCH) {
|
| 31 | - xasprintf(cause, "%s: regexec failed", re->str);
|
| 32 | - pcre2_match_data_free(pmd);
|
| 33 | - return (-1);
|
| 34 | - }
|
| 35 | + if (pmd == NULL)
|
| 36 | + fatalx("pcre2_match_data_create_from_pattern failed");
|
| 37 |
|
| 38 | - if (rml != NULL) {
|
| 39 | - ovector = pcre2_get_ovector_pointer(pmd);
|
| 40 | - for (i = 0; i < res; i++) {
|
| 41 | - j = i * 2;
|
| 42 | - if (ovector[j + 1] <= ovector[j])
|
| 43 | - break;
|
| 44 | - rml->list[i].valid = 1;
|
| 45 | - rml->list[i].so = ovector[j];
|
| 46 | - rml->list[i].eo = ovector[j + 1];
|
| 47 | + res = pcre2_match(re->pcre2, buf, len, 0, 0, pmd, NULL);
|
| 48 | + if (res > 0) {
|
| 49 | + if (rml != NULL) {
|
| 50 | + if (res > NPMATCH)
|
| 51 | + res = NPMATCH;
|
| 52 | + ovector = pcre2_get_ovector_pointer(pmd);
|
| 53 | + for (i = 0; i < res; i++) {
|
| 54 | + j = i * 2;
|
| 55 | + if (ovector[j + 1] < ovector[j])
|
| 56 | + break;
|
| 57 | + rml->list[i].valid = 1;
|
| 58 | + rml->list[i].so = ovector[j];
|
| 59 | + rml->list[i].eo = ovector[j + 1];
|
| 60 | + }
|
| 61 | + rml->valid = 1;
|
| 62 | }
|
| 63 | - rml->valid = 1;
|
| 64 | + ret = 1;
|
| 65 | + } else if (res == PCRE2_ERROR_NOMATCH)
|
| 66 | + ret = 0;
|
| 67 | + else {
|
| 68 | + xasprintf(cause, "%s: regexec failed", re->str);
|
| 69 | + ret = -1;
|
| 70 | }
|
| 71 | -
|
| 72 | - return (res != PCRE2_ERROR_NOMATCH);
|
| 73 | + pcre2_match_data_free(pmd);
|
| 74 | + return (ret);
|
| 75 | }
|
| 76 |
|
| 77 | void
|