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