Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the YAML CPAN distribution.

Report information
The Basics
Id: 2957
Status: resolved
Priority: 0/
Queue: YAML

People
Owner: Nobody in particular
Requestors: cpan [...] tinita.de
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.35
Fixed in: 1.20



Subject: Serializing array-elements with dashes
Array elements like "something - " aren't parsed correctly. Here's the shortest script I could reproduce it with: perl -wle' use YAML; print "VERSION: $YAML::VERSION"; my $x = [ { "test - " => 23 } ]; my $y = Dump $x; print $y; my $z = Load($y); ' VERSION: 0.35 --- #YAML:1.0 - 'test - ': 23 --- !perl/YAML::Error code: YAML_PARSE_ERR_SINGLE_LINE msg: Couldn't parse single line value line: 2 document: 1 ... at -e line 6
This bug still exists in version 0.66. However, it doesn't look like it's the hyphen causing the trouble, it's the quoted string. Any quoted string put in place of 'test - ' will cause the same problem. The YAML being generated by the original test is this: --- - 'test - ': 23 ...which fails when re-parsed. However, the equivalent: --- - 'test - ': 23 ...*does* parse correctly. Also, if I add on to the sequence, something like this: --- - fnord: 1 'test - ': 23 ...that parses correctly, too. So something about having the quoted string being on the very first line may be the cause. --Larry Gilbert On Tue Jul 15 09:46:39 2003, guest wrote: Show quoted text
> Array elements like "something - " aren't parsed > correctly.
The sample code I gave doesn't show up indented properly on rt.cpan.org. Let me try it this way... | --- | - 'test - ': 23 | | --- | - | 'test - ': 23 | | --- | - fnord: 1 | 'test - ': 23 --Larry Gilbert
Subject: [PATCH] Serializing array-elements with dashes
I got some good practice out of the Perl debugger on this one. I oughta use that more. :-) Serializing the example Perl code resulted in what YAML terminology calls "in-line nested mapping." The bug causes failure if and when the first (or only) line in an in-line nested mapping uses a quoted string for a key. Line 379 in YAML/Loader.pm (in the _parse_seq subroutine) appears to be the critical point where some markup on a "-" line is examined to see whether it's an in-line mapping: if ($self->preface =~ /^(\s*)(\w.*\:(?: |$).*)$/) {...} This doesn't catch the case where the key is a quoted string, so the wrong branch is taken and parsing falls apart. (In the case of a single-line nested mapping like the example submitted, it chokes with YAML_PARSE_ERR_SINGLE_LINE; if there is more than one line and the first line uses a quoted key, it chokes with YAML_PARSE_ERR_INCONSISTENT_INDENTATION.) I'm attaching a patch I made to fix this. It uses extra regexes to catch single- and double-quoted keys here. This may not be the best way to go about it, but it seems to resolve the bug. I also took the liberty of enabling the relevant test in t/bugs-rt.t (it passes). --Larry Gilbert
Index: YAML/t/bugs-rt.t =================================================================== --- YAML/t/bugs-rt.t (revision 5) +++ YAML/t/bugs-rt.t (working copy) @@ -1,4 +1,4 @@ -use t::TestYAML tests => 41; +use t::TestYAML tests => 42; run_yaml_tests; @@ -59,8 +59,10 @@ -=== Ticket #2957 Serializing array-elements with dashes -+++ skip_this_for_now +=== Ticket #2957 Serializing array-elements with dashes [sic] +(Actually, the real problem is not with hyphens but with spaces in the hash +key. This gets serialized as a quoted string, and the bug prevents the quoted +string from being parsed correctly.) +++ perl: [ { "test - " => 23 } ]; +++ yaml --- Index: YAML/lib/YAML/Loader.pm =================================================================== --- YAML/lib/YAML/Loader.pm (revision 5) +++ YAML/lib/YAML/Loader.pm (working copy) @@ -376,7 +376,15 @@ else { $self->die('YAML_LOAD_ERR_BAD_SEQ_ELEMENT'); } - if ($self->preface =~ /^(\s*)(\w.*\:(?: |$).*)$/) { + # Check whether the preface looks like a YAML mapping ("key: value"). + # This is complicated because it has to account for the possibility + # that a key is a quoted string, which itself may contain escaped + # quotes. + my $preface = $self->preface; + if ( $preface =~ /^ (\s*) ( \w .*? \: (?:\ |$).*) $/x or + $preface =~ /^ (\s*) ('\w .*? (?<!\\) ' \s* \: (?:\ |$).*) $/x or + $preface =~ /^ (\s*) ("\w .*? (?<!\\) " \s* \: (?:\ |$).*) $/x + ) { $self->indent($self->offset->[$self->level] + 2 + length($1)); $self->content($2); $self->level($self->level + 1);
P.S. I think this patch fixes bug #13510 as well. --Larry
Now I realize a problem with my own patch! I did not understand the difference in escaping within single quotes versus double quotes. Mea culpa. The regex to catch single quotes could be changed like so... /^ (\s*) ('\w .*? (?<!') ' \s* \: (?:\ |$).*) $/x But it would fail to catch cases like this: --- - '''this still breaks': 1 ... --- - 'so does this''': 1 ... I think it would be better to do some more sophisticated parsing here than use regexes. The patch makes things work better, just not 100%. --Larry Gilbert
Just sending here a "me too" - I am part of Debian's pkg-perl group, and we just got this report against our packaged version: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=489200 The bug submitter finds that serializing and de-serializing structures such as [{' a' => 1}] causes the "YAML_PARSE_ERR_SINGLE_LINE" error. Structures such as [' a',' b'] or as [{'a'=>1}] do work as expected.
This issue has been copied to: https://github.com/ingydotnet/yaml-pm/issues/36 please take all future correspondence there. This ticket will remain open but please do not reply here. This ticket will be closed when the github issue is dealt with.
fixed in 1.20