8000 Fix cidin() to handle values above 2^31 platform-independently. · skyline2012/postgres@2e51555 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2e51555

Browse files
committed
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>
1 parent 253e30c commit 2e51555

File tree

1 file changed

+6
-12
lines changed
  • src/backend/utils/adt

1 file changed

+6
-12
lines changed

src/backend/utils/adt/xid.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,10 @@ Datum
4040
xidout(PG_FUNCTION_ARGS)
4141
{
4242
TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
43+
char *result = (char *) palloc(16);
4344

44-
/* maximum 32 bit unsigned integer representation takes 10 chars */
45-
char *str = palloc(11);
46-
47-
snprintf(str, 11, "%lu", (unsigned long) transactionId);
48-
49-
PG_RETURN_CSTRING(str);
45+
snprintf(result, 16, "%lu", (unsigned long) transactionId);
46+
PG_RETURN_CSTRING(result);
5047
}
5148

5249
/*
@@ -132,12 +129,9 @@ xidComparator(const void *arg1, const void *arg2)
132129
Datum
133130
cidin(PG_FUNCTION_ARGS)
134131
{
135-
char *s = PG_GETARG_CSTRING(0);
136-
CommandId c;
137-
138-
c = atoi(s);
132+
char *str = PG_GETARG_CSTRING(0);
139133

140-
PG_RETURN_COMMANDID(c);
134+
PG_RETURN_COMMANDID((CommandId) strtoul(str, NULL, 0));
141135
}
142136

143137
/*
@@ -149,7 +143,7 @@ cidout(PG_FUNCTION_ARGS)
149143
CommandId c = PG_GETARG_COMMANDID(0);
150144
char *result = (char *) palloc(16);
151145

152-
snprintf(result, 16, "%u", (unsigned int) c);
146+
snprintf(result, 16, "%lu", (unsigned long) c);
153147
PG_RETURN_CSTRING(result);
154148
}
155149

0 commit comments

Comments
 (0)
0