This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Perl_sv_vcatpvfn_flags: avoid a potential wrap
authorDavid Mitchell <davem@iabyn.com>
Wed, 10 May 2017 14:27:49 +0000 (15:27 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 7 Jun 2017 08:11:00 +0000 (09:11 +0100)
In the floating-point hex (%a) code, it checks whether the requested
precision is smaller than the hex buf size. It does this by casting
(precis + 1) to signed. Since precis can be any user-supplied value,
this can wrap. Instead, cast the (buffer_length - 1) to unsigned, since
this is bounded to a small constant value > 1.

In practise this makes no difference currently, as a large precis will
have caused a malloc panic earlier anyway. But that might change in
future.

sv.c

diff --git a/sv.c b/sv.c
index f56fc16..59960a9 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -12694,7 +12694,8 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                     if (has_precis) {
                         U8* ve = (subnormal ? vlnz + 1 : vend);
                         SSize_t vn = ve - v0;
-                        if ((SSize_t)(precis + 1) < vn) {
+                        assert(vn >= 1);
+                        if (precis < (Size_t)(vn - 1)) {
                             bool overflow = FALSE;
                             if (v0[precis + 1] < 0x8) {
                                 /* Round down, nothing to do. */