diff --git a/src/json.hpp b/src/json.hpp
index fc0562e8..dfd7bb70 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -3631,7 +3631,7 @@ class basic_json
                 static const unsigned char yybm[] =
                 {
                     0,  64,  64,  64,  64,  64,  64,  64,
-                    64,  96,  96,  64,  64,  96,  64,  64,
+                    64,  32,  32,  64,  64,  32,  64,  64,
                     64,  64,  64,  64,  64,  64,  64,  64,
                     64,  64,  64,  64,  64,  64,  64,  64,
                     96,  64,   0,  64,  64,  64,  64,  64,
@@ -3914,11 +3914,26 @@ basic_json_parser_25:
 basic_json_parser_26:
                 yyaccept = 0;
                 yych = *(m_marker = ++m_cursor);
-                if (yych <= 0x00)
+                if (yych <= '\n')
                 {
+                    if (yych <= 0x00)
+                    {
+                        goto basic_json_parser_19;
+                    }
+                    if (yych <= 0x08)
+                    {
+                        goto basic_json_parser_31;
+                    }
                     goto basic_json_parser_19;
                 }
-                goto basic_json_parser_31;
+                else
+                {
+                    if (yych == '\r')
+                    {
+                        goto basic_json_parser_19;
+                    }
+                    goto basic_json_parser_31;
+                }
 basic_json_parser_27:
                 ++m_cursor;
                 {
@@ -3939,7 +3954,7 @@ basic_json_parser_31:
                 {
                     goto basic_json_parser_30;
                 }
-                if (yych <= 0x00)
+                if (yych <= '\r')
                 {
                     goto basic_json_parser_32;
                 }
@@ -4395,7 +4410,7 @@ basic_json_parser_59:
             m_buffer.erase(0, static_cast<size_t>(offset_start));
             std::string line;
             std::getline(*m_stream, line);
-            m_buffer += line;
+            m_buffer += "\n" + line; // add line with newline symbol
 
             m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
             m_start  = m_content;
@@ -4641,6 +4656,9 @@ basic_json_parser_59:
                         return result;
                     }
 
+                    // no comma is expected here
+                    unexpect(lexer::token_type::value_separator);
+
                     // otherwise: parse key-value pairs
                     do
                     {
@@ -4707,6 +4725,9 @@ basic_json_parser_59:
                         return result;
                     }
 
+                    // no comma is expected here
+                    unexpect(lexer::token_type::value_separator);
+
                     // otherwise: parse values
                     do
                     {
@@ -4796,11 +4817,8 @@ basic_json_parser_59:
 
                 default:
                 {
-                    std::string error_msg = "parse error - unexpected \'";
-                    error_msg += m_lexer.get_token();
-                    error_msg += "\' (";
-                    error_msg += lexer::token_type_name(last_token) + ")";
-                    throw std::invalid_argument(error_msg);
+                    // the last token was unexpected
+                    unexpect(last_token);
                 }
             }
 
@@ -4830,6 +4848,18 @@ basic_json_parser_59:
             }
         }
 
+        inline void unexpect(typename lexer::token_type t) const
+        {
+            if (t == last_token)
+            {
+                std::string error_msg = "parse error - unexpected \'";
+                error_msg += m_lexer.get_token();
+                error_msg += "\' (";
+                error_msg += lexer::token_type_name(last_token) + ")";
+                throw std::invalid_argument(error_msg);
+            }
+        }
+
       private:
         /// levels of recursion
         int depth = 0;
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 1ed2af2f..51622f5a 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -3669,7 +3669,7 @@ class basic_json
                 // string
                 quotation_mark  = [\"];
                 escape          = [\\];
-                unescaped       = [^\"\\\000];
+                unescaped       = [^\"\\\000\t\n\r];
                 single_escaped  = [\"\\/bfnrt];
                 unicode_escaped = [u][0-9a-fA-F]{4};
                 escaped         = escape (single_escaped | unicode_escaped);
@@ -3701,7 +3701,7 @@ class basic_json
             m_buffer.erase(0, static_cast<size_t>(offset_start));
             std::string line;
             std::getline(*m_stream, line);
-            m_buffer += line;
+            m_buffer += "\n" + line; // add line with newline symbol
 
             m_content = reinterpret_cast<const lexer_char_t*>(m_buffer.c_str());
             m_start  = m_content;
@@ -3947,6 +3947,9 @@ class basic_json
                         return result;
                     }
 
+                    // no comma is expected here
+                    unexpect(lexer::token_type::value_separator);
+
                     // otherwise: parse key-value pairs
                     do
                     {
@@ -4013,6 +4016,9 @@ class basic_json
                         return result;
                     }
 
+                    // no comma is expected here
+                    unexpect(lexer::token_type::value_separator);
+
                     // otherwise: parse values
                     do
                     {
@@ -4102,11 +4108,8 @@ class basic_json
 
                 default:
                 {
-                    std::string error_msg = "parse error - unexpected \'";
-                    error_msg += m_lexer.get_token();
-                    error_msg += "\' (";
-                    error_msg += lexer::token_type_name(last_token) + ")";
-                    throw std::invalid_argument(error_msg);
+                    // the last token was unexpected
+                    unexpect(last_token);
                 }
             }
 
@@ -4136,6 +4139,18 @@ class basic_json
             }
         }
 
+        inline void unexpect(typename lexer::token_type t) const
+        {
+            if (t == last_token)
+            {
+                std::string error_msg = "parse error - unexpected \'";
+                error_msg += m_lexer.get_token();
+                error_msg += "\' (";
+                error_msg += lexer::token_type_name(last_token) + ")";
+                throw std::invalid_argument(error_msg);
+            }
+        }
+
       private:
         /// levels of recursion
         int depth = 0;
diff --git a/test/json_tests/fail1.json b/test/json_tests/fail1.json
new file mode 100644
index 00000000..6216b865
--- /dev/null
+++ b/test/json_tests/fail1.json
@@ -0,0 +1 @@
+"A JSON payload should be an object or array, not a string."
\ No newline at end of file
diff --git a/test/json_tests/fail10.json b/test/json_tests/fail10.json
new file mode 100644
index 00000000..5d8c0047
--- /dev/null
+++ b/test/json_tests/fail10.json
@@ -0,0 +1 @@
+{"Extra value after close": true} "misplaced quoted value"
\ No newline at end of file
diff --git a/test/json_tests/fail11.json b/test/json_tests/fail11.json
new file mode 100644
index 00000000..76eb95b4
--- /dev/null
+++ b/test/json_tests/fail11.json
@@ -0,0 +1 @@
+{"Illegal expression": 1 + 2}
\ No newline at end of file
diff --git a/test/json_tests/fail12.json b/test/json_tests/fail12.json
new file mode 100644
index 00000000..77580a45
--- /dev/null
+++ b/test/json_tests/fail12.json
@@ -0,0 +1 @@
+{"Illegal invocation": alert()}
\ No newline at end of file
diff --git a/test/json_tests/fail13.json b/test/json_tests/fail13.json
new file mode 100644
index 00000000..379406b5
--- /dev/null
+++ b/test/json_tests/fail13.json
@@ -0,0 +1 @@
+{"Numbers cannot have leading zeroes": 013}
\ No newline at end of file
diff --git a/test/json_tests/fail14.json b/test/json_tests/fail14.json
new file mode 100644
index 00000000..0ed366b3
--- /dev/null
+++ b/test/json_tests/fail14.json
@@ -0,0 +1 @@
+{"Numbers cannot be hex": 0x14}
\ No newline at end of file
diff --git a/test/json_tests/fail15.json b/test/json_tests/fail15.json
new file mode 100644
index 00000000..fc8376b6
--- /dev/null
+++ b/test/json_tests/fail15.json
@@ -0,0 +1 @@
+["Illegal backslash escape: \x15"]
\ No newline at end of file
diff --git a/test/json_tests/fail16.json b/test/json_tests/fail16.json
new file mode 100644
index 00000000..3fe21d4b
--- /dev/null
+++ b/test/json_tests/fail16.json
@@ -0,0 +1 @@
+[\naked]
\ No newline at end of file
diff --git a/test/json_tests/fail17.json b/test/json_tests/fail17.json
new file mode 100644
index 00000000..62b9214a
--- /dev/null
+++ b/test/json_tests/fail17.json
@@ -0,0 +1 @@
+["Illegal backslash escape: \017"]
\ No newline at end of file
diff --git a/test/json_tests/fail18.json b/test/json_tests/fail18.json
new file mode 100644
index 00000000..edac9271
--- /dev/null
+++ b/test/json_tests/fail18.json
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
\ No newline at end of file
diff --git a/test/json_tests/fail19.json b/test/json_tests/fail19.json
new file mode 100644
index 00000000..3b9c46fa
--- /dev/null
+++ b/test/json_tests/fail19.json
@@ -0,0 +1 @@
+{"Missing colon" null}
\ No newline at end of file
diff --git a/test/json_tests/fail2.json b/test/json_tests/fail2.json
new file mode 100644
index 00000000..6b7c11e5
--- /dev/null
+++ b/test/json_tests/fail2.json
@@ -0,0 +1 @@
+["Unclosed array"
\ No newline at end of file
diff --git a/test/json_tests/fail20.json b/test/json_tests/fail20.json
new file mode 100644
index 00000000..27c1af3e
--- /dev/null
+++ b/test/json_tests/fail20.json
@@ -0,0 +1 @@
+{"Double colon":: null}
\ No newline at end of file
diff --git a/test/json_tests/fail21.json b/test/json_tests/fail21.json
new file mode 100644
index 00000000..62474573
--- /dev/null
+++ b/test/json_tests/fail21.json
@@ -0,0 +1 @@
+{"Comma instead of colon", null}
\ No newline at end of file
diff --git a/test/json_tests/fail22.json b/test/json_tests/fail22.json
new file mode 100644
index 00000000..a7752581
--- /dev/null
+++ b/test/json_tests/fail22.json
@@ -0,0 +1 @@
+["Colon instead of comma": false]
\ No newline at end of file
diff --git a/test/json_tests/fail23.json b/test/json_tests/fail23.json
new file mode 100644
index 00000000..494add1c
--- /dev/null
+++ b/test/json_tests/fail23.json
@@ -0,0 +1 @@
+["Bad value", truth]
\ No newline at end of file
diff --git a/test/json_tests/fail24.json b/test/json_tests/fail24.json
new file mode 100644
index 00000000..caff239b
--- /dev/null
+++ b/test/json_tests/fail24.json
@@ -0,0 +1 @@
+['single quote']
\ No newline at end of file
diff --git a/test/json_tests/fail25.json b/test/json_tests/fail25.json
new file mode 100644
index 00000000..8b7ad23e
--- /dev/null
+++ b/test/json_tests/fail25.json
@@ -0,0 +1 @@
+["	tab	character	in	string	"]
\ No newline at end of file
diff --git a/test/json_tests/fail26.json b/test/json_tests/fail26.json
new file mode 100644
index 00000000..845d26a6
--- /dev/null
+++ b/test/json_tests/fail26.json
@@ -0,0 +1 @@
+["tab\   character\   in\  string\  "]
\ No newline at end of file
diff --git a/test/json_tests/fail27.json b/test/json_tests/fail27.json
new file mode 100644
index 00000000..6b01a2ca
--- /dev/null
+++ b/test/json_tests/fail27.json
@@ -0,0 +1,2 @@
+["line
+break"]
\ No newline at end of file
diff --git a/test/json_tests/fail28.json b/test/json_tests/fail28.json
new file mode 100644
index 00000000..621a0101
--- /dev/null
+++ b/test/json_tests/fail28.json
@@ -0,0 +1,2 @@
+["line\
+break"]
\ No newline at end of file
diff --git a/test/json_tests/fail29.json b/test/json_tests/fail29.json
new file mode 100644
index 00000000..47ec421b
--- /dev/null
+++ b/test/json_tests/fail29.json
@@ -0,0 +1 @@
+[0e]
\ No newline at end of file
diff --git a/test/json_tests/fail3.json b/test/json_tests/fail3.json
new file mode 100644
index 00000000..168c81eb
--- /dev/null
+++ b/test/json_tests/fail3.json
@@ -0,0 +1 @@
+{unquoted_key: "keys must be quoted"}
\ No newline at end of file
diff --git a/test/json_tests/fail30.json b/test/json_tests/fail30.json
new file mode 100644
index 00000000..8ab0bc4b
--- /dev/null
+++ b/test/json_tests/fail30.json
@@ -0,0 +1 @@
+[0e+]
\ No newline at end of file
diff --git a/test/json_tests/fail31.json b/test/json_tests/fail31.json
new file mode 100644
index 00000000..1cce602b
--- /dev/null
+++ b/test/json_tests/fail31.json
@@ -0,0 +1 @@
+[0e+-1]
\ No newline at end of file
diff --git a/test/json_tests/fail32.json b/test/json_tests/fail32.json
new file mode 100644
index 00000000..45cba739
--- /dev/null
+++ b/test/json_tests/fail32.json
@@ -0,0 +1 @@
+{"Comma instead if closing brace": true,
\ No newline at end of file
diff --git a/test/json_tests/fail33.json b/test/json_tests/fail33.json
new file mode 100644
index 00000000..ca5eb19d
--- /dev/null
+++ b/test/json_tests/fail33.json
@@ -0,0 +1 @@
+["mismatch"}
\ No newline at end of file
diff --git a/test/json_tests/fail4.json b/test/json_tests/fail4.json
new file mode 100644
index 00000000..9de168bf
--- /dev/null
+++ b/test/json_tests/fail4.json
@@ -0,0 +1 @@
+["extra comma",]
\ No newline at end of file
diff --git a/test/json_tests/fail5.json b/test/json_tests/fail5.json
new file mode 100644
index 00000000..ddf3ce3d
--- /dev/null
+++ b/test/json_tests/fail5.json
@@ -0,0 +1 @@
+["double extra comma",,]
\ No newline at end of file
diff --git a/test/json_tests/fail6.json b/test/json_tests/fail6.json
new file mode 100644
index 00000000..ed91580e
--- /dev/null
+++ b/test/json_tests/fail6.json
@@ -0,0 +1 @@
+[   , "<-- missing value"]
\ No newline at end of file
diff --git a/test/json_tests/fail7.json b/test/json_tests/fail7.json
new file mode 100644
index 00000000..8a96af3e
--- /dev/null
+++ b/test/json_tests/fail7.json
@@ -0,0 +1 @@
+["Comma after the close"],
\ No newline at end of file
diff --git a/test/json_tests/fail8.json b/test/json_tests/fail8.json
new file mode 100644
index 00000000..b28479c6
--- /dev/null
+++ b/test/json_tests/fail8.json
@@ -0,0 +1 @@
+["Extra close"]]
\ No newline at end of file
diff --git a/test/json_tests/fail9.json b/test/json_tests/fail9.json
new file mode 100644
index 00000000..5815574f
--- /dev/null
+++ b/test/json_tests/fail9.json
@@ -0,0 +1 @@
+{"Extra comma": true,}
\ No newline at end of file
diff --git a/test/json_tests/pass1.json b/test/json_tests/pass1.json
new file mode 100644
index 00000000..70e26854
--- /dev/null
+++ b/test/json_tests/pass1.json
@@ -0,0 +1,58 @@
+[
+    "JSON Test Pattern pass1",
+    {"object with 1 member":["array with 1 element"]},
+    {},
+    [],
+    -42,
+    true,
+    false,
+    null,
+    {
+        "integer": 1234567890,
+        "real": -9876.543210,
+        "e": 0.123456789e-12,
+        "E": 1.234567890E+34,
+        "":  23456789012E66,
+        "zero": 0,
+        "one": 1,
+        "space": " ",
+        "quote": "\"",
+        "backslash": "\\",
+        "controls": "\b\f\n\r\t",
+        "slash": "/ & \/",
+        "alpha": "abcdefghijklmnopqrstuvwyz",
+        "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
+        "digit": "0123456789",
+        "0123456789": "digit",
+        "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
+        "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
+        "true": true,
+        "false": false,
+        "null": null,
+        "array":[  ],
+        "object":{  },
+        "address": "50 St. James Street",
+        "url": "http://www.JSON.org/",
+        "comment": "// /* <!-- --",
+        "# -- --> */": " ",
+        " s p a c e d " :[1,2 , 3
+
+,
+
+4 , 5        ,          6           ,7        ],"compact":[1,2,3,4,5,6,7],
+        "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
+        "quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
+        "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
+: "A key can be any string"
+    },
+    0.5 ,98.6
+,
+99.44
+,
+
+1066,
+1e1,
+0.1e1,
+1e-1,
+1e00,2e+00,2e-00
+,"rosebud"]
\ No newline at end of file
diff --git a/test/json_tests/pass2.json b/test/json_tests/pass2.json
new file mode 100644
index 00000000..d3c63c7a
--- /dev/null
+++ b/test/json_tests/pass2.json
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
\ No newline at end of file
diff --git a/test/json_tests/pass3.json b/test/json_tests/pass3.json
new file mode 100644
index 00000000..4528d51f
--- /dev/null
+++ b/test/json_tests/pass3.json
@@ -0,0 +1,6 @@
+{
+    "JSON Test Pattern pass3": {
+        "The outermost value": "must be an object or array.",
+        "In this test": "It is an object."
+    }
+}
diff --git a/test/unit.cpp b/test/unit.cpp
index 236e1f93..d8f5d2d2 100644
--- a/test/unit.cpp
+++ b/test/unit.cpp
@@ -7398,16 +7398,17 @@ TEST_CASE("parser class")
 
                 // exotic test cases for full coverage
                 {
-                    {
-                        std::stringstream ss;
-                        ss << "\"\\u000\n1\"";
-                        CHECK(json::parser(ss).parse().get<json::string_t>() == "\x01");
-                    }
-                    {
-                        std::stringstream ss;
-                        ss << "\"\\u00\n01\"";
-                        CHECK(json::parser(ss).parse().get<json::string_t>() == "\x01");
-                    }
+                    // that one got illegal
+                    //{
+                    //    std::stringstream ss;
+                    //    ss << "\"\\u000\n1\"";
+                    //    CHECK(json::parser(ss).parse().get<json::string_t>() == "\x01");
+                    //}
+                    //{
+                    //    std::stringstream ss;
+                    //    ss << "\"\\u00\n01\"";
+                    //    CHECK(json::parser(ss).parse().get<json::string_t>() == "\x01");
+                    //}
                 }
 
                 CHECK(json::parser("\"\\u0001\"").parse().get<json::string_t>() == "\x01");
@@ -8439,6 +8440,73 @@ TEST_CASE("concepts")
     }
 }
 
+TEST_CASE("JSON compliance")
+{
+    // test cases are from http://json.org/JSON_checker/
+
+    SECTION("expected failures")
+    {
+        for (auto filename :
+                {
+                    //"test/json_tests/fail1.json",
+                    "test/json_tests/fail2.json",
+                    "test/json_tests/fail3.json",
+                    "test/json_tests/fail4.json",
+                    "test/json_tests/fail5.json",
+                    "test/json_tests/fail6.json",
+                    "test/json_tests/fail7.json",
+                    "test/json_tests/fail8.json",
+                    "test/json_tests/fail9.json",
+                    "test/json_tests/fail10.json",
+                    "test/json_tests/fail11.json",
+                    "test/json_tests/fail12.json",
+                    "test/json_tests/fail13.json",
+                    "test/json_tests/fail14.json",
+                    "test/json_tests/fail15.json",
+                    "test/json_tests/fail16.json",
+                    "test/json_tests/fail17.json",
+                    //"test/json_tests/fail18.json",
+                    "test/json_tests/fail19.json",
+                    "test/json_tests/fail20.json",
+                    "test/json_tests/fail21.json",
+                    "test/json_tests/fail22.json",
+                    "test/json_tests/fail23.json",
+                    "test/json_tests/fail24.json",
+                    "test/json_tests/fail25.json",
+                    "test/json_tests/fail26.json",
+                    "test/json_tests/fail27.json",
+                    "test/json_tests/fail28.json",
+                    "test/json_tests/fail29.json",
+                    "test/json_tests/fail30.json",
+                    "test/json_tests/fail31.json",
+                    "test/json_tests/fail32.json",
+                    "test/json_tests/fail33.json"
+                })
+        {
+            CAPTURE(filename);
+            json j;
+            std::ifstream f(filename);
+            CHECK_THROWS_AS(j << f, std::invalid_argument);
+        }
+    }
+
+    SECTION("expected passes")
+    {
+        for (auto filename :
+                {
+                    "test/json_tests/pass1.json",
+                    "test/json_tests/pass2.json",
+                    "test/json_tests/pass3.json"
+                })
+        {
+            CAPTURE(filename);
+            json j;
+            std::ifstream f(filename);
+            CHECK_NOTHROW(j << f);
+        }
+    }
+}
+
 TEST_CASE("regression tests")
 {
     SECTION("issue #60 - Double quotation mark is not parsed correctly")