aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_waldump/pg_waldump.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 44b5c8726e6..8630000ef0b 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -13,6 +13,7 @@
#include "postgres.h"
#include <dirent.h>
+#include <limits.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -1007,12 +1008,40 @@ main(int argc, char **argv)
private.startptr = (uint64) xlogid << 32 | xrecoff;
break;
case 't':
- if (sscanf(optarg, "%u", &private.timeline) != 1)
+
+ /*
+ * This is like option_parse_int() but needs to handle
+ * unsigned 32-bit int. Also, we accept both decimal and
+ * hexadecimal specifications here.
+ */
{
- pg_log_error("invalid timeline specification: \"%s\"", optarg);
- goto bad_argument;
+ char *endptr;
+ unsigned long val;
+
+ errno = 0;
+ val = strtoul(optarg, &endptr, 0);
+
+ while (*endptr != '\0' && isspace((unsigned char) *endptr))
+ endptr++;
+
+ if (*endptr != '\0')
+ {
+ pg_log_error("invalid value \"%s\" for option %s",
+ optarg, "-t/--timeline");
+ goto bad_argument;
+ }
+
+ if (errno == ERANGE || val < 1 || val > UINT_MAX)
+ {
+ pg_log_error("%s must be in range %u..%u",
+ "-t/--timeline", 1, UINT_MAX);
+ goto bad_argument;
+ }
+
+ private.timeline = val;
+
+ break;
}
- break;
case 'w':
config.filter_by_fpw = true;
break;