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_parser.h" | 5 #include "base/json/json_parser.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... | |
21 public: | 21 public: |
22 JSONParser* NewTestParser(const std::string& input, | 22 JSONParser* NewTestParser(const std::string& input, |
23 int options = JSON_PARSE_RFC) { | 23 int options = JSON_PARSE_RFC) { |
24 JSONParser* parser = new JSONParser(options); | 24 JSONParser* parser = new JSONParser(options); |
25 parser->start_pos_ = input.data(); | 25 parser->start_pos_ = input.data(); |
26 parser->pos_ = parser->start_pos_; | 26 parser->pos_ = parser->start_pos_; |
27 parser->end_pos_ = parser->start_pos_ + input.length(); | 27 parser->end_pos_ = parser->start_pos_ + input.length(); |
28 return parser; | 28 return parser; |
29 } | 29 } |
30 | 30 |
31 // MSan will do a better job detecting over-read errors if the input is | |
32 // not nul-terminated on the heap. This will copy |input| to a new buffer | |
33 // owned by |owner|, returning a StringPiece to |owner|. | |
34 StringPiece MakeNullTerminatedInput(const char* input, | |
jdoerrie
2017/05/05 09:34:11
nit: MakeNonNullTerminatedInput
Robert Sesek
2017/05/05 21:20:50
Done.
| |
35 std::unique_ptr<char[]>* owner) { | |
36 size_t str_len = strlen(input); | |
37 owner->reset(new char[str_len]); | |
38 memcpy(owner->get(), input, str_len); | |
39 return StringPiece(owner->get(), str_len); | |
40 } | |
41 | |
31 void TestLastThree(JSONParser* parser) { | 42 void TestLastThree(JSONParser* parser) { |
32 EXPECT_EQ(',', *parser->NextChar()); | 43 EXPECT_EQ(',', *parser->NextChar()); |
33 EXPECT_EQ('|', *parser->NextChar()); | 44 EXPECT_EQ('|', *parser->NextChar()); |
34 EXPECT_EQ('\0', *parser->NextChar()); | 45 EXPECT_EQ('\0', *parser->NextChar()); |
35 EXPECT_EQ(parser->end_pos_, parser->pos_); | 46 EXPECT_EQ(parser->end_pos_, parser->pos_); |
36 } | 47 } |
37 }; | 48 }; |
38 | 49 |
39 TEST_F(JSONParserTest, NextChar) { | 50 TEST_F(JSONParserTest, NextChar) { |
40 std::string input("Hello world"); | 51 std::string input("Hello world"); |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 {"9e-3", true, 0.009}, | 371 {"9e-3", true, 0.009}, |
361 {"2e+", false, 0}, | 372 {"2e+", false, 0}, |
362 {"2e+2", true, 200}, | 373 {"2e+2", true, 200}, |
363 // clang-format on | 374 // clang-format on |
364 }; | 375 }; |
365 | 376 |
366 for (unsigned int i = 0; i < arraysize(kCases); ++i) { | 377 for (unsigned int i = 0; i < arraysize(kCases); ++i) { |
367 auto test_case = kCases[i]; | 378 auto test_case = kCases[i]; |
368 SCOPED_TRACE(StringPrintf("case %u: \"%s\"", i, test_case.input)); | 379 SCOPED_TRACE(StringPrintf("case %u: \"%s\"", i, test_case.input)); |
369 | 380 |
370 // MSan will do a better job detecting over-read errors if the input is | 381 std::unique_ptr<char[]> input_owner; |
371 // not nul-terminated on the heap. | 382 StringPiece input = MakeNullTerminatedInput(test_case.input, &input_owner); |
372 size_t str_len = strlen(test_case.input); | |
373 auto non_nul_termianted = MakeUnique<char[]>(str_len); | |
374 memcpy(non_nul_termianted.get(), test_case.input, str_len); | |
375 | 383 |
376 StringPiece string_piece(non_nul_termianted.get(), str_len); | 384 std::unique_ptr<Value> result = JSONReader::Read(input); |
377 std::unique_ptr<Value> result = JSONReader::Read(string_piece); | |
378 if (test_case.parse_success) { | 385 if (test_case.parse_success) { |
379 EXPECT_TRUE(result); | 386 EXPECT_TRUE(result); |
380 } else { | 387 } else { |
381 EXPECT_FALSE(result); | 388 EXPECT_FALSE(result); |
382 } | 389 } |
383 | 390 |
384 if (!result) | 391 if (!result) |
385 continue; | 392 continue; |
386 | 393 |
387 double double_value = 0; | 394 double double_value = 0; |
388 EXPECT_TRUE(result->GetAsDouble(&double_value)); | 395 EXPECT_TRUE(result->GetAsDouble(&double_value)); |
389 EXPECT_EQ(test_case.value, double_value); | 396 EXPECT_EQ(test_case.value, double_value); |
390 } | 397 } |
391 } | 398 } |
392 | 399 |
400 TEST_F(JSONParserTest, UnterminatedInputs) { | |
401 const char* kCases[] = { | |
402 // clang-format off | |
403 "/", | |
404 "//", | |
405 "/*", | |
406 "\"xxxxxx", | |
407 "\"", | |
408 "{ ", | |
409 "[\t", | |
410 // clang-format on | |
411 }; | |
412 | |
413 for (unsigned int i = 0; i < arraysize(kCases); ++i) { | |
414 auto* test_case = kCases[i]; | |
415 SCOPED_TRACE(StringPrintf("case %u: \"%s\"", i, test_case)); | |
416 | |
417 std::unique_ptr<char[]> input_owner; | |
418 StringPiece input = MakeNullTerminatedInput(test_case, &input_owner); | |
419 | |
420 EXPECT_FALSE(JSONReader::Read(input)); | |
421 } | |
422 } | |
423 | |
393 } // namespace internal | 424 } // namespace internal |
394 } // namespace base | 425 } // namespace base |
OLD | NEW |