From: Gisle Aas Date: Sun, 11 Dec 2005 18:14:24 +0000 (+0000) Subject: Disallow sprintf's vector handling for non-integer formats. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=26372e719d968db9587087a91713eb8747db7141;p=p5sagit%2Fp5-mst-13.2.git Disallow sprintf's vector handling for non-integer formats. Avoids core dump for printf("%vs") and similar. p4raw-id: //depot/perl@26321 --- diff --git a/sv.c b/sv.c index fc2540d..f48e886 100644 --- a/sv.c +++ b/sv.c @@ -8103,12 +8103,14 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV if (*q == '%') { eptr = q++; elen = 1; + if (vectorize) { + c = '%'; + goto unknown; + } goto string; } - if (vectorize) - argsv = vecsv; - else if (!args) { + if (!vectorize && !args) { if (efix) { const I32 i = efix-1; argsv = (i >= 0 && i < svmax) ? svargs[i] : &PL_sv_undef; @@ -8123,7 +8125,9 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV /* STRINGS */ case 'c': - uv = (args && !vectorize) ? va_arg(*args, int) : SvIVx(argsv); + if (vectorize) + goto unknown; + uv = (args) ? va_arg(*args, int) : SvIVx(argsv); if ((uv > 255 || (!UNI_IS_INVARIANT(uv) && SvUTF8(sv))) && !IN_BYTES) { @@ -8139,7 +8143,9 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV goto string; case 's': - if (args && !vectorize) { + if (vectorize) + goto unknown; + if (args) { eptr = va_arg(*args, char*); if (eptr) #ifdef MACOS_TRADITIONAL @@ -8170,7 +8176,6 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV } string: - vectorize = FALSE; if (has_precis && elen > precis) elen = precis; break; @@ -8385,6 +8390,8 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV case 'e': case 'E': case 'f': case 'g': case 'G': + if (vectorize) + goto unknown; /* This is evil, but floating point is even more evil */ @@ -8417,7 +8424,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV } /* now we need (long double) if intsize == 'q', else (double) */ - nv = (args && !vectorize) ? + nv = (args) ? #if LONG_DOUBLESIZE > DOUBLESIZE intsize == 'q' ? va_arg(*args, long double) : @@ -8428,7 +8435,6 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV : SvNVx(argsv); need = 0; - vectorize = FALSE; if (c != 'e' && c != 'E') { i = PERL_INT_MIN; /* FIXME: if HAS_LONG_DOUBLE but not USE_LONG_DOUBLE this @@ -8586,8 +8592,10 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV /* SPECIAL */ case 'n': + if (vectorize) + goto unknown; i = SvCUR(sv) - origlen; - if (args && !vectorize) { + if (args) { switch (intsize) { case 'h': *(va_arg(*args, short*)) = i; break; default: *(va_arg(*args, int*)) = i; break; @@ -8600,7 +8608,6 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV } else sv_setuv_mg(argsv, (UV)i); - vectorize = FALSE; continue; /* not "break" */ /* UNKNOWN */ diff --git a/t/op/sprintf.t b/t/op/sprintf.t index 4130a5a..d7f71e7 100755 --- a/t/op/sprintf.t +++ b/t/op/sprintf.t @@ -404,11 +404,18 @@ __END__ >%*2*2$d< >[12, 3]< >%*2*2$d INVALID< >%*2$1d< >[12, 3]< >%*2$1d INVALID< >%0v2.2d< >''< >< ->%vc,%d< >[63, 64, 65]< >?,64< +>%vc,%d< >[63, 64, 65]< >%vc,63 INVALID< +>%v%,%d< >[63, 64, 65]< >%v%,63 INVALID< >%vd,%d< >[1, 2, 3]< >49,2< ->%vf,%d< >[1, 2, 3]< >1.000000,2< +>%vf,%d< >[1, 2, 3]< >%vf,1 INVALID< +>%vF,%d< >[1, 2, 3]< >%vF,1 INVALID< +>%ve,%d< >[1, 2, 3]< >%ve,1 INVALID< +>%vE,%d< >[1, 2, 3]< >%vE,1 INVALID< +>%vg,%d< >[1, 2, 3]< >%vg,1 INVALID< +>%vG,%d< >[1, 2, 3]< >%vG,1 INVALID< >%vp< >''< >%vp INVALID< ->%vs,%d< >[1, 2, 3]< >1,2< +>%vn< >''< >%vn INVALID< +>%vs,%d< >[1, 2, 3]< >%vs,1 INVALID< >%v_< >''< >%v_ INVALID< >%v#x< >''< >%v#x INVALID< >%v02x< >"foo\012"< >66.6f.6f.0a<