From bab69b5df4e7c669df32f5d21fa084c2dcbad7d3 Mon Sep 17 00:00:00 2001 From: Trevor Robinson Date: Thu, 15 Mar 2018 22:37:54 -0500 Subject: [PATCH] Check for leading newlines when determining if block indentation indicator is needed (#404) * Check for leading newlines when determining if block indentation indicator is needed Fixes #403 * Perf: Swap order of checks for block indentation edge case --- lib/js-yaml/dumper.js | 10 ++++++++-- test/issues/0403.js | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 test/issues/0403.js diff --git a/lib/js-yaml/dumper.js b/lib/js-yaml/dumper.js index 025b1855..67cf6ca0 100644 --- a/lib/js-yaml/dumper.js +++ b/lib/js-yaml/dumper.js @@ -234,6 +234,12 @@ function isPlainSafeFirst(c) { && c !== CHAR_GRAVE_ACCENT; } +// Determines whether block indentation indicator is required. +function needIndentIndicator(string) { + var leadingSpaceRe = /^\n* /; + return leadingSpaceRe.test(string); +} + var STYLE_PLAIN = 1, STYLE_SINGLE = 2, STYLE_LITERAL = 3, @@ -301,7 +307,7 @@ function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, te ? STYLE_PLAIN : STYLE_SINGLE; } // Edge case: block indentation indicator can only have one digit. - if (string[0] === ' ' && indentPerLevel > 9) { + if (indentPerLevel > 9 && needIndentIndicator(string)) { return STYLE_DOUBLE; } // At this point we know block styles are valid. @@ -365,7 +371,7 @@ function writeScalar(state, string, level, iskey) { // Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. function blockHeader(string, indentPerLevel) { - var indentIndicator = (string[0] === ' ') ? String(indentPerLevel) : ''; + var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ''; // note the special case: the string '\n' counts as a "trailing" empty line. var clip = string[string.length - 1] === '\n'; diff --git a/test/issues/0403.js b/test/issues/0403.js new file mode 100644 index 00000000..43bc271c --- /dev/null +++ b/test/issues/0403.js @@ -0,0 +1,22 @@ +'use strict'; + + +var assert = require('assert'); +var yaml = require('../../'); + + +test('should properly dump leading newlines and spaces', function () { + var dump, src; + + src = { str: '\n a\nb' }; + dump = yaml.dump(src); + assert.deepEqual(yaml.safeLoad(dump), src); + + src = { str: '\n\n a\nb' }; + dump = yaml.dump(src); + assert.deepEqual(yaml.safeLoad(dump), src); + + src = { str: '\n a\nb' }; + dump = yaml.dump(src, { indent: 10 }); + assert.deepEqual(yaml.safeLoad(dump), src); +});