It seems to me that when using the pg_amcheck --startblock and --endblock options on platforms where sizeof(long) == 4, you cannot specify higher block numbers (unless you do tricks with negative numbers). The attached patch should fix this by using strtoul() instead of strtol(). I also tightened up the number scanning a bit in other ways, similar to the code in other frontend utilities. I know some people have been working on tightening all this up. Please check that it's up to speed.
From d8bcc7cab6000acdaab69a81a57d7d6d41ae7bd5 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Thu, 22 Jul 2021 16:49:37 +0200
Subject: [PATCH] pg_amcheck: Fix block number parsing on command line

The previous code wouldn't handle higher block numbers on systems
where sizeof(long) == 4.
---
 src/bin/pg_amcheck/pg_amcheck.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/bin/pg_amcheck/pg_amcheck.c b/src/bin/pg_amcheck/pg_amcheck.c
index 4bde16fb4b..d18d38010d 100644
--- a/src/bin/pg_amcheck/pg_amcheck.c
+++ b/src/bin/pg_amcheck/pg_amcheck.c
@@ -297,6 +297,7 @@ main(int argc, char *argv[])
                                                        long_options, 
&optindex)) != -1)
        {
                char       *endptr;
+               unsigned long optval;
 
                switch (c)
                {
@@ -407,30 +408,34 @@ main(int argc, char *argv[])
                                }
                                break;
                        case 7:
-                               opts.startblock = strtol(optarg, &endptr, 10);
-                               if (*endptr != '\0')
+                               errno = 0;
+                               optval = strtoul(optarg, &endptr, 10);
+                               if (endptr == optarg || *endptr != '\0' || 
errno != 0)
                                {
                                        pg_log_error("invalid start block");
                                        exit(1);
                                }
-                               if (opts.startblock > MaxBlockNumber || 
opts.startblock < 0)
+                               if (optval > MaxBlockNumber)
                                {
                                        pg_log_error("start block out of 
bounds");
                                        exit(1);
                                }
+                               opts.startblock = optval;
                                break;
                        case 8:
-                               opts.endblock = strtol(optarg, &endptr, 10);
-                               if (*endptr != '\0')
+                               errno = 0;
+                               optval = strtoul(optarg, &endptr, 10);
+                               if (endptr == optarg || *endptr != '\0' || 
errno != 0)
                                {
                                        pg_log_error("invalid end block");
                                        exit(1);
                                }
-                               if (opts.endblock > MaxBlockNumber || 
opts.endblock < 0)
+                               if (optval > MaxBlockNumber)
                                {
                                        pg_log_error("end block out of bounds");
                                        exit(1);
                                }
+                               opts.endblock = optval;
                                break;
                        case 9:
                                opts.rootdescend = true;
-- 
2.32.0

Reply via email to