Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yaml::parse() fails at double quoted multi line messages #11109

Closed
MalteWunsch opened this issue Jun 12, 2014 · 6 comments
Closed

Yaml::parse() fails at double quoted multi line messages #11109

MalteWunsch opened this issue Jun 12, 2014 · 6 comments

Comments

@MalteWunsch
Copy link
Contributor

The YAML specification has the following example for a multi line message in double quotes:

quoted: "So does this
  quoted scalar.\n"

Write that in a MultilineDoubleQuotedMessage.yml and try to Yaml::parse('MultilineDoubleQuotedMessage.yml') - Symfony will throw an exception like this:

Malformed inline YAML string ("So does this) in .../MultilineDoubleQuotedMessage.yml at line 1 (near "quoted: "So does this").

in .../symfony/symfony/src/Symfony/Component/Yaml/Inline.php at line 244
...

I tried that in Symfony 2.2.0 and 2.4.6, but the underlying issue seems to be the reg exp in https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Yaml/Inline.php#L246 , which lives on in Symfony 2.5.0.

A unit test in Symfony\Component\Yaml\Tests\YamlTest could look something like this:

public function testParseAcceptsMultilineDoubleQuotedMessage()
{
    $filename = __DIR__ . '/Fixtures/MultilineDoubleQuotedMessage.yml';
    $this->setExpectedException(null);
    Yaml::parse($filename);
}
@stof
Copy link
Member

stof commented Jun 12, 2014

I don't understand exactly what you mean when you talk about the different Symfony versions. Are 2.2.0 and 2.4.6 affected too, or is it only affecting 2.5.0 ?

@apfelbox
Copy link
Contributor

I read it as 2.2.0 and 2.4.6 are affected and the line is still included in 2.5.0

Actually the commit is 3ab9a6e, so if this line causes the error, it is included in 2.1.0 up to today.

@MalteWunsch
Copy link
Contributor Author

apfelbox is right: the line of code I'm pointing at is included from 2.1.0 up to 2.5.0. But I have only tested it in 2.2.0 and 2.4.6 - both versions are definitely affected.

@johnvh
Copy link

johnvh commented Jun 2, 2015

Using symfony/yaml 2.7.0, it looks like any multiline "flow" scalars fail. Double-quoted definitely fails, but so do plain, and single-quoted.

$ php -r '
require "vendor/autoload.php";
var_dump(\Symfony\Component\Yaml\Yaml::parse(<<<EOM
---
a: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ipsum justo,
  rhoncus non libero eget.
EOM
));
'

PHP Fatal error:  Uncaught exception 'Symfony\Component\Yaml\Exception\ParseException'
with message 'Unable to parse at line 3 (near "  rhoncus non libero eget.").' in
/Users/john/dev/symfony-yaml-test/vendor/symfony/yaml/Parser.php:285

This is pretty common is yaml land, and really hurts interop with other yaml libs. I've been running into this left and right trying to use symfony/yaml to load yaml files that were generate with ruby stdlib yaml (psych).

@alanevans
Copy link

Just want to add a couple of additional notes here.

  1. It is fairly easy to reproduce this issue if you generate YAML in ruby to be parsed by symfony. Ruby allows you to specify the length at which lines will wrap, and so you can set that really short to reproduce the bug, or you can set them really long in order to work around it (what I'm doing in practice to work around this issue is ensuring that the wrap length in ruby is longer than the length of any expected string so that it doesn't wrap). Example:
$ irb
2.1.2 :001 > require 'yaml'
 => true
2.1.2 :002 > obj = {a:1, b:"A really long string."}
 => {:a=>1, :b=>"A really long string."}
2.1.2 :003 > open('/tmp/testfile', 'w') { |f|
2.1.2 :004 >     f.write obj.to_yaml(line_width: 5)
2.1.2 :005?>   }
 => 40

The resulting file looks like this (though the details don't matter so much - just the line wrapping):

---
:a: 1
:b: A really
  long
  string.
  1. The very first example on this issue is a good test - it is accepted by the reference parser at http://ben-kiki.org/ypaste/ which is as close to an "official" version as we can get I'd think. This YAML string is currently not accepted by symfony YAML 2.8.7. I'm using the initial example like this to test:
<?php
require_once(__DIR__ . '/vendor/autoload.php');
$p = new Symfony\Component\Yaml\Parser();
$o = $p->parse('quoted: "So does this
  quoted scalar.\n"');
var_dump($o);

It's also equally possible to use my ruby example here as a test string - the reference parser is happy with it, symfony is not. This kind of string wrapping seems like a commonly used core feature of YAML, but possibly isn't encountered so often in configuration files where string tend to be short.

@xabbuh
Copy link
Member

xabbuh commented Jul 6, 2016

Please check out #19304 which should solve this issue.

xabbuh added a commit that referenced this issue Sep 20, 2016
This PR was submitted for the 2.7 branch but it was merged into the 3.2-dev branch instead (closes #19304).

Discussion
----------

[Yaml] fix parsing multi-line mapping values

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #11109
| License       | MIT
| Doc PR        |

Commits
-------

3954530 [Yaml] fix parsing multi-line mapping values
@xabbuh xabbuh closed this as completed Sep 20, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants