This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Quad_t and Uquad_t cannot unpack as NVs.
authorJarkko Hietaniemi <jhi@iki.fi>
Tue, 6 May 2014 16:50:55 +0000 (12:50 -0400)
committerTony Cook <tony@develop-help.com>
Thu, 29 May 2014 06:50:54 +0000 (16:50 +1000)
If IVSIZE >= 8, a Quad_t is always >= IV_MIN, and <= IV_MAX, and an
Uquad_t is always (>= 0 aka UV_MIN and) <= UV_MAX; they cannot escape
their quadness and be NVs.  (This logic may fail if Quad_t is not 8
bytes, but then other things would no doubt fail.)

Also tighten the logic by adding HAS_QUAD, also for the pack case.

Fix for Coverity perl5 CID 28942.

pp_pack.c

index 3aa7a73..e4211b1 100644 (file)
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -1632,14 +1632,13 @@ S_unpack_rec(pTHX_ tempsym_t* symptr, const char *s, const char *strbeg, const c
                PUSHs(newSVpvn_flags(aptr, len, SVs_TEMP));
            }
            break;
-#if IVSIZE >= 8
+#if defined(HAS_QUAD) && IVSIZE >= 8
        case 'q':
            while (len-- > 0) {
                Quad_t aquad;
                 SHIFT_VAR(utf8, s, strend, aquad, datumtype, needs_swap);
                if (!checksum)
-                    mPUSHs(aquad >= IV_MIN && aquad <= IV_MAX ?
-                          newSViv((IV)aquad) : newSVnv((NV)aquad));
+                    mPUSHs(newSViv((IV)aquad));
                else if (checksum > bits_in_uv)
                    cdouble += (NV)aquad;
                else
@@ -1651,8 +1650,7 @@ S_unpack_rec(pTHX_ tempsym_t* symptr, const char *s, const char *strbeg, const c
                Uquad_t auquad;
                 SHIFT_VAR(utf8, s, strend, auquad, datumtype, needs_swap);
                if (!checksum)
-                   mPUSHs(auquad <= UV_MAX ?
-                          newSVuv((UV)auquad) : newSVnv((NV)auquad));
+                   mPUSHs(newSVuv((UV)auquad));
                else if (checksum > bits_in_uv)
                    cdouble += (NV)auquad;
                else
@@ -2982,7 +2980,7 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist )
                 PUSH32(utf8, cur, &ai32, needs_swap);
            }
            break;
-#if IVSIZE >= 8
+#if defined(HAS_QUAD) && IVSIZE >= 8
        case 'Q':
            while (len-- > 0) {
                Uquad_t auquad;