postgres.git / summary / log / commit / refs

commit    ff5ef6add448a180909f1c45151b0aa9929982d9
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Tue Oct 18 16:24:46 2016 +0000

    Fix cidin() to handle values above 2^31 platform-independently.
    
    CommandId is declared as uint32, and values up to 4G are indeed legal.
    cidout() handles them properly by treating the value as unsigned int.
    But cidin() was just using atoi(), which has platform-dependent behavior
    for values outside the range of signed int, as reported by Bart Lengkeek
    in bug #14379.  Use strtoul() instead, as xidin() does.
    
    In passing, make some purely cosmetic changes to make xidin/xidout
    look more like cidin/cidout; the former didn't have a monopoly on
    best practice IMO.
    
    Neither xidin nor cidin make any attempt to throw error for invalid input.
    I didn't change that here, and am not sure it's worth worrying about
    since neither is really a user-facing type.  The point is just to ensure
    that indubitably-valid inputs work as expected.
    
    It's been like this for a long time, so back-patch to all supported
    branches.
    
    Report: <20161018152550.1413.6439@wrigleys.postgresql.org>


src/backend/utils/adt/xid.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/backend/utils/adt/xid.c b/src/backend/utils/adt/xid.c index db1e925ebfc..33e274b466e 100644 --- a/src/backend/utils/adt/xid.c +++ b/src/backend/utils/adt/xid.c @@ -40,13 +40,10 @@ Datum xidout(PG_FUNCTION_ARGS) { TransactionId transactionId = PG_GETARG_TRANSACTIONID(0); + char *result = (char *) palloc(16); - /* maximum 32 bit unsigned integer representation takes 10 chars */ - char *str = palloc(11); - - snprintf(str, 11, "%lu", (unsigned long) transactionId); - - PG_RETURN_CSTRING(str); + snprintf(result, 16, "%lu", (unsigned long) transactionId); + PG_RETURN_CSTRING(result); } /* @@ -132,12 +129,9 @@ xidComparator(const void *arg1, const void *arg2) Datum cidin(PG_FUNCTION_ARGS) { - char *s = PG_GETARG_CSTRING(0); - CommandId c; - - c = atoi(s); + char *str = PG_GETARG_CSTRING(0); - PG_RETURN_COMMANDID(c); + PG_RETURN_COMMANDID((CommandId) strtoul(str, NULL, 0)); } /* @@ -149,7 +143,7 @@ cidout(PG_FUNCTION_ARGS) CommandId c = PG_GETARG_COMMANDID(0); char *result = (char *) palloc(16); - snprintf(result, 16, "%u", (unsigned int) c); + snprintf(result, 16, "%lu", (unsigned long) c); PG_RETURN_CSTRING(result); } [parent: be680535e9c1]