Skip Menu |

This queue is for tickets about the YAML-Tiny CPAN distribution.

Report information
The Basics
Id: 55181
Status: open
Priority: 0/
Queue: YAML-Tiny

People
Owner: Nobody in particular
Requestors: tokuhirom [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: do not skip empty line in "|+"
Date: Wed, 3 Mar 2010 22:46:18 +0900
To: bug-YAML-Tiny [...] rt.cpan.org
From: Tokuhiro Matsuno <tokuhirom [...] gmail.com>
The following test case is failed.I think YAML::Tiny should pass this test. -------------------------------------------------------------------------------- use strict; use warnings; use YAML (); use YAML::Tiny (); use Test::More tests => 1; my $x = <<'...'; --- baz: |+ yay yoh ... is_deeply(YAML::Tiny::Load($x), YAML::Load($x)); ------------------------------------------------------------------------------------ 1..1 not ok 1 # Failed test at hoge.pl line 15. # Structures begin differing at: # $got->{baz} = 'yay # yoh # ' # $expected->{baz} = 'yay # # yoh # ' # Looks like you failed 1 test of 1.
On Wed Mar 03 08:47:21 2010, tokuhirom@gmail.com wrote: Show quoted text
> The following test case is failed.I think YAML::Tiny should pass this > test. > >
-------------------------------------------------------------------------------- Show quoted text
> use strict; > use warnings; > use YAML (); > use YAML::Tiny (); > use Test::More tests => 1; > > my $x = <<'...'; > --- > baz: |+ > yay > > yoh > ... > > is_deeply(YAML::Tiny::Load($x), YAML::Load($x)); >
------------------------------------------------------------------------------------ Show quoted text
> 1..1 > not ok 1 > # Failed test at hoge.pl line 15. > # Structures begin differing at: > # $got->{baz} = 'yay > # yoh > # ' > # $expected->{baz} = 'yay > # > # yoh > # ' > # Looks like you failed 1 test of 1.
I ran into this today, it's not just |+ that has the problem, it affects any block scalar that has bare newlines in it. My suspicion is that the problem is actually in read_string, but i don't have time to dig further at the moment.
Subject: [rt.cpan.org #55181] PATCH to allow embedded empty lines
Date: Mon, 20 May 2013 14:14:04 -0500 (CDT)
To: bug-YAML-Tiny [...] rt.cpan.org
From: Aaron Hall <ahall [...] vitaphone.net>
read_string splits lines and discards any blank lines. The problem is that _read_hash and _read_array depend on that behavior, so they have to be fixed. Then _read_scalar has to know what to do with the blank lines. This patch keeps embedded blank lines inside block scalars. Once I fixed that, I realized that the fix would be out of spec (per YAML 1.1, 4.9.3 and the "Support for the chomping indicators on multi-line scalar styles is required" statement in YAML::Tiny(3)) for everything *but* `|+`, so I implemented the other indicators and added tests. I'm making it sound like I know a lot more about this than I actually do, so I could have gotten something wrong. I'm actually not 100% sure I'm reading the spec right w.r.t. trailing newlines vs. lack of trailing newlines, but everything passes the existing tests, and the other modules pass my added tests. Patch follows: -------- diff -ur YAML-Tiny-1.51/lib/YAML/Tiny.pm YAML-Tiny-1.51-ahall/lib/YAML/Tiny.pm --- YAML-Tiny-1.51/lib/YAML/Tiny.pm 2012-03-10 18:30:04.000000000 -0600 +++ YAML-Tiny-1.51-ahall/lib/YAML/Tiny.pm 2013-05-20 14:06:12.000000000 -0500 @@ -126,8 +126,8 @@ } # Split the file into lines - my @lines = grep { ! /^\s*(?:\#.*)?\z/ } - split /(?:\015{1,2}\012|\015|\012)/, $string; + my @lines = grep { ! /^\s*\#.*\z/ } + split /(?:\015{1,2}\012|\015|\012)/, $string; # Strip the initial YAML header @lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines; @@ -244,13 +244,24 @@ my @multiline = (); while ( @$lines ) { $lines->[0] =~ /^(\s*)/; - last unless length($1) >= $indent->[-1]; + + # Quit if we've hit a non-blank line with a shorter indent + last if (($lines->[0] ne '') && (length($1) < $indent->[-1])); + push @multiline, substr(shift(@$lines), length($1)); } - my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n"; - my $t = (substr($string, 1, 1) eq '-') ? '' : "\n"; - return join( $j, @multiline ) . $t; + # fold vs. literal + my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n"; + my $str = join( $j, @multiline ); + + # chomp indicator + my $ind = substr($string, 1, 1); + if ($ind eq '-') { $str =~ s/\n*\z//; } # strip + elsif ($ind eq '+') { $str .= "\n" } # keep + else { $str =~ s/\n*\z/\n/; } # clip + + return $str; } # Parse an array @@ -258,6 +269,12 @@ my ($self, $array, $indent, $lines) = @_; while ( @$lines ) { + # Gobble blank lines + if ( $lines->[0] =~ /^\s*\z/ ) { + shift @$lines; + next; + } + # Check for a new document if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) { while ( @$lines and $lines->[0] !~ /^---/ ) { @@ -334,6 +351,12 @@ my ($self, $hash, $indent, $lines) = @_; while ( @$lines ) { + # Gobble blank lines + if ( $lines->[0] =~ /^\s*\z/ ) { + shift @$lines; + next; + } + # Check for a new document if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) { while ( @$lines and $lines->[0] !~ /^---/ ) { @@ -383,6 +406,11 @@ $self->_read_hash( $hash->{$key}, [ @$indent, length($1) ], $lines ); } } + else { + # Blank line, treat it like the end of an indented block; + # the top of the loop will gobble the line + $hash->{$key} = undef; + } } } diff -ur YAML-Tiny-1.51/t/03_regression.t YAML-Tiny-1.51-ahall/t/03_regression.t --- YAML-Tiny-1.51/t/03_regression.t 2012-03-10 18:30:04.000000000 -0600 +++ YAML-Tiny-1.51-ahall/t/03_regression.t 2013-05-20 13:36:14.000000000 -0500 @@ -10,7 +10,7 @@ use File::Spec::Functions ':ALL'; use t::lib::Test; -use Test::More tests(37, 0, 13); +use Test::More tests(41, 0, 13); use YAML::Tiny qw{ Load Dump LoadFile DumpFile @@ -96,7 +96,63 @@ ); +# ... with embedded blank line +yaml_ok( <<'END_YAML', +--- +- | + foo + + bar +- 1 +END_YAML + [ [ "foo\n\nbar\n", 1 ] ], + 'block scalar with embedded empty line', +); + +# ... with embedded and trailing blank lines (keep) +yaml_ok( <<'END_YAML', +--- +- |+ + foo + + bar + +- 1 +END_YAML + [ [ "foo\n\nbar\n\n\n", 1 ] ], + 'block scalar keeps trailing blank line', +); + +# ... with embedded and trailing blank lines (clip) +yaml_ok( <<'END_YAML', +--- +- | + foo + + bar + + +- 1 +END_YAML + [ [ "foo\n\nbar\n", 1 ] ], + 'block scalar clips trailing blank lines', +); + +# ... with embedded and trailing blank lines (strip) +yaml_ok( <<'END_YAML', +--- +- |- + foo + + bar + + +- 1 +END_YAML + [ [ "foo\n\nbar", 1 ] ], + 'block scalar strips trailing newlines', +); #####################################################################
On Wed Mar 03 08:47:21 2010, tokuhirom@gmail.com wrote: Show quoted text
> The following test case is failed.I think YAML::Tiny should pass this > test. > > -------------------------------------------------------------------------------- > use strict; > use warnings; > use YAML (); > use YAML::Tiny (); > use Test::More tests => 1; > > my $x = <<'...'; > --- > baz: |+ > yay > > yoh > ... > > is_deeply(YAML::Tiny::Load($x), YAML::Load($x)); > ------------------------------------------------------------------------------------ > 1..1 > not ok 1 > # Failed test at hoge.pl line 15. > # Structures begin differing at: > # $got->{baz} = 'yay > # yoh > # ' > # $expected->{baz} = 'yay > # > # yoh > # ' > # Looks like you failed 1 test of 1.
This may be the same bug as reported in: https://rt.cpan.org/Ticket/Display.html?id=56045