[perl #121366] avoid using an invalid SvPVX() in Perl_sv_pvn_force_flags
authorTony Cook <tony@develop-help.com>
Wed, 26 Mar 2014 03:31:57 +0000 (14:31 +1100)
committerTony Cook <tony@develop-help.com>
Wed, 26 Mar 2014 03:31:57 +0000 (14:31 +1100)
This would cause valgrind to complain about:

  vec($Foo, 0, 1) = 1; # for example

when $Foo was undef, since SvPVX()[1] isn't initialized until the SV is
at least a SVt_PV.

[1] well, sv_u.svu_rv, but sv_u is a union, so the same memory is
initialized.  This isn't technically legal from a C point of view,
but pointer types are compatible enough with each other for it to not
be an issue.

sv.c

diff --git a/sv.c b/sv.c
index dcb1d5e..087606b 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -9502,7 +9502,8 @@ Perl_sv_pvn_force_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
        if (lp)
            *lp = len;
 
-       if (s != SvPVX_const(sv)) {     /* Almost, but not quite, sv_setpvn() */
+        if (SvTYPE(sv) < SVt_PV ||
+            s != SvPVX_const(sv)) {    /* Almost, but not quite, sv_setpvn() */
            if (SvROK(sv))
                sv_unref(sv);
            SvUPGRADE(sv, SVt_PV);              /* Never FALSE */