diff --git a/src/scanscalar.cpp b/src/scanscalar.cpp index 2a7afa9..064c086 100644 --- a/src/scanscalar.cpp +++ b/src/scanscalar.cpp @@ -23,6 +23,7 @@ namespace YAML bool emptyLine = false, moreIndented = false; int foldedNewlineCount = 0; bool foldedNewlineStartedMoreIndented = false; + std::size_t lastEscapedChar = std::string::npos; std::string scalar; params.leadingSpaces = false; @@ -52,6 +53,7 @@ namespace YAML // eat escape character and get out (but preserve trailing whitespace!) INPUT.get(); lastNonWhitespaceChar = scalar.size(); + lastEscapedChar = scalar.size(); escapedNewline = true; break; } @@ -60,6 +62,7 @@ namespace YAML if(INPUT.peek() == params.escape) { scalar += Exp::Escape(INPUT); lastNonWhitespaceChar = scalar.size(); + lastEscapedChar = scalar.size(); continue; } @@ -171,20 +174,32 @@ namespace YAML // post-processing if(params.trimTrailingSpaces) { std::size_t pos = scalar.find_last_not_of(' '); + if(lastEscapedChar != std::string::npos) { + if(pos < lastEscapedChar || pos == std::string::npos) + pos = lastEscapedChar; + } if(pos < scalar.size()) scalar.erase(pos + 1); } switch(params.chomp) { case CLIP: { - const std::size_t pos = scalar.find_last_not_of('\n'); + std::size_t pos = scalar.find_last_not_of('\n'); + if(lastEscapedChar != std::string::npos) { + if(pos < lastEscapedChar || pos == std::string::npos) + pos = lastEscapedChar; + } if(pos == std::string::npos) scalar.erase(); else if(pos + 1 < scalar.size()) scalar.erase(pos + 2); } break; case STRIP: { - const std::size_t pos = scalar.find_last_not_of('\n'); + std::size_t pos = scalar.find_last_not_of('\n'); + if(lastEscapedChar != std::string::npos) { + if(pos < lastEscapedChar || pos == std::string::npos) + pos = lastEscapedChar; + } if(pos == std::string::npos) scalar.erase(); else if(pos < scalar.size()) diff --git a/test/old-api/parsertests.cpp b/test/old-api/parsertests.cpp index 3ef4195..7f80f98 100644 --- a/test/old-api/parsertests.cpp +++ b/test/old-api/parsertests.cpp @@ -892,6 +892,17 @@ namespace Test return doc.to() == 5; } + + bool QuotedNewline() + { + std::string input = "foo: \"\\n\""; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + return doc["foo"].to() == "\n"; + } } namespace { @@ -1172,6 +1183,7 @@ namespace Test RunParserTest(&Parser::NaN, "NaN", passed, total); RunParserTest(&Parser::NonConstKey, "non const key", passed, total); RunParserTest(&Parser::SingleChar, "single char", passed, total); + RunParserTest(&Parser::QuotedNewline, "quoted newline", passed, total); RunEncodingTest(&EncodeToUtf8, false, "UTF-8, no BOM", passed, total); RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total);