String value is escaped in an unwanted way
When updating a string value with forward slashes, the resulting string escapes the forward slashes unnecessarily:
final doc = YamlEditor('exampleKey: \${file(../../bar.yml)}');
doc.update(['exampleKey'], '\${file(../../foo.yml)}');
print(doc);
// exampleKey: ${file(..\/..\/bar.yml)}
My current workaround is to modify the resulting string:
doc.toString().replaceAll('\\/', '/')
It would be nice to customize that behaviour.
// exampleKey: ${file(..\/..\/bar.yml)}
Are you sure it's not double quoting it, as:
// exampleKey: "${file(..\/..\/bar.yml)}"
On topic, I'm guessing we could make the strings prettier. Contributions are welcome, but I think it would be best to have:
- Lots of test cases, and,
- Source code comments arguing why not escaping certain sequences is always safe.
Are you sure it's not double quoting it, as: // exampleKey: "${file(../../bar.yml)}"
Oh yeah, that's right. When skipping the { and } characters, everything worked as expected during experimentation, with no double quotes or escaping:
doc.update(['exampleKey'], '\$file(../../foo.yml)');
print(doc);
// exampleKey: $file(../../foo.yml)
So curly braces makes this function return true: https://github.com/dart-lang/yaml_edit/blob/4fadb43801b07f90b3f0c6065dbce4efc6d8d55e/lib/src/utils.dart#L15 and then that triggers escaping all code units in this map: https://github.com/dart-lang/yaml_edit/blob/4fadb43801b07f90b3f0c6065dbce4efc6d8d55e/lib/src/strings.dart#L286 But the forward slashes, in itself, does not trigger any character escaping.
I can make a PR if there is a consensus on the solution. Personally, I'd like to pass a parameter to skip all checks for dangerous strings and skip all character replacing somehow.
Hi, back again.
I'm trying to insert the following value in a map:
$ref: "#/components/schemas/fooObject"
using this snippet:
final specEditor = YamlEditor(asyncApiSpecText);
specEditor.update(
['some', 'path'],
{'\$ref': '#/components/schemas/fooObject'},
);
The result is:
some:
path:
$ref: "#\/components\/schemas\/fooObject"
Sorry if my comment is overkill. I just wanted to explain YamlEditor`'s logic leading to the escaped forward slashes.
Forward slashes must be escaped in YAML for JSON compatibility when strings are encoded as ScalarStyle.DOUBLE_QUOTED. See section linked
TLDR: YamlEditor is just trying to make sure it remains spec-compliant and package:yaml doesn't complain.
@Schwusch the leading # is not safe in ScalarStyle.PLAIN in YAML because of the preceding whitespace just after :. See here.
Your string would be considered a comment by the parser if inserted with the leading #. It defaults to ScalarStyle.DOUBLE_QUOTED to preserve your leading #.
# Your ref key would be null if parsed
some:
path:
$ref: #/components/schemas/fooObject
const asyncApiSpecText = r'''
some:
path:
$ref: #/components/schemas/fooObject
''';
print(loadYaml(asyncApiSpecText)); // {some: {path: {$ref: null}}}
If you omit the leading #, the string will be encoded without even being defaulted to ScalarStyle.DOUBLE_QUOTED.
final specEditor = YamlEditor(asyncApiSpecText);
specEditor.update(
['some', 'path'],
{'\$ref': '/components/schemas/fooObject'},
);
some:
path:
$ref: /components/schemas/fooObject