diff options
author | Tom Lane | 2016-03-14 18:38:36 +0000 |
---|---|---|
committer | Tom Lane | 2016-03-14 18:38:44 +0000 |
commit | f3f3aae4b7841f4dc51129691a7404a03eb55449 (patch) | |
tree | f11852dce43fdb7906466cec03bd3625a5b1bc6d | |
parent | 6be84eeb8d5a72014b1b6e44d0646f69531a1ccf (diff) |
Improve conversions from uint64 to Perl types.
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
-rw-r--r-- | src/pl/plperl/plperl.c | 14 | ||||
-rw-r--r-- | src/pl/plperl/plperl.h | 7 |
2 files changed, 12 insertions, 9 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 269f7f3322..1114b59416 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -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"))); diff --git a/src/pl/plperl/plperl.h b/src/pl/plperl/plperl.h index 9179bbd339..0146d60a11 100644 --- a/src/pl/plperl/plperl.h +++ b/src/pl/plperl/plperl.h @@ -88,6 +88,13 @@ #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 *); |