| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // http://code.google.com/p/protobuf/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| 11 // * Redistributions in binary form must reproduce the above | 11 // * Redistributions in binary form must reproduce the above |
| 12 // copyright notice, this list of conditions and the following disclaimer | 12 // copyright notice, this list of conditions and the following disclaimer |
| 13 // in the documentation and/or other materials provided with the | 13 // in the documentation and/or other materials provided with the |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 // Test that sh-style comments are not ignored by default. | 404 // Test that sh-style comments are not ignored by default. |
| 405 { "foo # bar\n" | 405 { "foo # bar\n" |
| 406 "baz", { | 406 "baz", { |
| 407 { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, | 407 { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, |
| 408 { Tokenizer::TYPE_SYMBOL , "#" , 0, 4, 5 }, | 408 { Tokenizer::TYPE_SYMBOL , "#" , 0, 4, 5 }, |
| 409 { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6, 9 }, | 409 { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6, 9 }, |
| 410 { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0, 3 }, | 410 { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0, 3 }, |
| 411 { Tokenizer::TYPE_END , "" , 1, 3, 3 }, | 411 { Tokenizer::TYPE_END , "" , 1, 3, 3 }, |
| 412 }}, | 412 }}, |
| 413 | 413 |
| 414 // Bytes with the high-order bit set should not be seen as control characters. | |
| 415 { "\300", { | |
| 416 { Tokenizer::TYPE_SYMBOL, "\300", 0, 0, 1 }, | |
| 417 { Tokenizer::TYPE_END , "" , 0, 1, 1 }, | |
| 418 }}, | |
| 419 | |
| 420 // Test all whitespace chars | 414 // Test all whitespace chars |
| 421 { "foo\n\t\r\v\fbar", { | 415 { "foo\n\t\r\v\fbar", { |
| 422 { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, | 416 { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, |
| 423 { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11, 14 }, | 417 { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11, 14 }, |
| 424 { Tokenizer::TYPE_END , "" , 1, 14, 14 }, | 418 { Tokenizer::TYPE_END , "" , 1, 14, 14 }, |
| 425 }}, | 419 }}, |
| 426 }; | 420 }; |
| 427 | 421 |
| 428 TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) { | 422 TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) { |
| 429 // Set up the tokenizer. | 423 // Set up the tokenizer. |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 EXPECT_EQ(0xabcdef12u, ParseInteger("0xabcdef12")); | 728 EXPECT_EQ(0xabcdef12u, ParseInteger("0xabcdef12")); |
| 735 EXPECT_EQ(0xabcdef12u, ParseInteger("0xABCDEF12")); | 729 EXPECT_EQ(0xabcdef12u, ParseInteger("0xABCDEF12")); |
| 736 EXPECT_EQ(kuint64max, ParseInteger("0xFFFFFFFFFFFFFFFF")); | 730 EXPECT_EQ(kuint64max, ParseInteger("0xFFFFFFFFFFFFFFFF")); |
| 737 EXPECT_EQ(01234567, ParseInteger("01234567")); | 731 EXPECT_EQ(01234567, ParseInteger("01234567")); |
| 738 EXPECT_EQ(0X123, ParseInteger("0X123")); | 732 EXPECT_EQ(0X123, ParseInteger("0X123")); |
| 739 | 733 |
| 740 // Test invalid integers that may still be tokenized as integers. | 734 // Test invalid integers that may still be tokenized as integers. |
| 741 EXPECT_EQ(0, ParseInteger("0x")); | 735 EXPECT_EQ(0, ParseInteger("0x")); |
| 742 | 736 |
| 743 uint64 i; | 737 uint64 i; |
| 744 #ifdef PROTOBUF_HASDEATH_TEST // death tests do not work on Windows yet | 738 #ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet |
| 745 // Test invalid integers that will never be tokenized as integers. | 739 // Test invalid integers that will never be tokenized as integers. |
| 746 EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("zxy", kuint64max, &i), | 740 EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("zxy", kuint64max, &i), |
| 747 "passed text that could not have been tokenized as an integer"); | 741 "passed text that could not have been tokenized as an integer"); |
| 748 EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("1.2", kuint64max, &i), | 742 EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("1.2", kuint64max, &i), |
| 749 "passed text that could not have been tokenized as an integer"); | 743 "passed text that could not have been tokenized as an integer"); |
| 750 EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("08", kuint64max, &i), | 744 EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("08", kuint64max, &i), |
| 751 "passed text that could not have been tokenized as an integer"); | 745 "passed text that could not have been tokenized as an integer"); |
| 752 EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("0xg", kuint64max, &i), | 746 EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("0xg", kuint64max, &i), |
| 753 "passed text that could not have been tokenized as an integer"); | 747 "passed text that could not have been tokenized as an integer"); |
| 754 EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("-1", kuint64max, &i), | 748 EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("-1", kuint64max, &i), |
| 755 "passed text that could not have been tokenized as an integer"); | 749 "passed text that could not have been tokenized as an integer"); |
| 756 #endif // PROTOBUF_HASDEATH_TEST | 750 #endif // PROTOBUF_HAS_DEATH_TEST |
| 757 | 751 |
| 758 // Test overflows. | 752 // Test overflows. |
| 759 EXPECT_TRUE (Tokenizer::ParseInteger("0", 0, &i)); | 753 EXPECT_TRUE (Tokenizer::ParseInteger("0", 0, &i)); |
| 760 EXPECT_FALSE(Tokenizer::ParseInteger("1", 0, &i)); | 754 EXPECT_FALSE(Tokenizer::ParseInteger("1", 0, &i)); |
| 761 EXPECT_TRUE (Tokenizer::ParseInteger("1", 1, &i)); | 755 EXPECT_TRUE (Tokenizer::ParseInteger("1", 1, &i)); |
| 762 EXPECT_TRUE (Tokenizer::ParseInteger("12345", 12345, &i)); | 756 EXPECT_TRUE (Tokenizer::ParseInteger("12345", 12345, &i)); |
| 763 EXPECT_FALSE(Tokenizer::ParseInteger("12346", 12345, &i)); | 757 EXPECT_FALSE(Tokenizer::ParseInteger("12346", 12345, &i)); |
| 764 EXPECT_TRUE (Tokenizer::ParseInteger("0xFFFFFFFFFFFFFFFF" , kuint64max, &i)); | 758 EXPECT_TRUE (Tokenizer::ParseInteger("0xFFFFFFFFFFFFFFFF" , kuint64max, &i)); |
| 765 EXPECT_FALSE(Tokenizer::ParseInteger("0x10000000000000000", kuint64max, &i)); | 759 EXPECT_FALSE(Tokenizer::ParseInteger("0x10000000000000000", kuint64max, &i)); |
| 766 } | 760 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 789 // Test 'f' suffix. | 783 // Test 'f' suffix. |
| 790 EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1f")); | 784 EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1f")); |
| 791 EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.0f")); | 785 EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.0f")); |
| 792 EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1F")); | 786 EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1F")); |
| 793 | 787 |
| 794 // These should parse successfully even though they are out of range. | 788 // These should parse successfully even though they are out of range. |
| 795 // Overflows become infinity and underflows become zero. | 789 // Overflows become infinity and underflows become zero. |
| 796 EXPECT_EQ( 0.0, Tokenizer::ParseFloat("1e-9999999999999999999999999999")); | 790 EXPECT_EQ( 0.0, Tokenizer::ParseFloat("1e-9999999999999999999999999999")); |
| 797 EXPECT_EQ(HUGE_VAL, Tokenizer::ParseFloat("1e+9999999999999999999999999999")); | 791 EXPECT_EQ(HUGE_VAL, Tokenizer::ParseFloat("1e+9999999999999999999999999999")); |
| 798 | 792 |
| 799 #ifdef PROTOBUF_HASDEATH_TEST // death tests do not work on Windows yet | 793 #ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet |
| 800 // Test invalid integers that will never be tokenized as integers. | 794 // Test invalid integers that will never be tokenized as integers. |
| 801 EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("zxy"), | 795 EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("zxy"), |
| 802 "passed text that could not have been tokenized as a float"); | 796 "passed text that could not have been tokenized as a float"); |
| 803 EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("1-e0"), | 797 EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("1-e0"), |
| 804 "passed text that could not have been tokenized as a float"); | 798 "passed text that could not have been tokenized as a float"); |
| 805 EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("-1.0"), | 799 EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("-1.0"), |
| 806 "passed text that could not have been tokenized as a float"); | 800 "passed text that could not have been tokenized as a float"); |
| 807 #endif // PROTOBUF_HASDEATH_TEST | 801 #endif // PROTOBUF_HAS_DEATH_TEST |
| 808 } | 802 } |
| 809 | 803 |
| 810 TEST_F(TokenizerTest, ParseString) { | 804 TEST_F(TokenizerTest, ParseString) { |
| 811 string output; | 805 string output; |
| 812 Tokenizer::ParseString("'hello'", &output); | 806 Tokenizer::ParseString("'hello'", &output); |
| 813 EXPECT_EQ("hello", output); | 807 EXPECT_EQ("hello", output); |
| 814 Tokenizer::ParseString("\"blah\\nblah2\"", &output); | 808 Tokenizer::ParseString("\"blah\\nblah2\"", &output); |
| 815 EXPECT_EQ("blah\nblah2", output); | 809 EXPECT_EQ("blah\nblah2", output); |
| 816 Tokenizer::ParseString("'\\1x\\1\\123\\739\\52\\334n\\3'", &output); | 810 Tokenizer::ParseString("'\\1x\\1\\123\\739\\52\\334n\\3'", &output); |
| 817 EXPECT_EQ("\1x\1\123\739\52\334n\3", output); | 811 EXPECT_EQ("\1x\1\123\739\52\334n\3", output); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 836 // Here's some broken UTF16; there's a head surrogate with no tail surrogate. | 830 // Here's some broken UTF16; there's a head surrogate with no tail surrogate. |
| 837 // We just output this as if it were UTF8; it's not a defined code point, but | 831 // We just output this as if it were UTF8; it's not a defined code point, but |
| 838 // it has a defined encoding. | 832 // it has a defined encoding. |
| 839 Tokenizer::ParseString("'\\ud852XX'", &output); | 833 Tokenizer::ParseString("'\\ud852XX'", &output); |
| 840 EXPECT_EQ("\xed\xa1\x92XX", output); | 834 EXPECT_EQ("\xed\xa1\x92XX", output); |
| 841 // Malformed escape: Demons may fly out of the nose. | 835 // Malformed escape: Demons may fly out of the nose. |
| 842 Tokenizer::ParseString("\\u0", &output); | 836 Tokenizer::ParseString("\\u0", &output); |
| 843 EXPECT_EQ("u0", output); | 837 EXPECT_EQ("u0", output); |
| 844 | 838 |
| 845 // Test invalid strings that will never be tokenized as strings. | 839 // Test invalid strings that will never be tokenized as strings. |
| 846 #ifdef PROTOBUF_HASDEATH_TEST // death tests do not work on Windows yet | 840 #ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet |
| 847 EXPECT_DEBUG_DEATH(Tokenizer::ParseString("", &output), | 841 EXPECT_DEBUG_DEATH(Tokenizer::ParseString("", &output), |
| 848 "passed text that could not have been tokenized as a string"); | 842 "passed text that could not have been tokenized as a string"); |
| 849 #endif // PROTOBUF_HASDEATH_TEST | 843 #endif // PROTOBUF_HAS_DEATH_TEST |
| 850 } | 844 } |
| 851 | 845 |
| 852 TEST_F(TokenizerTest, ParseStringAppend) { | 846 TEST_F(TokenizerTest, ParseStringAppend) { |
| 853 // Check that ParseString and ParseStringAppend differ. | 847 // Check that ParseString and ParseStringAppend differ. |
| 854 string output("stuff+"); | 848 string output("stuff+"); |
| 855 Tokenizer::ParseStringAppend("'hello'", &output); | 849 Tokenizer::ParseStringAppend("'hello'", &output); |
| 856 EXPECT_EQ("stuff+hello", output); | 850 EXPECT_EQ("stuff+hello", output); |
| 857 Tokenizer::ParseString("'hello'", &output); | 851 Tokenizer::ParseString("'hello'", &output); |
| 858 EXPECT_EQ("hello", output); | 852 EXPECT_EQ("hello", output); |
| 859 } | 853 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 876 return out << CEscape(test_case.input); | 870 return out << CEscape(test_case.input); |
| 877 } | 871 } |
| 878 | 872 |
| 879 ErrorCase kErrorCases[] = { | 873 ErrorCase kErrorCases[] = { |
| 880 // String errors. | 874 // String errors. |
| 881 { "'\\l' foo", true, | 875 { "'\\l' foo", true, |
| 882 "0:2: Invalid escape sequence in string literal.\n" }, | 876 "0:2: Invalid escape sequence in string literal.\n" }, |
| 883 { "'\\x' foo", true, | 877 { "'\\x' foo", true, |
| 884 "0:3: Expected hex digits for escape sequence.\n" }, | 878 "0:3: Expected hex digits for escape sequence.\n" }, |
| 885 { "'foo", false, | 879 { "'foo", false, |
| 886 "0:4: String literals cannot cross line boundaries.\n" }, | 880 "0:4: Unexpected end of string.\n" }, |
| 887 { "'bar\nfoo", true, | 881 { "'bar\nfoo", true, |
| 888 "0:4: String literals cannot cross line boundaries.\n" }, | 882 "0:4: String literals cannot cross line boundaries.\n" }, |
| 889 { "'\\u01' foo", true, | 883 { "'\\u01' foo", true, |
| 890 "0:5: Expected four hex digits for \\u escape sequence.\n" }, | 884 "0:5: Expected four hex digits for \\u escape sequence.\n" }, |
| 891 { "'\\u01' foo", true, | 885 { "'\\u01' foo", true, |
| 892 "0:5: Expected four hex digits for \\u escape sequence.\n" }, | 886 "0:5: Expected four hex digits for \\u escape sequence.\n" }, |
| 893 { "'\\uXYZ' foo", true, | 887 { "'\\uXYZ' foo", true, |
| 894 "0:3: Expected four hex digits for \\u escape sequence.\n" }, | 888 "0:3: Expected four hex digits for \\u escape sequence.\n" }, |
| 895 | 889 |
| 896 // Integer errors. | 890 // Integer errors. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 "0:0: Invalid control characters encountered in text.\n" }, | 938 "0:0: Invalid control characters encountered in text.\n" }, |
| 945 | 939 |
| 946 // Check recovery from '\0'. We have to explicitly specify the length of | 940 // Check recovery from '\0'. We have to explicitly specify the length of |
| 947 // these strings because otherwise the string constructor will just call | 941 // these strings because otherwise the string constructor will just call |
| 948 // strlen() which will see the first '\0' and think that is the end of the | 942 // strlen() which will see the first '\0' and think that is the end of the |
| 949 // string. | 943 // string. |
| 950 { string("\0foo", 4), true, | 944 { string("\0foo", 4), true, |
| 951 "0:0: Invalid control characters encountered in text.\n" }, | 945 "0:0: Invalid control characters encountered in text.\n" }, |
| 952 { string("\0\0foo", 5), true, | 946 { string("\0\0foo", 5), true, |
| 953 "0:0: Invalid control characters encountered in text.\n" }, | 947 "0:0: Invalid control characters encountered in text.\n" }, |
| 948 |
| 949 // Check error from high order bits set |
| 950 { "\300foo", true, |
| 951 "0:0: Interpreting non ascii codepoint 192.\n" }, |
| 954 }; | 952 }; |
| 955 | 953 |
| 956 TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) { | 954 TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) { |
| 957 // Set up the tokenizer. | 955 // Set up the tokenizer. |
| 958 TestInputStream input(kErrorCases_case.input.data(), | 956 TestInputStream input(kErrorCases_case.input.data(), |
| 959 kErrorCases_case.input.size(), | 957 kErrorCases_case.input.size(), |
| 960 kBlockSizes_case); | 958 kBlockSizes_case); |
| 961 TestErrorCollector error_collector; | 959 TestErrorCollector error_collector; |
| 962 Tokenizer tokenizer(&input, &error_collector); | 960 Tokenizer tokenizer(&input, &error_collector); |
| 963 | 961 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 992 | 990 |
| 993 // Only "foo" should have been read. | 991 // Only "foo" should have been read. |
| 994 EXPECT_EQ(strlen("foo"), input.ByteCount()); | 992 EXPECT_EQ(strlen("foo"), input.ByteCount()); |
| 995 } | 993 } |
| 996 | 994 |
| 997 | 995 |
| 998 } // namespace | 996 } // namespace |
| 999 } // namespace io | 997 } // namespace io |
| 1000 } // namespace protobuf | 998 } // namespace protobuf |
| 1001 } // namespace google | 999 } // namespace google |
| OLD | NEW |