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:
Brian Fraser
2012-11-30 16:17:45 -03:00
parent b1e0aac38f
commit 76a010abee
4 changed files with 75 additions and 5 deletions

View File

@@ -2168,7 +2168,9 @@ sub parse_my_print_defaults {
my ($output) = @args{@required_args};
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;
@@ -2186,7 +2188,8 @@ sub parse_option_file {
die "Failed to parse the [mysqld] section" unless $mysqld_section;
my ($config, $dupes) = _parse_varvals(
map { $_ =~ m/^([^=]+)(?:=(.*))?$/ }
map { $_ =~ m/^([^=]+)(?:=(.*))?$/ ? ($1, $2) : () }
grep { $_ !~ m/^\s*$/ } # no empty lines
grep { $_ !~ m/^\s*#/ } # no # comment lines
split("\n", $mysqld_section)
);
@@ -2206,6 +2209,9 @@ sub _parse_varvals {
my $val; # value for current variable
ITEM:
foreach my $item ( @varvals ) {
if ( !defined($item) ) {
$item = '';
}
if ( $item ) {
$item =~ s/^\s+//;
$item =~ s/\s+$//;

View File

@@ -288,7 +288,9 @@ sub parse_my_print_defaults {
# Parse the "--var=val" lines.
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;
@@ -309,7 +311,8 @@ sub parse_option_file {
# Parse the "var=val" lines.
my ($config, $dupes) = _parse_varvals(
map { $_ =~ m/^([^=]+)(?:=(.*))?$/ }
map { $_ =~ m/^([^=]+)(?:=(.*))?$/ ? ($1, $2) : () }
grep { $_ !~ m/^\s*$/ } # no empty lines
grep { $_ !~ m/^\s*#/ } # no # comment lines
split("\n", $mysqld_section)
);
@@ -336,6 +339,11 @@ sub _parse_varvals {
my $val; # value for current variable
ITEM:
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 ) {
# Strip leading and trailing whitespace.
$item =~ s/^\s+//;

View File

@@ -9,7 +9,7 @@ BEGIN {
use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use Test::More tests => 30;
use Test::More;
use MySQLConfig;
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.
# #############################################################################
@@ -841,4 +865,5 @@ like(
'_d() works'
);
ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
done_testing;
exit;

View 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