v6-0001-pg_waldump-Allow-hexadecimal-values-for-t-timelin.patch

text/plain

Filename: v6-0001-pg_waldump-Allow-hexadecimal-values-for-t-timelin.patch
Type: text/plain
Part: 0
Message: Re: Timeline ID hexadecimal format

Patch

Format: format-patch
Series: patch v6-0001
Subject: pg_waldump: Allow hexadecimal values for -t/--timeline option
File+
doc/src/sgml/ref/pg_waldump.sgml 2 1
src/bin/pg_waldump/pg_waldump.c 33 4
From a19f9aea4fdeed473d490db6c79a5425bc2bcafd Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Mon, 20 Mar 2023 09:11:35 +0100
Subject: [PATCH v6] pg_waldump: Allow hexadecimal values for -t/--timeline
 option

Discussion: https://www.postgresql.org/message-id/flat/8fef346e-2541-76c3-d768-6536ae052993@lardiere.net
---
 doc/src/sgml/ref/pg_waldump.sgml |  3 ++-
 src/bin/pg_waldump/pg_waldump.c  | 37 ++++++++++++++++++++++++++++----
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/doc/src/sgml/ref/pg_waldump.sgml b/doc/src/sgml/ref/pg_waldump.sgml
index 343f0482a9..7685d3d15b 100644
--- a/doc/src/sgml/ref/pg_waldump.sgml
+++ b/doc/src/sgml/ref/pg_waldump.sgml
@@ -215,7 +215,8 @@ <title>Options</title>
        <para>
         Timeline from which to read WAL records. The default is to use the
         value in <replaceable>startseg</replaceable>, if that is specified; otherwise, the
-        default is 1.
+        default is 1.  The value can be specified in decimal or hexadecimal,
+        for example <literal>17</literal> or <literal>0x11</literal>.
        </para>
       </listitem>
      </varlistentry>
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 44b5c8726e..8630000ef0 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;

base-commit: 0b51d423e974557e821d890c0a3a49e419a19caa
-- 
2.39.2