]> granicus.if.org Git - postgresql/commitdiff
Improve conversions from uint64 to Perl types.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 14 Mar 2016 18:38:36 +0000 (14:38 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 14 Mar 2016 18:38:44 +0000 (14:38 -0400)
Perl's integers are pointer-sized, so can hold more than INT_MAX on LP64
platforms, and come in both signed (IV) and unsigned (UV).  Floating
point values (NV) may also be larger than double.

Since Perl 5.19.4 array indices are SSize_t instead of I32, so allow up
to SSize_t_max on those versions.  The limit is not imposed just by
av_extend's argument type, but all the array handling code, so remove
the speculative comment.

Dagfinn Ilmari MannsÃ¥ker

src/pl/plperl/plperl.c
src/pl/plperl/plperl.h

index 269f7f332206d5b590ca648a31a20538bfa1a6dd..1114b594165564767cf3416e76f198608de3a8aa 100644 (file)
@@ -3104,9 +3104,9 @@ plperl_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 processed,
        hv_store_string(result, "status",
                                        cstr2sv(SPI_result_code_string(status)));
        hv_store_string(result, "processed",
-                                       (processed > (uint64) INT_MAX) ?
-                                       newSVnv((double) processed) :
-                                       newSViv((int) processed));
+                                       (processed > (uint64) UV_MAX) ?
+                                       newSVnv((NV) processed) :
+                                       newSVuv((UV) processed));
 
        if (status > 0 && tuptable)
        {
@@ -3114,12 +3114,8 @@ plperl_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 processed,
                SV                 *row;
                uint64          i;
 
-               /*
-                * av_extend's 2nd argument is declared I32.  It's possible we could
-                * nonetheless push more than INT_MAX elements into a Perl array, but
-                * let's just fail instead of trying.
-                */
-               if (processed > (uint64) INT_MAX)
+               /* Prevent overflow in call to av_extend() */
+               if (processed > (uint64) AV_SIZE_MAX)
                        ereport(ERROR,
                                        (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                        errmsg("query result has too many rows to fit in a Perl array")));
index 9179bbd33909f6307c4b70c2cf87682779232f88..0146d60a116077968ec07870e6df21cdcb8070b0 100644 (file)
 #define GvCV_set(gv, cv)               (GvCV(gv) = cv)
 #endif
 
+/* Perl 5.19.4 changed array indices from I32 to SSize_t */
+#if PERL_BCDVERSION >= 0x5019004
+#define AV_SIZE_MAX SSize_t_MAX
+#else
+#define AV_SIZE_MAX I32_MAX
+#endif
+
 /* declare routines from plperl.c for access by .xs files */
 HV                *plperl_spi_exec(char *, int);
 void           plperl_return_next(SV *);