mirror of
https://github.com/nlohmann/json
synced 2024-11-24 04:40:13 +00:00
Merge pull request #18 from Teemperor/fix_quote_escaping
Fixed escaped quotes (issue #17)
This commit is contained in:
commit
661a44d156
62
src/json.cc
62
src/json.cc
@ -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
|
||||||
|
// character is even
|
||||||
|
bool evenAmountOfBackslashes = true;
|
||||||
|
|
||||||
// if the closing quotes are escaped (character before the quotes is a
|
// iterate with pos_ over the whole string
|
||||||
// backslash), we continue looking for the final quotes
|
for (;pos_ < buffer_.size(); pos_++) {
|
||||||
while (quotepos_ != std::string::npos and buffer_[quotepos_ - 1] == '\\')
|
char currentChar = buffer_[pos_];
|
||||||
{
|
|
||||||
quotepos_ = buffer_.find_first_of("\"", quotepos_ + 1);
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember if we have an even amount of backslashes before the current character
|
||||||
|
if (currentChar == '\\') {
|
||||||
|
// jump between even/uneven for each backslash we encounter
|
||||||
|
evenAmountOfBackslashes = !evenAmountOfBackslashes;
|
||||||
|
} else {
|
||||||
|
// zero backslashes are also an even number, so as soon as we encounter a non-backslash
|
||||||
|
// the chain of backslashes breaks and we start again from zero
|
||||||
|
evenAmountOfBackslashes = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if closing quotes were found
|
// we iterated over the whole string without finding a unescaped quote
|
||||||
if (quotepos_ == std::string::npos)
|
// so the given string is malformed
|
||||||
{
|
error("expected '\"'");
|
||||||
error("expected '\"'");
|
|
||||||
}
|
|
||||||
|
|
||||||
// store the coordinates of the string for the later return value
|
|
||||||
const auto stringBegin = pos_;
|
|
||||||
const auto stringLength = quotepos_ - pos_;
|
|
||||||
|
|
||||||
// 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")
|
|||||||
// 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);
|
||||||
|
Loading…
Reference in New Issue
Block a user