Fixed escaped quotes
Fixes #17 
Also added a test to prevent regressions.

{"label": "nlohmann:master", "ref": "master", "sha": "46474010307f209ddfb1454844f8b4432ffe6f11"}
Currently the parser assumes if a '\' is before a double quote, the double quote isn't the end of the string.

Note that there are more complicated cases like this (and their expansion) which need to be handled properly which probably will take more code to support properly: ("\\"", "\\") of arbitrary length. A reverse search which checks if the number of '\' preceding the quote is even or odd would do it: https://github.com/nlohmann/json/blob/master/src/json.cc#L2050

Performance in backslash-heavy strings may suffer a lot though. Might be better to do a pure forward scan of the string counting backslashes as you go (Lots of memory access, but it should all be prefetched + L1 cached by current x86, x64 CPUs).

Improper parsing of JSON string "\\"
diff --git a/src/json.cc b/src/json.cc
index e548366a3d..5cec2d09a9 100644
--- a/src/json.cc
+++ b/src/json.cc
@@ -2042,34 +2042,46 @@ Parses a string after opening quotes (\p ") where read.
 */
 std::string json::parser::parseString()
 {
-    // get position of closing quotes
-    auto quotepos_ = buffer_.find_first_of("\"", pos_);
-
-    // if the closing quotes are escaped (character before the quotes is a
-    // backslash), we continue looking for the final quotes
-    while (quotepos_ != std::string::npos and buffer_[quotepos_ - 1] == '\\')
-    {
-        quotepos_ = buffer_.find_first_of("\"", quotepos_ + 1);
-    }
+    // remember the position where the first character of the string was
+    const auto startPos = pos_;
+    // true if and only if the amount of backslashes before the current
+    // character is even
+    bool evenAmountOfBackslashes = true;
+
+    // iterate with pos_ over the whole string
+    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
-    if (quotepos_ == std::string::npos)
-    {
-        error("expected '\"'");
+        // 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;
+        }
     }
 
-    // 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);
+    // we iterated over the whole string without finding a unescaped quote
+    // so the given string is malformed
+    error("expected '\"'");
 }
 
 /*!

diff --git a/test/json_unit.cc b/test/json_unit.cc
index f820ffa892..7856bdd18f 100644
--- a/test/json_unit.cc
+++ b/test/json_unit.cc
@@ -1621,6 +1621,7 @@ TEST_CASE("Parser")
         // escape characters
         CHECK_THROWS_AS(json::parse("\"\\\""), std::invalid_argument);
         CHECK_NOTHROW(json::parse("\"\\\"\""));
+        CHECK_NOTHROW(json::parse("\"\\\\\""));
 
         // quotes must be closed
         CHECK_THROWS_AS(json::parse("\""), std::invalid_argument);

{"json_unit": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"json_unit": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"passed_count": 1, "failed_count": 0, "skipped_count": 0, "passed_tests": ["json_unit"], "failed_tests": [], "skipped_tests": []}
{"passed_count": 0, "failed_count": 0, "skipped_count": 0, "passed_tests": [], "failed_tests": [], "skipped_tests": []}
{"passed_count": 1, "failed_count": 0, "skipped_count": 0, "passed_tests": ["json_unit"], "failed_tests": [], "skipped_tests": []}