From f3f3aae4b7841f4dc51129691a7404a03eb55449 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 14 Mar 2016 14:38:36 -0400 Subject: [PATCH] Improve conversions from uint64 to Perl types. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 | 14 +++++--------- 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 *); -- 2.40.0