mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-10-19 17:04:00 +00:00
Fix for 917770: Use of uninitialized value in substitution (s///) at pt-config-diff line 1996
This turned out to be two bugs mangled into one. First, _parse_varvals can deal with (var, undef), but not with (undef). This is a problem because two of the trhee spots that call _parse_varvals can return undef because of this: map { $_ =~ m/^([^=]+)(?:=(.*))?$/ } grep { $_ !~ m/^\s*#/ } # no # comment lines split("\n", $mysqld_section) The problem is twofold. First, we are not skipping empty or whitespace-only lines. That means that the map will fail, and pass an undef to _parse_varvals. So this ended up in a triple fix: Make _parse_varvals deal with a sole undef, skip empty/whitespace lines, and change that map to map { $_ =~ m/^([^=]+)(?:=(.*))?$/ ? ($1, $2) : () } so even if the regex fails in the future, no sole undef will be passed down the chain.
This commit is contained in:
@@ -2168,7 +2168,9 @@ sub parse_my_print_defaults {
|
|||||||
my ($output) = @args{@required_args};
|
my ($output) = @args{@required_args};
|
||||||
|
|
||||||
my ($config, $dupes) = _parse_varvals(
|
my ($config, $dupes) = _parse_varvals(
|
||||||
map { $_ =~ m/^--([^=]+)(?:=(.*))?$/ } split("\n", $output)
|
map { $_ =~ m/^--([^=]+)(?:=(.*))?$/ ? ($1, $2) : () }
|
||||||
|
grep { $_ !~ m/^\s*$/ } # no empty lines
|
||||||
|
split("\n", $output)
|
||||||
);
|
);
|
||||||
|
|
||||||
return $config, $dupes;
|
return $config, $dupes;
|
||||||
@@ -2186,7 +2188,8 @@ sub parse_option_file {
|
|||||||
die "Failed to parse the [mysqld] section" unless $mysqld_section;
|
die "Failed to parse the [mysqld] section" unless $mysqld_section;
|
||||||
|
|
||||||
my ($config, $dupes) = _parse_varvals(
|
my ($config, $dupes) = _parse_varvals(
|
||||||
map { $_ =~ m/^([^=]+)(?:=(.*))?$/ }
|
map { $_ =~ m/^([^=]+)(?:=(.*))?$/ ? ($1, $2) : () }
|
||||||
|
grep { $_ !~ m/^\s*$/ } # no empty lines
|
||||||
grep { $_ !~ m/^\s*#/ } # no # comment lines
|
grep { $_ !~ m/^\s*#/ } # no # comment lines
|
||||||
split("\n", $mysqld_section)
|
split("\n", $mysqld_section)
|
||||||
);
|
);
|
||||||
@@ -2206,6 +2209,9 @@ sub _parse_varvals {
|
|||||||
my $val; # value for current variable
|
my $val; # value for current variable
|
||||||
ITEM:
|
ITEM:
|
||||||
foreach my $item ( @varvals ) {
|
foreach my $item ( @varvals ) {
|
||||||
|
if ( !defined($item) ) {
|
||||||
|
$item = '';
|
||||||
|
}
|
||||||
if ( $item ) {
|
if ( $item ) {
|
||||||
$item =~ s/^\s+//;
|
$item =~ s/^\s+//;
|
||||||
$item =~ s/\s+$//;
|
$item =~ s/\s+$//;
|
||||||
|
@@ -288,7 +288,9 @@ sub parse_my_print_defaults {
|
|||||||
|
|
||||||
# Parse the "--var=val" lines.
|
# Parse the "--var=val" lines.
|
||||||
my ($config, $dupes) = _parse_varvals(
|
my ($config, $dupes) = _parse_varvals(
|
||||||
map { $_ =~ m/^--([^=]+)(?:=(.*))?$/ } split("\n", $output)
|
map { $_ =~ m/^--([^=]+)(?:=(.*))?$/ ? ($1, $2) : () }
|
||||||
|
grep { $_ !~ m/^\s*$/ } # no empty lines
|
||||||
|
split("\n", $output)
|
||||||
);
|
);
|
||||||
|
|
||||||
return $config, $dupes;
|
return $config, $dupes;
|
||||||
@@ -309,7 +311,8 @@ sub parse_option_file {
|
|||||||
|
|
||||||
# Parse the "var=val" lines.
|
# Parse the "var=val" lines.
|
||||||
my ($config, $dupes) = _parse_varvals(
|
my ($config, $dupes) = _parse_varvals(
|
||||||
map { $_ =~ m/^([^=]+)(?:=(.*))?$/ }
|
map { $_ =~ m/^([^=]+)(?:=(.*))?$/ ? ($1, $2) : () }
|
||||||
|
grep { $_ !~ m/^\s*$/ } # no empty lines
|
||||||
grep { $_ !~ m/^\s*#/ } # no # comment lines
|
grep { $_ !~ m/^\s*#/ } # no # comment lines
|
||||||
split("\n", $mysqld_section)
|
split("\n", $mysqld_section)
|
||||||
);
|
);
|
||||||
@@ -336,6 +339,11 @@ sub _parse_varvals {
|
|||||||
my $val; # value for current variable
|
my $val; # value for current variable
|
||||||
ITEM:
|
ITEM:
|
||||||
foreach my $item ( @varvals ) {
|
foreach my $item ( @varvals ) {
|
||||||
|
# We were passed an undef for the value, or we're dealing with an empty
|
||||||
|
# line
|
||||||
|
if ( !defined($item) ) {
|
||||||
|
$item = '';
|
||||||
|
}
|
||||||
if ( $item ) {
|
if ( $item ) {
|
||||||
# Strip leading and trailing whitespace.
|
# Strip leading and trailing whitespace.
|
||||||
$item =~ s/^\s+//;
|
$item =~ s/^\s+//;
|
||||||
|
@@ -9,7 +9,7 @@ BEGIN {
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
use English qw(-no_match_vars);
|
use English qw(-no_match_vars);
|
||||||
use Test::More tests => 30;
|
use Test::More;
|
||||||
|
|
||||||
use MySQLConfig;
|
use MySQLConfig;
|
||||||
use DSNParser;
|
use DSNParser;
|
||||||
@@ -827,6 +827,30 @@ SKIP: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# #############################################################################
|
||||||
|
# Use of uninitialized value in substitution (s///) at pt-config-diff line 1996
|
||||||
|
# https://bugs.launchpad.net/percona-toolkit/+bug/917770
|
||||||
|
# #############################################################################
|
||||||
|
|
||||||
|
$config = eval {
|
||||||
|
new MySQLConfig(
|
||||||
|
file => "$trunk/t/pt-config-diff/samples/bug_917770.cnf",
|
||||||
|
TextResultSetParser => $trp,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
is(
|
||||||
|
$EVAL_ERROR,
|
||||||
|
'',
|
||||||
|
"Bug 917770: Lives ok on lines with just spaces"
|
||||||
|
);
|
||||||
|
|
||||||
|
is(
|
||||||
|
$config->format(),
|
||||||
|
'option_file',
|
||||||
|
"Detect option_file type"
|
||||||
|
);
|
||||||
|
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
# Done.
|
# Done.
|
||||||
# #############################################################################
|
# #############################################################################
|
||||||
@@ -841,4 +865,5 @@ like(
|
|||||||
'_d() works'
|
'_d() works'
|
||||||
);
|
);
|
||||||
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
|
||||||
|
done_testing;
|
||||||
exit;
|
exit;
|
||||||
|
31
t/pt-config-diff/samples/bug_917770.cnf
Normal file
31
t/pt-config-diff/samples/bug_917770.cnf
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
[client]
|
||||||
|
user = msandbox
|
||||||
|
password = msandbox
|
||||||
|
port = PORT
|
||||||
|
socket = /tmp/PORT/mysql_sandboxPORT.sock
|
||||||
|
|
||||||
|
[mysqld]
|
||||||
|
port = PORTa
|
||||||
|
socket = /tmp/PORT/mysql_sandboxPORT.sock
|
||||||
|
pid-file = /tmp/PORT/data/mysql_sandboxPORT.pid
|
||||||
|
basedir = PERCONA_TOOLKIT_SANDBOX
|
||||||
|
datadir = /tmp/PORT/data
|
||||||
|
key_buffer_size = 16M
|
||||||
|
innodb_buffer_pool_size = 16M
|
||||||
|
innodb_data_home_dir = /tmp/PORT/data
|
||||||
|
innodb_log_group_home_dir = /tmp/PORT/data
|
||||||
|
innodb_data_file_path = ibdata1:10M:autoextend
|
||||||
|
innodb_log_file_size = 5M
|
||||||
|
log-bin = mysql-bin
|
||||||
|
relay_log = mysql-relay-bin
|
||||||
|
log_slave_updates
|
||||||
|
server-id = PORT
|
||||||
|
report-host = 127.0.0.1
|
||||||
|
report-port = PORT
|
||||||
|
log-error = /tmp/PORT/data/mysqld.log
|
||||||
|
innodb_lock_wait_timeout = 3
|
||||||
|
general_log
|
||||||
|
general_log_file = genlog
|
||||||
|
# These next two lines have a space in them, and trigger the bug
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user