Commit fa0ee9c9 authored by Raphael Isemann's avatar Raphael Isemann

Fixed escaped quotes

parent 46474010
...@@ -2042,34 +2042,46 @@ Parses a string after opening quotes (\p ") where read. ...@@ -2042,34 +2042,46 @@ Parses a string after opening quotes (\p ") where read.
*/ */
std::string json::parser::parseString() std::string json::parser::parseString()
{ {
// get position of closing quotes // remember the position where the first character of the string was
auto quotepos_ = buffer_.find_first_of("\"", pos_); const auto startPos = pos_;
// true if and only if the amount of backslashes before the current
// if the closing quotes are escaped (character before the quotes is a // character is even
// backslash), we continue looking for the final quotes bool evenAmountOfBackslashes = true;
while (quotepos_ != std::string::npos and buffer_[quotepos_ - 1] == '\\')
{ // iterate with pos_ over the whole string
quotepos_ = buffer_.find_first_of("\"", quotepos_ + 1); for (;pos_ < buffer_.size(); pos_++) {
} char currentChar = buffer_[pos_];
// currentChar is a quote, so we might have found the end of the string
if (currentChar == '"') {
// but only if the amount of backslashes before that quote is even
if (evenAmountOfBackslashes) {
const auto stringLength = pos_ - startPos;
// set pos_ behind the trailing quote
pos_++;
// find next char to parse
next();
// return string inside the quotes
return buffer_.substr(startPos, stringLength);
}
}
// check if closing quotes were found // remember if we have a even amount of backslashes before the current character
if (quotepos_ == std::string::npos) if (currentChar == '\\') {
{ // jump between even/uneven for each backslash we encounter
error("expected '\"'"); evenAmountOfBackslashes = !evenAmountOfBackslashes;
} else {
// zero backslashes are also a even number, so as soon as we encounter a non-backslash
// the chain of backslashes breaks and we start again from zero
evenAmountOfBackslashes = true;
}
} }
// store the coordinates of the string for the later return value // we iterated over the whole string without finding a unescaped quote
const auto stringBegin = pos_; // so the given string is malformed
const auto stringLength = quotepos_ - pos_; error("expected '\"'");
// set buffer position to the position behind (+1) the closing quote
pos_ = quotepos_ + 1;
// read next character
next();
// return the string value
return buffer_.substr(stringBegin, stringLength);
} }
/*! /*!
......
...@@ -1621,6 +1621,7 @@ TEST_CASE("Parser") ...@@ -1621,6 +1621,7 @@ TEST_CASE("Parser")
// escape characters // escape characters
CHECK_THROWS_AS(json::parse("\"\\\""), std::invalid_argument); CHECK_THROWS_AS(json::parse("\"\\\""), std::invalid_argument);
CHECK_NOTHROW(json::parse("\"\\\"\"")); CHECK_NOTHROW(json::parse("\"\\\"\""));
CHECK_NOTHROW(json::parse("\"\\\\\""));
// quotes must be closed // quotes must be closed
CHECK_THROWS_AS(json::parse("\""), std::invalid_argument); CHECK_THROWS_AS(json::parse("\""), std::invalid_argument);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment