Skip to content

Commit

Permalink
Merge pull request #521 from vcache/feature/dumper-spec-compilance
Browse files Browse the repository at this point in the history
dumper: don't quote strings with # without need
  • Loading branch information
Vitaly Puzrin authored Oct 21, 2019
2 parents 2fcb465 + 667b3a1 commit d9fe622
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
29 changes: 24 additions & 5 deletions lib/js-yaml/dumper.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ var _hasOwnProperty = Object.prototype.hasOwnProperty;

var CHAR_TAB = 0x09; /* Tab */
var CHAR_LINE_FEED = 0x0A; /* LF */
var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */
var CHAR_SPACE = 0x20; /* Space */
var CHAR_EXCLAMATION = 0x21; /* ! */
var CHAR_DOUBLE_QUOTE = 0x22; /* " */
Expand Down Expand Up @@ -189,8 +190,23 @@ function isPrintable(c) {
|| (0x10000 <= c && c <= 0x10FFFF);
}

// [34] ns-char ::= nb-char - s-white
// [27] nb-char ::= c-printable - b-char - c-byte-order-mark
// [26] b-char ::= b-line-feed | b-carriage-return
// [24] b-line-feed ::= #xA /* LF */
// [25] b-carriage-return ::= #xD /* CR */
// [3] c-byte-order-mark ::= #xFEFF
function isNsChar(c) {
return isPrintable(c) && !isWhitespace(c)
// byte-order-mark
&& c !== 0xFEFF
// b-char
&& c !== CHAR_CARRIAGE_RETURN
&& c !== CHAR_LINE_FEED;
}

// Simplified test for values allowed after the first character in plain style.
function isPlainSafe(c) {
function isPlainSafe(c, prev) {
// Uses a subset of nb-char - c-flow-indicator - ":" - "#"
// where nb-char ::= c-printable - b-char - c-byte-order-mark.
return isPrintable(c) && c !== 0xFEFF
Expand All @@ -201,8 +217,9 @@ function isPlainSafe(c) {
&& c !== CHAR_LEFT_CURLY_BRACKET
&& c !== CHAR_RIGHT_CURLY_BRACKET
// - ":" - "#"
// /* An ns-char preceding */ "#"
&& c !== CHAR_COLON
&& c !== CHAR_SHARP;
&& ((c !== CHAR_SHARP) || (prev && isNsChar(prev)));
}

// Simplified test for values allowed as the first character in plain style.
Expand Down Expand Up @@ -258,7 +275,7 @@ var STYLE_PLAIN = 1,
// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).
function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) {
var i;
var char;
var char, prev_char;
var hasLineBreak = false;
var hasFoldableLine = false; // only checked if shouldTrackWidth
var shouldTrackWidth = lineWidth !== -1;
Expand All @@ -274,7 +291,8 @@ function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, te
if (!isPrintable(char)) {
return STYLE_DOUBLE;
}
plain = plain && isPlainSafe(char);
prev_char = i > 0 ? string.charCodeAt(i - 1) : null;
plain = plain && isPlainSafe(char, prev_char);
}
} else {
// Case: block styles permitted.
Expand All @@ -293,7 +311,8 @@ function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, te
} else if (!isPrintable(char)) {
return STYLE_DOUBLE;
}
plain = plain && isPlainSafe(char);
prev_char = i > 0 ? string.charCodeAt(i - 1) : null;
plain = plain && isPlainSafe(char, prev_char);
}
// in case the end is missing a \n
hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&
Expand Down
23 changes: 23 additions & 0 deletions test/issues/0521.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';


var assert = require('assert');
var yaml = require('../../');
var readFileSync = require('fs').readFileSync;


test('Don\'t quote strings with # without need', function () {
var data = yaml.safeLoad(readFileSync(require('path').join(__dirname, '/0521.yml'), 'utf8'));

var sample = {
'http://example.com/page#anchor': 'no#quotes#required',
'parameter#fallback': 'quotes #required',
'foo #bar': 'key is quoted'
};

assert.deepEqual(
yaml.dump(sample),
yaml.dump(data)
);

});
3 changes: 3 additions & 0 deletions test/issues/0521.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
http://example.com/page#anchor: no#quotes#required
parameter#fallback: 'quotes #required'
'foo #bar': key is quoted

0 comments on commit d9fe622

Please sign in to comment.