1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-05 07:21:24 +03:00

Improve range checks of options for pg_test_fsync and pg_test_timing

Both tools never had safeguard checks for the options provided, and it
was possible to make pg_test_fsync run an infinite amount of time or
pass down buggy values to pg_test_timing.

These behaviors have existed for a long time, with no actual complaints,
so no backpatch is done.  Basic TAP tests are introduced for both tools.

Author: Michael Paquier
Reviewed-by: Peter Eisentraut
Discussion: https://postgr.es/m/20200806062759.GE16470@paquier.xyz
This commit is contained in:
Michael Paquier
2020-09-28 10:13:59 +09:00
parent 41efb83408
commit 4d29e6dbd0
8 changed files with 121 additions and 24 deletions

View File

@ -1 +1,3 @@
/pg_test_fsync
/tmp_check/

View File

@ -22,6 +22,12 @@ install: all installdirs
installdirs:
$(MKDIR_P) '$(DESTDIR)$(bindir)'
check:
$(prove_check)
installcheck:
$(prove_installcheck)
uninstall:
rm -f '$(DESTDIR)$(bindir)/pg_test_fsync$(X)'

View File

@ -5,6 +5,7 @@
#include "postgres_fe.h"
#include <limits.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
@ -62,7 +63,7 @@ do { \
static const char *progname;
static int secs_per_test = 5;
static unsigned int secs_per_test = 5;
static int needs_unlink = 0;
static char full_buf[DEFAULT_XLOG_SEG_SIZE],
*buf,
@ -148,6 +149,8 @@ handle_args(int argc, char *argv[])
int option; /* Command line option */
int optindex = 0; /* used by getopt_long */
unsigned long optval; /* used for option parsing */
char *endptr;
if (argc > 1)
{
@ -173,7 +176,24 @@ handle_args(int argc, char *argv[])
break;
case 's':
secs_per_test = atoi(optarg);
errno = 0;
optval = strtoul(optarg, &endptr, 10);
if (endptr == optarg || *endptr != '\0' ||
errno != 0 || optval != (unsigned int) optval)
{
pg_log_error("invalid argument for option %s", "--secs-per-test");
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
}
secs_per_test = (unsigned int) optval;
if (secs_per_test == 0)
{
pg_log_error("%s must be in range %u..%u",
"--secs-per-test", 1, UINT_MAX);
exit(1);
}
break;
default:
@ -193,8 +213,8 @@ handle_args(int argc, char *argv[])
exit(1);
}
printf(ngettext("%d second per test\n",
"%d seconds per test\n",
printf(ngettext("%u second per test\n",
"%u seconds per test\n",
secs_per_test),
secs_per_test);
#if PG_O_DIRECT != 0

View File

@ -0,0 +1,25 @@
use strict;
use warnings;
use Config;
use TestLib;
use Test::More tests => 12;
#########################################
# Basic checks
program_help_ok('pg_test_fsync');
program_version_ok('pg_test_fsync');
program_options_handling_ok('pg_test_fsync');
#########################################
# Test invalid option combinations
command_fails_like(
[ 'pg_test_fsync', '--secs-per-test', 'a' ],
qr/\Qpg_test_fsync: error: invalid argument for option --secs-per-test\E/,
'pg_test_fsync: invalid argument for option --secs-per-test');
command_fails_like(
[ 'pg_test_fsync', '--secs-per-test', '0' ],
qr/\Qpg_test_fsync: error: --secs-per-test must be in range 1..4294967295\E/,
'pg_test_fsync: --secs-per-test must be in range');