Skip Menu |

This queue is for tickets about the Config-General CPAN distribution.

Report information
The Basics
Id: 54580
Status: resolved
Priority: 0/
Queue: Config-General

People
Owner: tlinden [...] cpan.org
Requestors: TSHINNIC [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 2.44
Fixed in: (no value)



Subject: Many single quoted strings and -InterPolateVars causes value corruption
When there are many single-quoted strings in a config line, a problem sometimes corrupts the text, with one or more single-quoted strings replaced with text like "QUOTE279QUOTE". A config line like sheep_tale 'Mary' 'had' 'a' 'little' 'lamb' can sometimes be seen by a program as "'Mary' 'had' 'a' QUOTE999QUOTE 'lamb'" Depending on the number of lines in a config file which have multiple single-quoted strings, this may happen only infrequently. (If there is only one single-quoted string per line the problem will not happen.) Routine Config::General::Interpolated::_interpolate() uses a method of temporarily replacing single-quoted strings in order to avoid 'seeing' these when looking for ${var} during interpolation. At the end of the routine the replaced text segments are restored from a hash. However the method for generating the hash keys is able to accidentally *repeat* a key more than once, and then loses track of one or more single-quoted strings. These then don't get replaced and the weird placeholder texts remain in the value. The fix is to use a simple counter within the routine to generate keys as needed. That patch file is attached, along with a test file that demonstrates the problem before patching, and that the problem is fixed after patch applied. Please note that the patch also includes the rest of the suggested patch in a previous bug report. Old bug 46184 When -InterPolateEnv is enabled, -StrictVars is ignored suggested a patch that moved some code out of _interpolate() into _interpolate_hash(). Deleting the moved code from _interpolate() was missed. That was noticed while researching the present bug. This bug report is also related to the first problem mentioned in bug 51494, which had an alternate solution using split().
Subject: 90_RTxxxxx_interpolate_single_quotes.t
# This test relates to the first part of the following bug report # CPAN RT bug report #51494 # https://rt.cpan.org/Public/Bug/Display.html?id=51494 # which was separately discovered and noted my $debug_here = 0; use Test::More tests => 2; #use Test::More qw(no_plan); use Data::Dumper; BEGIN { use_ok "Config::General"}; #------------------------------------------------------------------ # Test handling of values containing *many* single-quoted strings # when -InterPolateVars option is set # - - - - - - - - - - - - - - # Create a test string value containing many single-quoted strings my $duplication_count = 2000; # $duplication_count = 100; # This produces a lot of different quoted strings with explicit ordering. # By using this input it becomes even more obvious what goes wrong. my $text_for_test; foreach my $counter ( reverse 1 .. $duplication_count ) { $text_for_test .= " 'luck${counter}'"; } # remove the extra leading space from test value, as C::G will strip # leading/trailing spaces on read, causing later mismatch on test $text_for_test =~ s{\A }{}; # Create the config source line: key plus value my $config_source_text = 'test_single_many ' . $text_for_test; diag qq{config_source_text: '$config_source_text'} if $debug_here > 1; # - - - - - - - - - - - - - - $cfgo = Config::General->new( -String => $config_source_text, -InterPolateVars => 1 ); %hash = $cfgo->getall; diag( Data::Dumper->Dump([ \%hash ], [qw{ *hash }]) ) if $debug_here > 1; $text_from_test = $hash{test_single_many}; is( $text_from_test, $text_for_test, "value with single-quote strings is as expected" ); if ( $debug_here ) { my @oops = $text_from_test =~ m{QUOTE\d+QUOTE}g; diag "Found @{[ scalar @oops ]} accidents"; } __END__ not ok 2 - value with single-quote strings is same # Failed test 'value with single-quote strings is same' # at t\80_interpolate.t line 56. # got: ''luck' 'luck' 'luck' QUOTE279QUOTE 'luck'' # expected: ''luck' 'luck' 'luck' 'luck' 'luck'' # Found 1 accidents # vim:ft=perl:ts=4:sw=4:et:is:hls:ss=10:
Subject: Interpolated.pm.RTxxxxx.patch
--- Interpolated.pm.original 2009-07-19 15:04:51.000000000 -0500 +++ Interpolated.pm 2010-02-12 20:57:26.343373600 -0600 @@ -65,6 +65,7 @@ # called directly by Config::General::_parse_value() # my ($this, $config, $key, $value) = @_; + my $quote_counter = 100; # some dirty trick to circumvent single quoted vars to be interpolated # we remove all quotes and replace them with unique random literals, @@ -72,7 +73,7 @@ # fixes bug rt#35766 my %quotes; $value =~ s/(\'[^\']+?\')/ - my $key = "QUOTE" . int(rand(1000)) . "QUOTE"; + my $key = "QUOTE" . ($quote_counter++) . "QUOTE"; $quotes{ $key } = $1; $key; /gex; @@ -85,23 +86,12 @@ if (exists $config->{__stack}->{$var_lc}) { $con . $config->{__stack}->{$var_lc}; } - elsif ($this->{InterPolateEnv}) { - # may lead to vulnerabilities, by default flag turned off - if (defined($ENV{$var})) { - $con . $ENV{$var}; - } - else { - $con; - } - } - else { - if ($this->{StrictVars}) { + elsif ($this->{StrictVars}) { croak "Use of uninitialized variable (\$$var) while loading config entry: $key = $value\n"; } - else { - # be cool - $con; - } + else { + # be cool + $con; } }egx;
fixed in 2.45. Thanks for the patch!