|
|
dcb3b7 |
From cfb736762c1becf344ce6beaa701ff2e1abd5f9c Mon Sep 17 00:00:00 2001
|
|
|
dcb3b7 |
From: Yves Orton <demerphq@gmail.com>
|
|
|
dcb3b7 |
Date: Tue, 13 Sep 2016 23:14:49 +0200
|
|
|
dcb3b7 |
Subject: [PATCH 4/5] fix #129267: rework gv_fetchmethod_pvn_flags separator
|
|
|
dcb3b7 |
parsing
|
|
|
dcb3b7 |
MIME-Version: 1.0
|
|
|
dcb3b7 |
Content-Type: text/plain; charset=UTF-8
|
|
|
dcb3b7 |
Content-Transfer-Encoding: 8bit
|
|
|
dcb3b7 |
|
|
|
dcb3b7 |
With previous code we could overrun the end of the name when
|
|
|
dcb3b7 |
the last char in the string was a colon. This reworks the code
|
|
|
dcb3b7 |
so it is more clear what is going on, and so it more similar
|
|
|
dcb3b7 |
to other code that also parses out package separaters in gv.c.
|
|
|
dcb3b7 |
|
|
|
dcb3b7 |
This is a rework of the reverted patches:
|
|
|
dcb3b7 |
243ca72 rename "nend" name_cursor in Perl_gv_fetchmethod_pvn_flags
|
|
|
dcb3b7 |
b053c93 fix: [perl #129267] Possible string overrun with invalid len in gv.c
|
|
|
dcb3b7 |
|
|
|
dcb3b7 |
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
|
|
dcb3b7 |
---
|
|
|
dcb3b7 |
gv.c | 36 ++++++++++++++++++++++++++----------
|
|
|
dcb3b7 |
1 file changed, 26 insertions(+), 10 deletions(-)
|
|
|
dcb3b7 |
|
|
|
dcb3b7 |
diff --git a/gv.c b/gv.c
|
|
|
dcb3b7 |
index 07709a0..3237c53 100644
|
|
|
dcb3b7 |
--- a/gv.c
|
|
|
dcb3b7 |
+++ b/gv.c
|
|
|
dcb3b7 |
@@ -1010,7 +1010,6 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
|
|
|
dcb3b7 |
{
|
|
|
dcb3b7 |
const char * const origname = name;
|
|
|
dcb3b7 |
const char * const name_end = name + len;
|
|
|
dcb3b7 |
- const char *nend;
|
|
|
dcb3b7 |
const char *last_separator = NULL;
|
|
|
dcb3b7 |
GV* gv;
|
|
|
dcb3b7 |
HV* ostash = stash;
|
|
|
dcb3b7 |
@@ -1029,16 +1028,33 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
|
|
|
dcb3b7 |
the error reporting code. */
|
|
|
dcb3b7 |
}
|
|
|
dcb3b7 |
|
|
|
dcb3b7 |
- for (nend = name; *nend || nend != name_end; nend++) {
|
|
|
dcb3b7 |
- if (*nend == '\'') {
|
|
|
dcb3b7 |
- last_separator = nend;
|
|
|
dcb3b7 |
- name = nend + 1;
|
|
|
dcb3b7 |
- }
|
|
|
dcb3b7 |
- else if (*nend == ':' && *(nend + 1) == ':') {
|
|
|
dcb3b7 |
- last_separator = nend++;
|
|
|
dcb3b7 |
- name = nend + 1;
|
|
|
dcb3b7 |
- }
|
|
|
dcb3b7 |
+ {
|
|
|
dcb3b7 |
+ /* check if the method name is fully qualified or
|
|
|
dcb3b7 |
+ * not, and separate the package name from the actual
|
|
|
dcb3b7 |
+ * method name.
|
|
|
dcb3b7 |
+ *
|
|
|
dcb3b7 |
+ * leaves last_separator pointing to the beginning of the
|
|
|
dcb3b7 |
+ * last package separator (either ' or ::) or 0
|
|
|
dcb3b7 |
+ * if none was found.
|
|
|
dcb3b7 |
+ *
|
|
|
dcb3b7 |
+ * leaves name pointing at the beginning of the
|
|
|
dcb3b7 |
+ * method name.
|
|
|
dcb3b7 |
+ */
|
|
|
dcb3b7 |
+ const char *name_cursor = name;
|
|
|
dcb3b7 |
+ const char * const name_em1 = name_end - 1; /* name_end minus 1 */
|
|
|
dcb3b7 |
+ for (name_cursor = name; name_cursor < name_end ; name_cursor++) {
|
|
|
dcb3b7 |
+ if (*name_cursor == '\'') {
|
|
|
dcb3b7 |
+ last_separator = name_cursor;
|
|
|
dcb3b7 |
+ name = name_cursor + 1;
|
|
|
dcb3b7 |
+ }
|
|
|
dcb3b7 |
+ else if (name_cursor < name_em1 && *name_cursor == ':' && name_cursor[1] == ':') {
|
|
|
dcb3b7 |
+ last_separator = name_cursor++;
|
|
|
dcb3b7 |
+ name = name_cursor + 1;
|
|
|
dcb3b7 |
+ }
|
|
|
dcb3b7 |
+ }
|
|
|
dcb3b7 |
}
|
|
|
dcb3b7 |
+
|
|
|
dcb3b7 |
+ /* did we find a separator? */
|
|
|
dcb3b7 |
if (last_separator) {
|
|
|
dcb3b7 |
if ((last_separator - origname) == 5 && memEQ(origname, "SUPER", 5)) {
|
|
|
dcb3b7 |
/* ->SUPER::method should really be looked up in original stash */
|
|
|
dcb3b7 |
--
|
|
|
dcb3b7 |
2.7.4
|
|
|
dcb3b7 |
|