diff options
author | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2015-05-16 11:05:40 +0000 |
---|---|---|
committer | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2015-05-16 11:05:40 +0000 |
commit | 2fa78aa4e42bcebf2d616c4ee89c012f29dc3447 (patch) | |
tree | a45abf928ba1e6f2aef5fbe82c8725b98d3eb97b | |
parent | 4b79af6b4cbeb5326ae5e4d83f3e935e00286c19 (diff) | |
download | pcre-2fa78aa4e42bcebf2d616c4ee89c012f29dc3447.tar.gz |
Fix named forward reference to duplicate group number overflow bug.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1559 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | pcre_compile.c | 26 | ||||
-rw-r--r-- | testdata/testinput1 | 3 | ||||
-rw-r--r-- | testdata/testoutput1 | 5 |
4 files changed, 30 insertions, 9 deletions
@@ -22,6 +22,11 @@ Version 8.38 xx-xxx-xxxx 4. A recursive back reference by name within a group that had the same name as another group caused a buffer overflow. For example: /(?J)(?'d'(?'d'\g{d}))/. This bug was discovered by the LLVM fuzzer. + +30. A forward reference by name to a group whose number is the same as the + current group, for example in this pattern: /(?|(\k'Pm')|(?'Pm'))/, caused + a buffer overflow at compile time. This bug was discovered by the LLVM + fuzzer. Version 8.37 28-April-2015 diff --git a/pcre_compile.c b/pcre_compile.c index fd413ac..245a311 100644 --- a/pcre_compile.c +++ b/pcre_compile.c @@ -7187,15 +7187,15 @@ for (;; ptr++) open_capitem *oc; recno = ng->number; if (is_recurse) break; - for (oc = cd->open_caps; oc != NULL; oc = oc->next) - { - if (oc->number == recno) - { - oc->flag = TRUE; + for (oc = cd->open_caps; oc != NULL; oc = oc->next) + { + if (oc->number == recno) + { + oc->flag = TRUE; break; - } - } - } + } + } + } } /* Count named back references. */ @@ -7207,6 +7207,14 @@ for (;; ptr++) 16-bit data item. */ *lengthptr += IMM2_SIZE; + + /* If this is a forward reference and we are within a (?|...) group, + the reference may end up as the number of a group which we are + currently inside, that is, it could be a recursive reference. In the + real compile this will be picked up and the reference wrapped with + OP_ONCE to make it atomic, so we must space in case this occurs. */ + + if (recno == 0) *lengthptr += 2 + 2*LINK_SIZE; } /* In the real compile, search the name table. We check the name @@ -7579,7 +7587,7 @@ for (;; ptr++) previous = NULL; cd->iscondassert = FALSE; } - else + else { previous = code; item_hwm_offset = cd->hwm - cd->start_workspace; diff --git a/testdata/testinput1 b/testdata/testinput1 index 73c2f4d..8379ce0 100644 --- a/testdata/testinput1 +++ b/testdata/testinput1 @@ -5730,4 +5730,7 @@ AbcdCBefgBhiBqz "(?1)(?#?'){8}(a)" baaaaaaaaac +"(?|(\k'Pm')|(?'Pm'))" + abcd + /-- End of testinput1 --/ diff --git a/testdata/testoutput1 b/testdata/testoutput1 index 0a53fd0..e852ab9 100644 --- a/testdata/testoutput1 +++ b/testdata/testoutput1 @@ -9429,4 +9429,9 @@ No match 0: aaaaaaaaa 1: a +"(?|(\k'Pm')|(?'Pm'))" + abcd + 0: + 1: + /-- End of testinput1 --/ |