| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "base/json/json_reader.h" | 5 #include "base/json/json_reader.h" | 
| 6 | 6 | 
| 7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" | 
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" | 
|  | 9 #include "base/logging.h" | 
| 9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" | 
| 10 #include "base/path_service.h" | 11 #include "base/path_service.h" | 
| 11 #include "base/string_piece.h" | 12 #include "base/string_piece.h" | 
| 12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" | 
| 13 #include "base/values.h" | 14 #include "base/values.h" | 
| 14 #include "build/build_config.h" | 15 #include "build/build_config.h" | 
| 15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" | 
| 16 | 17 | 
| 17 namespace base { | 18 namespace base { | 
| 18 | 19 | 
| 19 TEST(JSONReaderTest, Reading) { | 20 TEST(JSONReaderTest, Reading) { | 
| 20   // some whitespace checking | 21   // some whitespace checking | 
| 21   scoped_ptr<Value> root; | 22   scoped_ptr<Value> root; | 
| 22   root.reset(JSONReader().JsonToValue("   null   ", false, false)); | 23   root.reset(JSONReader().ReadToValue("   null   ")); | 
| 23   ASSERT_TRUE(root.get()); | 24   ASSERT_TRUE(root.get()); | 
| 24   EXPECT_TRUE(root->IsType(Value::TYPE_NULL)); | 25   EXPECT_TRUE(root->IsType(Value::TYPE_NULL)); | 
| 25 | 26 | 
| 26   // Invalid JSON string | 27   // Invalid JSON string | 
| 27   root.reset(JSONReader().JsonToValue("nu", false, false)); | 28   root.reset(JSONReader().ReadToValue("nu")); | 
| 28   EXPECT_FALSE(root.get()); | 29   EXPECT_FALSE(root.get()); | 
| 29 | 30 | 
| 30   // Simple bool | 31   // Simple bool | 
| 31   root.reset(JSONReader().JsonToValue("true  ", false, false)); | 32   root.reset(JSONReader().ReadToValue("true  ")); | 
| 32   ASSERT_TRUE(root.get()); | 33   ASSERT_TRUE(root.get()); | 
| 33   EXPECT_TRUE(root->IsType(Value::TYPE_BOOLEAN)); | 34   EXPECT_TRUE(root->IsType(Value::TYPE_BOOLEAN)); | 
| 34 | 35 | 
| 35   // Embedded comment | 36   // Embedded comment | 
| 36   root.reset(JSONReader().JsonToValue("/* comment */null", false, false)); | 37   root.reset(JSONReader().ReadToValue("/* comment */null")); | 
| 37   ASSERT_TRUE(root.get()); | 38   ASSERT_TRUE(root.get()); | 
| 38   EXPECT_TRUE(root->IsType(Value::TYPE_NULL)); | 39   EXPECT_TRUE(root->IsType(Value::TYPE_NULL)); | 
| 39   root.reset(JSONReader().JsonToValue("40 /* comment */", false, false)); | 40   root.reset(JSONReader().ReadToValue("40 /* comment */")); | 
| 40   ASSERT_TRUE(root.get()); | 41   ASSERT_TRUE(root.get()); | 
| 41   EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | 42   EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | 
| 42   root.reset(JSONReader().JsonToValue("true // comment", false, false)); | 43   root.reset(JSONReader().ReadToValue("true // comment")); | 
| 43   ASSERT_TRUE(root.get()); | 44   ASSERT_TRUE(root.get()); | 
| 44   EXPECT_TRUE(root->IsType(Value::TYPE_BOOLEAN)); | 45   EXPECT_TRUE(root->IsType(Value::TYPE_BOOLEAN)); | 
| 45   root.reset(JSONReader().JsonToValue("/* comment */\"sample string\"", | 46   root.reset(JSONReader().ReadToValue("/* comment */\"sample string\"")); | 
| 46                                       false, false)); |  | 
| 47   ASSERT_TRUE(root.get()); | 47   ASSERT_TRUE(root.get()); | 
| 48   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 48   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 
| 49   std::string value; | 49   std::string value; | 
| 50   EXPECT_TRUE(root->GetAsString(&value)); | 50   EXPECT_TRUE(root->GetAsString(&value)); | 
| 51   EXPECT_EQ("sample string", value); | 51   EXPECT_EQ("sample string", value); | 
|  | 52   root.reset(JSONReader().ReadToValue("[1, /* comment, 2 ] */ \n 3]")); | 
|  | 53   ASSERT_TRUE(root.get()); | 
|  | 54   ListValue* list = static_cast<ListValue*>(root.get()); | 
|  | 55   EXPECT_EQ(2u, list->GetSize()); | 
|  | 56   int int_val = 0; | 
|  | 57   EXPECT_TRUE(list->GetInteger(0, &int_val)); | 
|  | 58   EXPECT_EQ(1, int_val); | 
|  | 59   EXPECT_TRUE(list->GetInteger(1, &int_val)); | 
|  | 60   EXPECT_EQ(3, int_val); | 
|  | 61   root.reset(JSONReader().ReadToValue("[1, /*a*/2, 3]")); | 
|  | 62   ASSERT_TRUE(root.get()); | 
|  | 63   list = static_cast<ListValue*>(root.get()); | 
|  | 64   EXPECT_EQ(3u, list->GetSize()); | 
| 52 | 65 | 
| 53   // Test number formats | 66   // Test number formats | 
| 54   root.reset(JSONReader().JsonToValue("43", false, false)); | 67   root.reset(JSONReader().ReadToValue("43")); | 
| 55   ASSERT_TRUE(root.get()); | 68   ASSERT_TRUE(root.get()); | 
| 56   EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | 69   EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | 
| 57   int int_val = 0; |  | 
| 58   EXPECT_TRUE(root->GetAsInteger(&int_val)); | 70   EXPECT_TRUE(root->GetAsInteger(&int_val)); | 
| 59   EXPECT_EQ(43, int_val); | 71   EXPECT_EQ(43, int_val); | 
| 60 | 72 | 
| 61   // According to RFC4627, oct, hex, and leading zeros are invalid JSON. | 73   // According to RFC4627, oct, hex, and leading zeros are invalid JSON. | 
| 62   root.reset(JSONReader().JsonToValue("043", false, false)); | 74   root.reset(JSONReader().ReadToValue("043")); | 
| 63   EXPECT_FALSE(root.get()); | 75   EXPECT_FALSE(root.get()); | 
| 64   root.reset(JSONReader().JsonToValue("0x43", false, false)); | 76   root.reset(JSONReader().ReadToValue("0x43")); | 
| 65   EXPECT_FALSE(root.get()); | 77   EXPECT_FALSE(root.get()); | 
| 66   root.reset(JSONReader().JsonToValue("00", false, false)); | 78   root.reset(JSONReader().ReadToValue("00")); | 
| 67   EXPECT_FALSE(root.get()); | 79   EXPECT_FALSE(root.get()); | 
| 68 | 80 | 
| 69   // Test 0 (which needs to be special cased because of the leading zero | 81   // Test 0 (which needs to be special cased because of the leading zero | 
| 70   // clause). | 82   // clause). | 
| 71   root.reset(JSONReader().JsonToValue("0", false, false)); | 83   root.reset(JSONReader().ReadToValue("0")); | 
| 72   ASSERT_TRUE(root.get()); | 84   ASSERT_TRUE(root.get()); | 
| 73   EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | 85   EXPECT_TRUE(root->IsType(Value::TYPE_INTEGER)); | 
| 74   int_val = 1; | 86   int_val = 1; | 
| 75   EXPECT_TRUE(root->GetAsInteger(&int_val)); | 87   EXPECT_TRUE(root->GetAsInteger(&int_val)); | 
| 76   EXPECT_EQ(0, int_val); | 88   EXPECT_EQ(0, int_val); | 
| 77 | 89 | 
| 78   // Numbers that overflow ints should succeed, being internally promoted to | 90   // Numbers that overflow ints should succeed, being internally promoted to | 
| 79   // storage as doubles | 91   // storage as doubles | 
| 80   root.reset(JSONReader().JsonToValue("2147483648", false, false)); | 92   root.reset(JSONReader().ReadToValue("2147483648")); | 
| 81   ASSERT_TRUE(root.get()); | 93   ASSERT_TRUE(root.get()); | 
| 82   double double_val; | 94   double double_val; | 
| 83   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 95   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 
| 84   double_val = 0.0; | 96   double_val = 0.0; | 
| 85   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 97   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 
| 86   EXPECT_DOUBLE_EQ(2147483648.0, double_val); | 98   EXPECT_DOUBLE_EQ(2147483648.0, double_val); | 
| 87   root.reset(JSONReader().JsonToValue("-2147483649", false, false)); | 99   root.reset(JSONReader().ReadToValue("-2147483649")); | 
| 88   ASSERT_TRUE(root.get()); | 100   ASSERT_TRUE(root.get()); | 
| 89   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 101   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 
| 90   double_val = 0.0; | 102   double_val = 0.0; | 
| 91   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 103   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 
| 92   EXPECT_DOUBLE_EQ(-2147483649.0, double_val); | 104   EXPECT_DOUBLE_EQ(-2147483649.0, double_val); | 
| 93 | 105 | 
| 94   // Parse a double | 106   // Parse a double | 
| 95   root.reset(JSONReader().JsonToValue("43.1", false, false)); | 107   root.reset(JSONReader().ReadToValue("43.1")); | 
| 96   ASSERT_TRUE(root.get()); | 108   ASSERT_TRUE(root.get()); | 
| 97   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 109   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 
| 98   double_val = 0.0; | 110   double_val = 0.0; | 
| 99   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 111   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 
| 100   EXPECT_DOUBLE_EQ(43.1, double_val); | 112   EXPECT_DOUBLE_EQ(43.1, double_val); | 
| 101 | 113 | 
| 102   root.reset(JSONReader().JsonToValue("4.3e-1", false, false)); | 114   root.reset(JSONReader().ReadToValue("4.3e-1")); | 
| 103   ASSERT_TRUE(root.get()); | 115   ASSERT_TRUE(root.get()); | 
| 104   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 116   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 
| 105   double_val = 0.0; | 117   double_val = 0.0; | 
| 106   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 118   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 
| 107   EXPECT_DOUBLE_EQ(.43, double_val); | 119   EXPECT_DOUBLE_EQ(.43, double_val); | 
| 108 | 120 | 
| 109   root.reset(JSONReader().JsonToValue("2.1e0", false, false)); | 121   root.reset(JSONReader().ReadToValue("2.1e0")); | 
| 110   ASSERT_TRUE(root.get()); | 122   ASSERT_TRUE(root.get()); | 
| 111   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 123   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 
| 112   double_val = 0.0; | 124   double_val = 0.0; | 
| 113   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 125   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 
| 114   EXPECT_DOUBLE_EQ(2.1, double_val); | 126   EXPECT_DOUBLE_EQ(2.1, double_val); | 
| 115 | 127 | 
| 116   root.reset(JSONReader().JsonToValue("2.1e+0001", false, false)); | 128   root.reset(JSONReader().ReadToValue("2.1e+0001")); | 
| 117   ASSERT_TRUE(root.get()); | 129   ASSERT_TRUE(root.get()); | 
| 118   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 130   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 
| 119   double_val = 0.0; | 131   double_val = 0.0; | 
| 120   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 132   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 
| 121   EXPECT_DOUBLE_EQ(21.0, double_val); | 133   EXPECT_DOUBLE_EQ(21.0, double_val); | 
| 122 | 134 | 
| 123   root.reset(JSONReader().JsonToValue("0.01", false, false)); | 135   root.reset(JSONReader().ReadToValue("0.01")); | 
| 124   ASSERT_TRUE(root.get()); | 136   ASSERT_TRUE(root.get()); | 
| 125   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 137   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 
| 126   double_val = 0.0; | 138   double_val = 0.0; | 
| 127   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 139   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 
| 128   EXPECT_DOUBLE_EQ(0.01, double_val); | 140   EXPECT_DOUBLE_EQ(0.01, double_val); | 
| 129 | 141 | 
| 130   root.reset(JSONReader().JsonToValue("1.00", false, false)); | 142   root.reset(JSONReader().ReadToValue("1.00")); | 
| 131   ASSERT_TRUE(root.get()); | 143   ASSERT_TRUE(root.get()); | 
| 132   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 144   EXPECT_TRUE(root->IsType(Value::TYPE_DOUBLE)); | 
| 133   double_val = 0.0; | 145   double_val = 0.0; | 
| 134   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 146   EXPECT_TRUE(root->GetAsDouble(&double_val)); | 
| 135   EXPECT_DOUBLE_EQ(1.0, double_val); | 147   EXPECT_DOUBLE_EQ(1.0, double_val); | 
| 136 | 148 | 
| 137   // Fractional parts must have a digit before and after the decimal point. | 149   // Fractional parts must have a digit before and after the decimal point. | 
| 138   root.reset(JSONReader().JsonToValue("1.", false, false)); | 150   root.reset(JSONReader().ReadToValue("1.")); | 
| 139   EXPECT_FALSE(root.get()); | 151   EXPECT_FALSE(root.get()); | 
| 140   root.reset(JSONReader().JsonToValue(".1", false, false)); | 152   root.reset(JSONReader().ReadToValue(".1")); | 
| 141   EXPECT_FALSE(root.get()); | 153   EXPECT_FALSE(root.get()); | 
| 142   root.reset(JSONReader().JsonToValue("1.e10", false, false)); | 154   root.reset(JSONReader().ReadToValue("1.e10")); | 
| 143   EXPECT_FALSE(root.get()); | 155   EXPECT_FALSE(root.get()); | 
| 144 | 156 | 
| 145   // Exponent must have a digit following the 'e'. | 157   // Exponent must have a digit following the 'e'. | 
| 146   root.reset(JSONReader().JsonToValue("1e", false, false)); | 158   root.reset(JSONReader().ReadToValue("1e")); | 
| 147   EXPECT_FALSE(root.get()); | 159   EXPECT_FALSE(root.get()); | 
| 148   root.reset(JSONReader().JsonToValue("1E", false, false)); | 160   root.reset(JSONReader().ReadToValue("1E")); | 
| 149   EXPECT_FALSE(root.get()); | 161   EXPECT_FALSE(root.get()); | 
| 150   root.reset(JSONReader().JsonToValue("1e1.", false, false)); | 162   root.reset(JSONReader().ReadToValue("1e1.")); | 
| 151   EXPECT_FALSE(root.get()); | 163   EXPECT_FALSE(root.get()); | 
| 152   root.reset(JSONReader().JsonToValue("1e1.0", false, false)); | 164   root.reset(JSONReader().ReadToValue("1e1.0")); | 
| 153   EXPECT_FALSE(root.get()); | 165   EXPECT_FALSE(root.get()); | 
| 154 | 166 | 
| 155   // INF/-INF/NaN are not valid | 167   // INF/-INF/NaN are not valid | 
| 156   root.reset(JSONReader().JsonToValue("1e1000", false, false)); | 168   root.reset(JSONReader().ReadToValue("1e1000")); | 
| 157   EXPECT_FALSE(root.get()); | 169   EXPECT_FALSE(root.get()); | 
| 158   root.reset(JSONReader().JsonToValue("-1e1000", false, false)); | 170   root.reset(JSONReader().ReadToValue("-1e1000")); | 
| 159   EXPECT_FALSE(root.get()); | 171   EXPECT_FALSE(root.get()); | 
| 160   root.reset(JSONReader().JsonToValue("NaN", false, false)); | 172   root.reset(JSONReader().ReadToValue("NaN")); | 
| 161   EXPECT_FALSE(root.get()); | 173   EXPECT_FALSE(root.get()); | 
| 162   root.reset(JSONReader().JsonToValue("nan", false, false)); | 174   root.reset(JSONReader().ReadToValue("nan")); | 
| 163   EXPECT_FALSE(root.get()); | 175   EXPECT_FALSE(root.get()); | 
| 164   root.reset(JSONReader().JsonToValue("inf", false, false)); | 176   root.reset(JSONReader().ReadToValue("inf")); | 
| 165   EXPECT_FALSE(root.get()); | 177   EXPECT_FALSE(root.get()); | 
| 166 | 178 | 
| 167   // Invalid number formats | 179   // Invalid number formats | 
| 168   root.reset(JSONReader().JsonToValue("4.3.1", false, false)); | 180   root.reset(JSONReader().ReadToValue("4.3.1")); | 
| 169   EXPECT_FALSE(root.get()); | 181   EXPECT_FALSE(root.get()); | 
| 170   root.reset(JSONReader().JsonToValue("4e3.1", false, false)); | 182   root.reset(JSONReader().ReadToValue("4e3.1")); | 
| 171   EXPECT_FALSE(root.get()); | 183   EXPECT_FALSE(root.get()); | 
| 172 | 184 | 
| 173   // Test string parser | 185   // Test string parser | 
| 174   root.reset(JSONReader().JsonToValue("\"hello world\"", false, false)); | 186   root.reset(JSONReader().ReadToValue("\"hello world\"")); | 
| 175   ASSERT_TRUE(root.get()); | 187   ASSERT_TRUE(root.get()); | 
| 176   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 188   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 
| 177   std::string str_val; | 189   std::string str_val; | 
| 178   EXPECT_TRUE(root->GetAsString(&str_val)); | 190   EXPECT_TRUE(root->GetAsString(&str_val)); | 
| 179   EXPECT_EQ("hello world", str_val); | 191   EXPECT_EQ("hello world", str_val); | 
| 180 | 192 | 
| 181   // Empty string | 193   // Empty string | 
| 182   root.reset(JSONReader().JsonToValue("\"\"", false, false)); | 194   root.reset(JSONReader().ReadToValue("\"\"")); | 
| 183   ASSERT_TRUE(root.get()); | 195   ASSERT_TRUE(root.get()); | 
| 184   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 196   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 
| 185   str_val.clear(); | 197   str_val.clear(); | 
| 186   EXPECT_TRUE(root->GetAsString(&str_val)); | 198   EXPECT_TRUE(root->GetAsString(&str_val)); | 
| 187   EXPECT_EQ("", str_val); | 199   EXPECT_EQ("", str_val); | 
| 188 | 200 | 
| 189   // Test basic string escapes | 201   // Test basic string escapes | 
| 190   root.reset(JSONReader().JsonToValue("\" \\\"\\\\\\/\\b\\f\\n\\r\\t\\v\"", | 202   root.reset(JSONReader().ReadToValue("\" \\\"\\\\\\/\\b\\f\\n\\r\\t\\v\"")); | 
| 191                                       false, false)); |  | 
| 192   ASSERT_TRUE(root.get()); | 203   ASSERT_TRUE(root.get()); | 
| 193   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 204   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 
| 194   str_val.clear(); | 205   str_val.clear(); | 
| 195   EXPECT_TRUE(root->GetAsString(&str_val)); | 206   EXPECT_TRUE(root->GetAsString(&str_val)); | 
| 196   EXPECT_EQ(" \"\\/\b\f\n\r\t\v", str_val); | 207   EXPECT_EQ(" \"\\/\b\f\n\r\t\v", str_val); | 
| 197 | 208 | 
| 198   // Test hex and unicode escapes including the null character. | 209   // Test hex and unicode escapes including the null character. | 
| 199   root.reset(JSONReader().JsonToValue("\"\\x41\\x00\\u1234\"", false, | 210   root.reset(JSONReader().ReadToValue("\"\\x41\\x00\\u1234\"")); | 
| 200                                       false)); |  | 
| 201   ASSERT_TRUE(root.get()); | 211   ASSERT_TRUE(root.get()); | 
| 202   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 212   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 
| 203   str_val.clear(); | 213   str_val.clear(); | 
| 204   EXPECT_TRUE(root->GetAsString(&str_val)); | 214   EXPECT_TRUE(root->GetAsString(&str_val)); | 
| 205   EXPECT_EQ(std::wstring(L"A\0\x1234", 3), UTF8ToWide(str_val)); | 215   EXPECT_EQ(std::wstring(L"A\0\x1234", 3), UTF8ToWide(str_val)); | 
| 206 | 216 | 
| 207   // Test invalid strings | 217   // Test invalid strings | 
| 208   root.reset(JSONReader().JsonToValue("\"no closing quote", false, false)); | 218   root.reset(JSONReader().ReadToValue("\"no closing quote")); | 
| 209   EXPECT_FALSE(root.get()); | 219   EXPECT_FALSE(root.get()); | 
| 210   root.reset(JSONReader().JsonToValue("\"\\z invalid escape char\"", false, | 220   root.reset(JSONReader().ReadToValue("\"\\z invalid escape char\"")); | 
| 211                                       false)); |  | 
| 212   EXPECT_FALSE(root.get()); | 221   EXPECT_FALSE(root.get()); | 
| 213   root.reset(JSONReader().JsonToValue("\"\\xAQ invalid hex code\"", false, | 222   root.reset(JSONReader().ReadToValue("\"\\xAQ invalid hex code\"")); | 
| 214                                       false)); |  | 
| 215   EXPECT_FALSE(root.get()); | 223   EXPECT_FALSE(root.get()); | 
| 216   root.reset(JSONReader().JsonToValue("not enough hex chars\\x1\"", false, | 224   root.reset(JSONReader().ReadToValue("not enough hex chars\\x1\"")); | 
| 217                                       false)); |  | 
| 218   EXPECT_FALSE(root.get()); | 225   EXPECT_FALSE(root.get()); | 
| 219   root.reset(JSONReader().JsonToValue("\"not enough escape chars\\u123\"", | 226   root.reset(JSONReader().ReadToValue("\"not enough escape chars\\u123\"")); | 
| 220                                       false, false)); |  | 
| 221   EXPECT_FALSE(root.get()); | 227   EXPECT_FALSE(root.get()); | 
| 222   root.reset(JSONReader().JsonToValue("\"extra backslash at end of input\\\"", | 228   root.reset(JSONReader().ReadToValue("\"extra backslash at end of input\\\"")); | 
| 223                                       false, false)); |  | 
| 224   EXPECT_FALSE(root.get()); | 229   EXPECT_FALSE(root.get()); | 
| 225 | 230 | 
| 226   // Basic array | 231   // Basic array | 
| 227   root.reset(JSONReader::Read("[true, false, null]")); | 232   root.reset(JSONReader::Read("[true, false, null]")); | 
| 228   ASSERT_TRUE(root.get()); | 233   ASSERT_TRUE(root.get()); | 
| 229   EXPECT_TRUE(root->IsType(Value::TYPE_LIST)); | 234   EXPECT_TRUE(root->IsType(Value::TYPE_LIST)); | 
| 230   ListValue* list = static_cast<ListValue*>(root.get()); | 235   list = static_cast<ListValue*>(root.get()); | 
| 231   EXPECT_EQ(3U, list->GetSize()); | 236   EXPECT_EQ(3U, list->GetSize()); | 
| 232 | 237 | 
| 233   // Test with trailing comma.  Should be parsed the same as above. | 238   // Test with trailing comma.  Should be parsed the same as above. | 
| 234   scoped_ptr<Value> root2; | 239   scoped_ptr<Value> root2; | 
| 235   root2.reset(JSONReader::Read("[true, false, null, ]", | 240   root2.reset(JSONReader::Read("[true, false, null, ]", | 
| 236                                JSON_ALLOW_TRAILING_COMMAS)); | 241                                JSON_ALLOW_TRAILING_COMMAS)); | 
| 237   EXPECT_TRUE(root->Equals(root2.get())); | 242   EXPECT_TRUE(root->Equals(root2.get())); | 
| 238 | 243 | 
| 239   // Empty array | 244   // Empty array | 
| 240   root.reset(JSONReader::Read("[]")); | 245   root.reset(JSONReader::Read("[]")); | 
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 441     not_evil.append("[],"); | 446     not_evil.append("[],"); | 
| 442   } | 447   } | 
| 443   not_evil.append("[]]"); | 448   not_evil.append("[]]"); | 
| 444   root.reset(JSONReader::Read(not_evil)); | 449   root.reset(JSONReader::Read(not_evil)); | 
| 445   ASSERT_TRUE(root.get()); | 450   ASSERT_TRUE(root.get()); | 
| 446   EXPECT_TRUE(root->IsType(Value::TYPE_LIST)); | 451   EXPECT_TRUE(root->IsType(Value::TYPE_LIST)); | 
| 447   list = static_cast<ListValue*>(root.get()); | 452   list = static_cast<ListValue*>(root.get()); | 
| 448   EXPECT_EQ(5001U, list->GetSize()); | 453   EXPECT_EQ(5001U, list->GetSize()); | 
| 449 | 454 | 
| 450   // Test utf8 encoded input | 455   // Test utf8 encoded input | 
| 451   root.reset(JSONReader().JsonToValue("\"\xe7\xbd\x91\xe9\xa1\xb5\"", | 456   root.reset(JSONReader().ReadToValue("\"\xe7\xbd\x91\xe9\xa1\xb5\"")); | 
| 452                                       false, false)); |  | 
| 453   ASSERT_TRUE(root.get()); | 457   ASSERT_TRUE(root.get()); | 
| 454   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 458   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 
| 455   str_val.clear(); | 459   str_val.clear(); | 
| 456   EXPECT_TRUE(root->GetAsString(&str_val)); | 460   EXPECT_TRUE(root->GetAsString(&str_val)); | 
| 457   EXPECT_EQ(L"\x7f51\x9875", UTF8ToWide(str_val)); | 461   EXPECT_EQ(L"\x7f51\x9875", UTF8ToWide(str_val)); | 
| 458 | 462 | 
|  | 463   root.reset(JSONReader().ReadToValue( | 
|  | 464       "{\"path\": \"/tmp/\xc3\xa0\xc3\xa8\xc3\xb2.png\"}")); | 
|  | 465   ASSERT_TRUE(root.get()); | 
|  | 466   EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | 
|  | 467   EXPECT_TRUE(root->GetAsDictionary(&dict_val)); | 
|  | 468   EXPECT_TRUE(dict_val->GetString("path", &str_val)); | 
|  | 469   EXPECT_EQ("/tmp/\xC3\xA0\xC3\xA8\xC3\xB2.png", str_val); | 
|  | 470 | 
| 459   // Test invalid utf8 encoded input | 471   // Test invalid utf8 encoded input | 
| 460   root.reset(JSONReader().JsonToValue("\"345\xb0\xa1\xb0\xa2\"", | 472   root.reset(JSONReader().ReadToValue("\"345\xb0\xa1\xb0\xa2\"")); | 
| 461                                       false, false)); |  | 
| 462   EXPECT_FALSE(root.get()); | 473   EXPECT_FALSE(root.get()); | 
| 463   root.reset(JSONReader().JsonToValue("\"123\xc0\x81\"", | 474   root.reset(JSONReader().ReadToValue("\"123\xc0\x81\"")); | 
| 464                                       false, false)); | 475   EXPECT_FALSE(root.get()); | 
|  | 476   root.reset(JSONReader().ReadToValue("\"abc\xc0\xae\"")); | 
| 465   EXPECT_FALSE(root.get()); | 477   EXPECT_FALSE(root.get()); | 
| 466 | 478 | 
| 467   // Test utf16 encoded strings. | 479   // Test utf16 encoded strings. | 
| 468   root.reset(JSONReader().JsonToValue("\"\\u20ac3,14\"", false, false)); | 480   root.reset(JSONReader().ReadToValue("\"\\u20ac3,14\"")); | 
| 469   ASSERT_TRUE(root.get()); | 481   ASSERT_TRUE(root.get()); | 
| 470   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 482   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 
| 471   str_val.clear(); | 483   str_val.clear(); | 
| 472   EXPECT_TRUE(root->GetAsString(&str_val)); | 484   EXPECT_TRUE(root->GetAsString(&str_val)); | 
| 473   EXPECT_EQ("\xe2\x82\xac""3,14", str_val); | 485   EXPECT_EQ("\xe2\x82\xac""3,14", str_val); | 
| 474 | 486 | 
| 475   root.reset(JSONReader().JsonToValue("\"\\ud83d\\udca9\\ud83d\\udc6c\"", | 487   root.reset(JSONReader().ReadToValue("\"\\ud83d\\udca9\\ud83d\\udc6c\"")); | 
| 476                                       false, false)); |  | 
| 477   ASSERT_TRUE(root.get()); | 488   ASSERT_TRUE(root.get()); | 
| 478   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 489   EXPECT_TRUE(root->IsType(Value::TYPE_STRING)); | 
| 479   str_val.clear(); | 490   str_val.clear(); | 
| 480   EXPECT_TRUE(root->GetAsString(&str_val)); | 491   EXPECT_TRUE(root->GetAsString(&str_val)); | 
| 481   EXPECT_EQ("\xf0\x9f\x92\xa9\xf0\x9f\x91\xac", str_val); | 492   EXPECT_EQ("\xf0\x9f\x92\xa9\xf0\x9f\x91\xac", str_val); | 
| 482 | 493 | 
| 483   // Test invalid utf16 strings. | 494   // Test invalid utf16 strings. | 
| 484   const char* cases[] = { | 495   const char* cases[] = { | 
| 485     "\"\\u123\"",  // Invalid scalar. | 496     "\"\\u123\"",  // Invalid scalar. | 
| 486     "\"\\ud83d\"",  // Invalid scalar. | 497     "\"\\ud83d\"",  // Invalid scalar. | 
| 487     "\"\\u$%@!\"",  // Invalid scalar. | 498     "\"\\u$%@!\"",  // Invalid scalar. | 
| 488     "\"\\uzz89\"",  // Invalid scalar. | 499     "\"\\uzz89\"",  // Invalid scalar. | 
| 489     "\"\\ud83d\\udca\"",  // Invalid lower surrogate. | 500     "\"\\ud83d\\udca\"",  // Invalid lower surrogate. | 
| 490     "\"\\ud83d\\ud83d\"",  // Invalid lower surrogate. | 501     "\"\\ud83d\\ud83d\"",  // Invalid lower surrogate. | 
| 491     "\"\\ud83foo\"",  // No lower surrogate. | 502     "\"\\ud83foo\"",  // No lower surrogate. | 
| 492     "\"\\ud83\\foo\""  // No lower surrogate. | 503     "\"\\ud83\\foo\""  // No lower surrogate. | 
| 493   }; | 504   }; | 
| 494   for (size_t i = 0; i < arraysize(cases); ++i) { | 505   for (size_t i = 0; i < arraysize(cases); ++i) { | 
| 495     root.reset(JSONReader().JsonToValue(cases[i], false, false)); | 506     root.reset(JSONReader().ReadToValue(cases[i])); | 
| 496     EXPECT_FALSE(root.get()) << cases[i]; | 507     EXPECT_FALSE(root.get()) << cases[i]; | 
| 497   } | 508   } | 
|  | 509 | 
|  | 510   // Test literal root objects. | 
|  | 511   root.reset(JSONReader::Read("null")); | 
|  | 512   EXPECT_TRUE(root->IsType(Value::TYPE_NULL)); | 
|  | 513 | 
|  | 514   root.reset(JSONReader::Read("true")); | 
|  | 515   ASSERT_TRUE(root.get()); | 
|  | 516   EXPECT_TRUE(root->GetAsBoolean(&bool_value)); | 
|  | 517   EXPECT_TRUE(bool_value); | 
|  | 518 | 
|  | 519   root.reset(JSONReader::Read("10")); | 
|  | 520   ASSERT_TRUE(root.get()); | 
|  | 521   EXPECT_TRUE(root->GetAsInteger(&integer_value)); | 
|  | 522   EXPECT_EQ(10, integer_value); | 
|  | 523 | 
|  | 524   root.reset(JSONReader::Read("\"root\"")); | 
|  | 525   ASSERT_TRUE(root.get()); | 
|  | 526   EXPECT_TRUE(root->GetAsString(&str_val)); | 
|  | 527   EXPECT_EQ("root", str_val); | 
| 498 } | 528 } | 
| 499 | 529 | 
| 500 TEST(JSONReaderTest, ReadFromFile) { | 530 TEST(JSONReaderTest, ReadFromFile) { | 
| 501   FilePath path; | 531   FilePath path; | 
| 502   ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &path)); | 532   ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &path)); | 
| 503   path = path.Append(FILE_PATH_LITERAL("base")) | 533   path = path.Append(FILE_PATH_LITERAL("base")) | 
| 504              .Append(FILE_PATH_LITERAL("data")) | 534              .Append(FILE_PATH_LITERAL("data")) | 
| 505              .Append(FILE_PATH_LITERAL("json")); | 535              .Append(FILE_PATH_LITERAL("json")); | 
| 506 | 536 | 
| 507   std::string input; | 537   std::string input; | 
| 508   ASSERT_TRUE(file_util::ReadFileToString( | 538   ASSERT_TRUE(file_util::ReadFileToString( | 
| 509       path.Append(FILE_PATH_LITERAL("bom_feff.json")), &input)); | 539       path.Append(FILE_PATH_LITERAL("bom_feff.json")), &input)); | 
| 510 | 540 | 
| 511   JSONReader reader; | 541   JSONReader reader; | 
| 512   std::string error_msg; | 542   scoped_ptr<Value> root(reader.ReadToValue(input)); | 
| 513   scoped_ptr<Value> root( |  | 
| 514       JSONReader::ReadAndReturnError(input, JSON_PARSE_RFC, NULL, &error_msg)); |  | 
| 515   ASSERT_TRUE(root.get()) << reader.GetErrorMessage(); | 543   ASSERT_TRUE(root.get()) << reader.GetErrorMessage(); | 
| 516   EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | 544   EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | 
| 517 } | 545 } | 
| 518 | 546 | 
| 519 TEST(JSONReaderTest, ErrorMessages) { | 547 // Tests that the root of a JSON object can be deleted safely while its | 
| 520   // Error strings should not be modified in case of success. | 548 // children outlive it. | 
| 521   std::string error_message; | 549 TEST(JSONReaderTest, StringOptimizations) { | 
| 522   int error_code = 0; | 550   Value* dict_literals[2] = {0}; | 
| 523   scoped_ptr<Value> root; | 551   Value* dict_strings[2] = {0}; | 
| 524   root.reset(JSONReader::ReadAndReturnError("[42]", JSON_PARSE_RFC, | 552   Value* list_values[2] = {0}; | 
| 525                                             &error_code, &error_message)); |  | 
| 526   EXPECT_TRUE(error_message.empty()); |  | 
| 527   EXPECT_EQ(0, error_code); |  | 
| 528 | 553 | 
| 529   // Test line and column counting | 554   { | 
| 530   const char* big_json = "[\n0,\n1,\n2,\n3,4,5,6 7,\n8,\n9\n]"; | 555     scoped_ptr<Value> root(JSONReader::Read( | 
| 531   // error here --------------------------------^ | 556         "{" | 
| 532   root.reset(JSONReader::ReadAndReturnError(big_json, JSON_PARSE_RFC, | 557         "  \"test\": {" | 
| 533                                             &error_code, &error_message)); | 558         "    \"foo\": true," | 
| 534   EXPECT_FALSE(root.get()); | 559         "    \"bar\": 3.14," | 
| 535   EXPECT_EQ(JSONReader::FormatErrorMessage(5, 9, JSONReader::kSyntaxError), | 560         "    \"baz\": \"bat\"," | 
| 536             error_message); | 561         "    \"moo\": \"cow\"" | 
| 537   EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code); | 562         "  }," | 
|  | 563         "  \"list\": [" | 
|  | 564         "    \"a\"," | 
|  | 565         "    \"b\"" | 
|  | 566         "  ]" | 
|  | 567         "}", JSON_DETACHABLE_CHILDREN)); | 
|  | 568     ASSERT_TRUE(root.get()); | 
| 538 | 569 | 
| 539   // Test each of the error conditions | 570     DictionaryValue* root_dict = NULL; | 
| 540   root.reset(JSONReader::ReadAndReturnError("{},{}", JSON_PARSE_RFC, | 571     ASSERT_TRUE(root->GetAsDictionary(&root_dict)); | 
| 541                                             &error_code, &error_message)); |  | 
| 542   EXPECT_FALSE(root.get()); |  | 
| 543   EXPECT_EQ(JSONReader::FormatErrorMessage(1, 3, |  | 
| 544       JSONReader::kUnexpectedDataAfterRoot), error_message); |  | 
| 545   EXPECT_EQ(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, error_code); |  | 
| 546 | 572 | 
| 547   std::string nested_json; | 573     DictionaryValue* dict = NULL; | 
| 548   for (int i = 0; i < 101; ++i) { | 574     ListValue* list = NULL; | 
| 549     nested_json.insert(nested_json.begin(), '['); | 575 | 
| 550     nested_json.append(1, ']'); | 576     ASSERT_TRUE(root_dict->GetDictionary("test", &dict)); | 
|  | 577     ASSERT_TRUE(root_dict->GetList("list", &list)); | 
|  | 578 | 
|  | 579     EXPECT_TRUE(dict->Remove("foo", &dict_literals[0])); | 
|  | 580     EXPECT_TRUE(dict->Remove("bar", &dict_literals[1])); | 
|  | 581     EXPECT_TRUE(dict->Remove("baz", &dict_strings[0])); | 
|  | 582     EXPECT_TRUE(dict->Remove("moo", &dict_strings[1])); | 
|  | 583 | 
|  | 584     ASSERT_EQ(2u, list->GetSize()); | 
|  | 585     EXPECT_TRUE(list->Remove(0, &list_values[0])); | 
|  | 586     EXPECT_TRUE(list->Remove(0, &list_values[1])); | 
| 551   } | 587   } | 
| 552   root.reset(JSONReader::ReadAndReturnError(nested_json, JSON_PARSE_RFC, |  | 
| 553                                             &error_code, &error_message)); |  | 
| 554   EXPECT_FALSE(root.get()); |  | 
| 555   EXPECT_EQ(JSONReader::FormatErrorMessage(1, 101, JSONReader::kTooMuchNesting), |  | 
| 556             error_message); |  | 
| 557   EXPECT_EQ(JSONReader::JSON_TOO_MUCH_NESTING, error_code); |  | 
| 558 | 588 | 
| 559   root.reset(JSONReader::ReadAndReturnError("[1,]", JSON_PARSE_RFC, | 589   bool b = false; | 
| 560                                             &error_code, &error_message)); | 590   double d = 0; | 
| 561   EXPECT_FALSE(root.get()); | 591   std::string s; | 
| 562   EXPECT_EQ(JSONReader::FormatErrorMessage(1, 4, JSONReader::kTrailingComma), |  | 
| 563             error_message); |  | 
| 564   EXPECT_EQ(JSONReader::JSON_TRAILING_COMMA, error_code); |  | 
| 565 | 592 | 
| 566   root.reset(JSONReader::ReadAndReturnError("{foo:\"bar\"}", JSON_PARSE_RFC, | 593   EXPECT_TRUE(dict_literals[0]->GetAsBoolean(&b)); | 
| 567                                             &error_code, &error_message)); | 594   EXPECT_TRUE(b); | 
| 568   EXPECT_FALSE(root.get()); |  | 
| 569   EXPECT_EQ(JSONReader::FormatErrorMessage(1, 2, |  | 
| 570       JSONReader::kUnquotedDictionaryKey), error_message); |  | 
| 571   EXPECT_EQ(JSONReader::JSON_UNQUOTED_DICTIONARY_KEY, error_code); |  | 
| 572 | 595 | 
| 573   root.reset(JSONReader::ReadAndReturnError("{\"foo\":\"bar\",}", | 596   EXPECT_TRUE(dict_literals[1]->GetAsDouble(&d)); | 
| 574                                             JSON_PARSE_RFC, | 597   EXPECT_EQ(3.14, d); | 
| 575                                             &error_code, |  | 
| 576                                             &error_message)); |  | 
| 577   EXPECT_FALSE(root.get()); |  | 
| 578   EXPECT_EQ(JSONReader::FormatErrorMessage(1, 14, JSONReader::kTrailingComma), |  | 
| 579             error_message); |  | 
| 580 | 598 | 
| 581   root.reset(JSONReader::ReadAndReturnError("[nu]", JSON_PARSE_RFC, | 599   EXPECT_TRUE(dict_strings[0]->GetAsString(&s)); | 
| 582                                             &error_code, &error_message)); | 600   EXPECT_EQ("bat", s); | 
| 583   EXPECT_FALSE(root.get()); |  | 
| 584   EXPECT_EQ(JSONReader::FormatErrorMessage(1, 2, JSONReader::kSyntaxError), |  | 
| 585             error_message); |  | 
| 586   EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code); |  | 
| 587 | 601 | 
| 588   root.reset(JSONReader::ReadAndReturnError("[\"xxx\\xq\"]", JSON_PARSE_RFC, | 602   EXPECT_TRUE(dict_strings[1]->GetAsString(&s)); | 
| 589                                             &error_code, &error_message)); | 603   EXPECT_EQ("cow", s); | 
| 590   EXPECT_FALSE(root.get()); |  | 
| 591   EXPECT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape), |  | 
| 592             error_message); |  | 
| 593   EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code); |  | 
| 594 | 604 | 
| 595   root.reset(JSONReader::ReadAndReturnError("[\"xxx\\uq\"]", JSON_PARSE_RFC, | 605   EXPECT_TRUE(list_values[0]->GetAsString(&s)); | 
| 596                                             &error_code, &error_message)); | 606   EXPECT_EQ("a", s); | 
| 597   EXPECT_FALSE(root.get()); | 607   EXPECT_TRUE(list_values[1]->GetAsString(&s)); | 
| 598   EXPECT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape), | 608   EXPECT_EQ("b", s); | 
| 599             error_message); |  | 
| 600   EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code); |  | 
| 601 | 609 | 
| 602   root.reset(JSONReader::ReadAndReturnError("[\"xxx\\q\"]", JSON_PARSE_RFC, | 610   delete dict_literals[0]; | 
| 603                                             &error_code, &error_message)); | 611   delete dict_literals[1]; | 
| 604   EXPECT_FALSE(root.get()); | 612   delete dict_strings[0]; | 
| 605   EXPECT_EQ(JSONReader::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape), | 613   delete dict_strings[1]; | 
| 606             error_message); | 614   delete list_values[0]; | 
| 607   EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code); | 615   delete list_values[1]; | 
|  | 616 } | 
|  | 617 | 
|  | 618 // A smattering of invalid JSON designed to test specific portions of the | 
|  | 619 // parser implementation against buffer overflow. Best run with DCHECKs so | 
|  | 620 // that the one in NextChar fires. | 
|  | 621 TEST(JSONReaderTest, InvalidSanity) { | 
|  | 622   const char* invalid_json[] = { | 
|  | 623       "/* test *", | 
|  | 624       "{\"foo\"", | 
|  | 625       "{\"foo\":", | 
|  | 626       "  [", | 
|  | 627       "\"\\u123g\"", | 
|  | 628       "{\n\"eh:\n}", | 
|  | 629   }; | 
|  | 630 | 
|  | 631   for (size_t i = 0; i < arraysize(invalid_json); ++i) { | 
|  | 632     JSONReader reader; | 
|  | 633     LOG(INFO) << "Sanity test " << i << ": <" << invalid_json[i] << ">"; | 
|  | 634     EXPECT_FALSE(reader.ReadToValue(invalid_json[i])); | 
|  | 635     EXPECT_NE(JSONReader::JSON_NO_ERROR, reader.error_code()); | 
|  | 636     EXPECT_NE("", reader.GetErrorMessage()); | 
|  | 637   } | 
|  | 638 } | 
|  | 639 | 
|  | 640 TEST(JSONReaderTest, IllegalTrailingNull) { | 
|  | 641   const char json[] = { '"', 'n', 'u', 'l', 'l', '"', '\0' }; | 
|  | 642   std::string json_string(json, sizeof(json)); | 
|  | 643   JSONReader reader; | 
|  | 644   EXPECT_FALSE(reader.ReadToValue(json_string)); | 
|  | 645   EXPECT_EQ(JSONReader::JSON_UNEXPECTED_DATA_AFTER_ROOT, reader.error_code()); | 
| 608 } | 646 } | 
| 609 | 647 | 
| 610 }  // namespace base | 648 }  // namespace base | 
| OLD | NEW | 
|---|