Skip to content

Commit dbfa175

Browse files
author
Alexander Korotkov
committed
Fix reading 64-bit xids from string.
1 parent 8ed0428 commit dbfa175

File tree

4 files changed

+43
-15
lines changed

4 files changed

+43
-15
lines changed

src/backend/access/transam/twophase.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,7 +1703,7 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
17031703
TransactionId *subxids;
17041704
int i;
17051705

1706-
xid = (TransactionId) strtoul(clde->d_name, NULL, 16);
1706+
xid = (TransactionId) pg_strtouint64(clde->d_name, NULL, 16);
17071707

17081708
/* Reject XID if too new */
17091709
if (TransactionIdFollowsOrEquals(xid, origNextXid))
@@ -1839,7 +1839,7 @@ StandbyRecoverPreparedTransactions(bool overwriteOK)
18391839
TransactionId *subxids;
18401840
int i;
18411841

1842-
xid = (TransactionId) strtoul(clde->d_name, NULL, 16);
1842+
xid = (TransactionId) pg_strtouint64(clde->d_name, NULL, 16);
18431843

18441844
/* Already processed? */
18451845
if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid))
@@ -1927,7 +1927,7 @@ RecoverPreparedTransactions(void)
19271927
const char *gid;
19281928
int i;
19291929

1930-
xid = (TransactionId) strtoul(clde->d_name, NULL, 16);
1930+
xid = (TransactionId) pg_strtouint64(clde->d_name, NULL, 16);
19311931

19321932
/* Already processed? */
19331933
if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid))

src/backend/access/transam/xlog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5042,7 +5042,7 @@ readRecoveryCommandFile(void)
50425042
else if (strcmp(item->name, "recovery_target_xid") == 0)
50435043
{
50445044
errno = 0;
5045-
recoveryTargetXid = (TransactionId) strtoul(item->value, NULL, 0);
5045+
recoveryTargetXid = (TransactionId) pg_strtouint64(item->value, NULL, 0);
50465046
if (errno == EINVAL || errno == ERANGE)
50475047
ereport(FATAL,
50485048
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),

src/backend/utils/adt/xid.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@ xidin(PG_FUNCTION_ARGS)
3131
{
3232
char *str = PG_GETARG_CSTRING(0);
3333

34-
PG_RETURN_TRANSACTIONID((TransactionId) strtoul(str, NULL, 0));
34+
PG_RETURN_TRANSACTIONID((TransactionId) pg_strtouint64(str, NULL, 0));
3535
}
3636

3737
Datum
3838
xidout(PG_FUNCTION_ARGS)
3939
{
4040
TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
41-
char *result = (char *) palloc(16);
41+
char *result = (char *) palloc(32);
4242

43-
snprintf(result, 16, "%lu", (unsigned long) transactionId);
43+
snprintf(result, 32, XID_FMT, transactionId);
4444
PG_RETURN_CSTRING(result);
4545
}
4646

@@ -51,8 +51,12 @@ Datum
5151
xidrecv(PG_FUNCTION_ARGS)
5252
{
5353
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
54+
uint32 lo, hi;
55+
56+
lo = (uint32) pq_getmsgint(buf, sizeof(TransactionId));
57+
hi = (uint32) pq_getmsgint(buf, sizeof(TransactionId));
5458

55-
PG_RETURN_TRANSACTIONID((TransactionId) pq_getmsgint(buf, sizeof(TransactionId)));
59+
PG_RETURN_TRANSACTIONID((uint64) lo + ((uint64) hi << 32));
5660
}
5761

5862
/*
@@ -63,9 +67,14 @@ xidsend(PG_FUNCTION_ARGS)
6367
{
6468
TransactionId arg1 = PG_GETARG_TRANSACTIONID(0);
6569
StringInfoData buf;
70+
uint32 lo, hi;
71+
72+
lo = (uint32) (arg1 & 0xFFFFFFFF);
73+
hi = (uint32) (arg1 >> 32);
6674

6775
pq_begintypsend(&buf);
68-
pq_sendint(&buf, arg1, sizeof(arg1));
76+
pq_sendint(&buf, lo, sizeof(lo));
77+
pq_sendint(&buf, hi, sizeof(hi));
6978
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
7079
}
7180

src/bin/pg_resetxlog/pg_resetxlog.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static void KillExistingXLOG(void);
8181
static void KillExistingArchiveStatus(void);
8282
static void WriteEmptyXLOG(void);
8383
static void usage(void);
84+
static uint64 str2uint64(const char *str, char **endptr, int base);
8485

8586

8687
int
@@ -131,7 +132,7 @@ main(int argc, char *argv[])
131132
break;
132133

133134
case 'x':
134-
set_xid = strtoul(optarg, &endptr, 0);
135+
set_xid = str2uint64(optarg, &endptr, 0);
135136
if (endptr == optarg || *endptr != '\0')
136137
{
137138
fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-x");
@@ -146,14 +147,14 @@ main(int argc, char *argv[])
146147
break;
147148

148149
case 'c':
149-
set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0);
150+
set_oldest_commit_ts_xid = str2uint64(optarg, &endptr, 0);
150151
if (endptr == optarg || *endptr != ',')
151152
{
152153
fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-c");
153154
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
154155
exit(1);
155156
}
156-
set_newest_commit_ts_xid = strtoul(endptr + 1, &endptr2, 0);
157+
set_newest_commit_ts_xid = str2uint64(endptr + 1, &endptr2, 0);
157158
if (endptr2 == endptr + 1 || *endptr2 != '\0')
158159
{
159160
fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-c");
@@ -192,15 +193,15 @@ main(int argc, char *argv[])
192193
break;
193194

194195
case 'm':
195-
set_mxid = strtoul(optarg, &endptr, 0);
196+
set_mxid = str2uint64(optarg, &endptr, 0);
196197
if (endptr == optarg || *endptr != ',')
197198
{
198199
fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-m");
199200
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
200201
exit(1);
201202
}
202203

203-
set_oldestmxid = strtoul(endptr + 1, &endptr2, 0);
204+
set_oldestmxid = str2uint64(endptr + 1, &endptr2, 0);
204205
if (endptr2 == endptr + 1 || *endptr2 != '\0')
205206
{
206207
fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-m");
@@ -226,7 +227,7 @@ main(int argc, char *argv[])
226227
break;
227228

228229
case 'O':
229-
set_mxoff = strtoul(optarg, &endptr, 0);
230+
set_mxoff = str2uint64(optarg, &endptr, 0);
230231
if (endptr == optarg || *endptr != '\0')
231232
{
232233
fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-O");
@@ -1148,3 +1149,21 @@ usage(void)
11481149
printf(_(" -?, --help show this help, then exit\n"));
11491150
printf(_("\nReport bugs to <" PACKAGE_BUGREPORT ">.\n"));
11501151
}
1152+
1153+
1154+
/*
1155+
* str2uint64()
1156+
*
1157+
* convert string to 64-bit unsigned int
1158+
*/
1159+
static uint64
1160+
str2uint64(const char *str, char **endptr, int base)
1161+
{
1162+
#ifdef _MSC_VER /* MSVC only */
1163+
return _strtoui64(str, endptr, base);
1164+
#elif defined(HAVE_STRTOULL) && SIZEOF_LONG < 8
1165+
return strtoull(str, endptr, base);
1166+
#else
1167+
return strtoul(str, endptr, base);
1168+
#endif
1169+
}

0 commit comments

Comments
 (0)