This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
sprintf %a/%A more sanity checks
authorDavid Mitchell <davem@iabyn.com>
Thu, 1 Jun 2017 09:52:12 +0000 (10:52 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 7 Jun 2017 08:11:08 +0000 (09:11 +0100)
For the code which generates hexadecimal floating-point formats,
add extra sanity checks against buffer overruns.

sv.c

diff --git a/sv.c b/sv.c
index 486672a..f7b3137 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -11274,6 +11274,9 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal,
 #endif
 
     const U8* vmaxend = vhex + HEXTRACTSIZE;
+
+    assert(HEXTRACTSIZE <= VHEX_SIZE);
+
     PERL_UNUSED_VAR(ix); /* might happen */
     (void)Perl_frexp(PERL_ABS(nv), exponent);
     *subnormal = FALSE;
@@ -11516,6 +11519,8 @@ S_hextract(pTHX_ const NV nv, int* exponent, bool *subnormal,
  * same name within Perl_sv_vcatpvfn_flags().
  *
  * It assumes the caller has already done STORE_LC_NUMERIC_SET_TO_NEEDED();
+ *
+ * It requires the caller to make buf large enough.
  */
 
 static STRLEN
@@ -11757,6 +11762,12 @@ S_format_hexfp(pTHX_ char * const buf, const STRLEN bufsize, const char c,
     }
 
     elen = p - buf;
+
+    /* sanity checks */
+    if (elen >= bufsize || width >= bufsize)
+        /* diag_listed_as: Hexadecimal float: internal error (%s) */
+        Perl_croak(aTHX_ "Hexadecimal float: internal error (overflow)");
+
     elen += my_snprintf(p, bufsize - elen,
                         "%c%+d", lower ? 'p' : 'P',
                         exponent);