aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-10-18 12:24:46 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2016-10-18 12:24:58 -0400
commit219d476d8a8b720a034c6b21c5782c6fc20f5bf8 (patch)
treeb88e937a097157a3c204cb1004fe054beb4aaad1
parent75c9d9a674a1feec3c02aa83e3f24275e6d4cba5 (diff)
downloadpostgresql-219d476d8a8b720a034c6b21c5782c6fc20f5bf8.tar.gz
postgresql-219d476d8a8b720a034c6b21c5782c6fc20f5bf8.zip
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>
-rw-r--r--src/backend/utils/adt/xid.c18
1 files changed, 6 insertions, 12 deletions
diff --git a/src/backend/utils/adt/xid.c b/src/backend/utils/adt/xid.c
index 6b617653b70..3a7d8bca5bd 100644
--- a/src/backend/utils/adt/xid.c
+++ b/src/backend/utils/adt/xid.c
@@ -41,13 +41,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);
}
/*
@@ -148,12 +145,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));
}
/*
@@ -165,7 +159,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);
}