Skip to content

Commit 9a6345e

Browse files
committed
pg_resetwal: Improve numeric command-line argument parsing
Check errno after strtoul()/strtol() to handle out of range errors better. For out of range, strtoul() returns ULONG_MAX, and the previous code would proceed with that result. Reported-by: Mark Dilger <mark.dilger@enterprisedb.com> Discussion: https://www.postgresql.org/message-id/flat/6a10a211-872b-3c4c-106b-909ae5fefa61%40enterprisedb.com
1 parent f1899f2 commit 9a6345e

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

src/bin/pg_resetwal/pg_resetwal.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,9 @@ main(int argc, char *argv[])
154154
break;
155155

156156
case 'e':
157+
errno = 0;
157158
set_xid_epoch = strtoul(optarg, &endptr, 0);
158-
if (endptr == optarg || *endptr != '\0')
159+
if (endptr == optarg || *endptr != '\0' || errno != 0)
159160
{
160161
/*------
161162
translator: the second %s is a command line argument (-e, etc) */
@@ -171,8 +172,9 @@ main(int argc, char *argv[])
171172
break;
172173

173174
case 'u':
175+
errno = 0;
174176
set_oldest_xid = strtoul(optarg, &endptr, 0);
175-
if (endptr == optarg || *endptr != '\0')
177+
if (endptr == optarg || *endptr != '\0' || errno != 0)
176178
{
177179
pg_log_error("invalid argument for option %s", "-u");
178180
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
@@ -186,8 +188,9 @@ main(int argc, char *argv[])
186188
break;
187189

188190
case 'x':
191+
errno = 0;
189192
set_xid = strtoul(optarg, &endptr, 0);
190-
if (endptr == optarg || *endptr != '\0')
193+
if (endptr == optarg || *endptr != '\0' || errno != 0)
191194
{
192195
pg_log_error("invalid argument for option %s", "-x");
193196
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
@@ -201,15 +204,16 @@ main(int argc, char *argv[])
201204
break;
202205

203206
case 'c':
207+
errno = 0;
204208
set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0);
205-
if (endptr == optarg || *endptr != ',')
209+
if (endptr == optarg || *endptr != ',' || errno != 0)
206210
{
207211
pg_log_error("invalid argument for option %s", "-c");
208212
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
209213
exit(1);
210214
}
211215
set_newest_commit_ts_xid = strtoul(endptr + 1, &endptr2, 0);
212-
if (endptr2 == endptr + 1 || *endptr2 != '\0')
216+
if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
213217
{
214218
pg_log_error("invalid argument for option %s", "-c");
215219
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
@@ -232,8 +236,9 @@ main(int argc, char *argv[])
232236
break;
233237

234238
case 'o':
239+
errno = 0;
235240
set_oid = strtoul(optarg, &endptr, 0);
236-
if (endptr == optarg || *endptr != '\0')
241+
if (endptr == optarg || *endptr != '\0' || errno != 0)
237242
{
238243
pg_log_error("invalid argument for option %s", "-o");
239244
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
@@ -247,16 +252,17 @@ main(int argc, char *argv[])
247252
break;
248253

249254
case 'm':
255+
errno = 0;
250256
set_mxid = strtoul(optarg, &endptr, 0);
251-
if (endptr == optarg || *endptr != ',')
257+
if (endptr == optarg || *endptr != ',' || errno != 0)
252258
{
253259
pg_log_error("invalid argument for option %s", "-m");
254260
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
255261
exit(1);
256262
}
257263

258264
set_oldestmxid = strtoul(endptr + 1, &endptr2, 0);
259-
if (endptr2 == endptr + 1 || *endptr2 != '\0')
265+
if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
260266
{
261267
pg_log_error("invalid argument for option %s", "-m");
262268
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
@@ -280,8 +286,9 @@ main(int argc, char *argv[])
280286
break;
281287

282288
case 'O':
289+
errno = 0;
283290
set_mxoff = strtoul(optarg, &endptr, 0);
284-
if (endptr == optarg || *endptr != '\0')
291+
if (endptr == optarg || *endptr != '\0' || errno != 0)
285292
{
286293
pg_log_error("invalid argument for option %s", "-O");
287294
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
@@ -310,8 +317,9 @@ main(int argc, char *argv[])
310317
break;
311318

312319
case 1:
320+
errno = 0;
313321
set_wal_segsize = strtol(optarg, &endptr, 10) * 1024 * 1024;
314-
if (endptr == optarg || *endptr != '\0')
322+
if (endptr == optarg || *endptr != '\0' || errno != 0)
315323
{
316324
pg_log_error("argument of --wal-segsize must be a number");
317325
exit(1);

0 commit comments

Comments
 (0)