prevent SEGV from buffer read overrun, and refactor away duplicated code
authorYves Orton <demerphq@gmail.com>
Wed, 27 Mar 2013 10:17:25 +0000 (11:17 +0100)
committerYves Orton <demerphq@gmail.com>
Wed, 27 Mar 2013 10:17:25 +0000 (11:17 +0100)
The split patch introduced a buffer read overrun error in sv_dump() when
stringifying empty strings. This bug was always existant but was probably
never triggered because we almost always have at least one extflags set,
so it never got an empty buffer to show. Not so with the new compflags. :-(

dump.c

index eaf6674..b2857d3 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -2095,25 +2095,22 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
       dumpregexp:
        {
            struct regexp * const r = ReANY((REGEXP*)sv);
-            flags = r->compflags;
-            sv_setpv(d,"");
-            append_flags(d, flags, regexp_flags_names);
-            if (*(SvEND(d) - 1) == ',') {
-                SvCUR_set(d, SvCUR(d) - 1);
-                SvPVX(d)[SvCUR(d)] = '\0';
-            }
+#define SV_SET_STRINGIFY_REGEXP_FLAGS(d,flags) STMT_START { \
+            sv_setpv(d,"");                                 \
+            append_flags(d, flags, regexp_flags_names);     \
+            if (SvCUR(d) > 0 && *(SvEND(d) - 1) == ',') {       \
+                SvCUR_set(d, SvCUR(d) - 1);                 \
+                SvPVX(d)[SvCUR(d)] = '\0';                  \
+            }                                               \
+} STMT_END
+            SV_SET_STRINGIFY_REGEXP_FLAGS(d,r->compflags);
             Perl_dump_indent(aTHX_ level, file, "  COMPFLAGS = 0x%"UVxf" (%s)\n",
                                 (UV)(r->compflags), SvPVX_const(d));
 
-            flags = r->extflags;
-           sv_setpv(d,"");
-           append_flags(d, flags, regexp_flags_names);
-           if (*(SvEND(d) - 1) == ',') {
-               SvCUR_set(d, SvCUR(d) - 1);
-               SvPVX(d)[SvCUR(d)] = '\0';
-           }
+            SV_SET_STRINGIFY_REGEXP_FLAGS(d,r->extflags);
            Perl_dump_indent(aTHX_ level, file, "  EXTFLAGS = 0x%"UVxf" (%s)\n",
                                 (UV)(r->extflags), SvPVX_const(d));
+#undef SV_SET_STRINGIFY_REGEXP_FLAGS
 
            Perl_dump_indent(aTHX_ level, file, "  INTFLAGS = 0x%"UVxf"\n",
                                (UV)(r->intflags));