pg_amcheck: Fix block number parsing on command line
authorPeter Eisentraut <peter@eisentraut.org>
Fri, 20 Aug 2021 05:48:22 +0000 (07:48 +0200)
committerPeter Eisentraut <peter@eisentraut.org>
Fri, 20 Aug 2021 08:51:59 +0000 (10:51 +0200)
The previous code wouldn't handle higher block numbers on systems
where sizeof(long) == 4.

Reviewed-by: Mark Dilger <mark.dilger@enterprisedb.com>
Discussion: https://www.postgresql.org/message-id/flat/6a10a211-872b-3c4c-106b-909ae5fefa61%40enterprisedb.com

src/bin/pg_amcheck/pg_amcheck.c

index a86a1c098780b6b847bd31e31a0322b02361073d..af83d600abe745342cea7cf9bf63f4bcad6c2408 100644 (file)
@@ -298,6 +298,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;