Commit c56a9ca7f6484925627aa1da374a236949c07cb2
1 parent
47c093c4
JSON: Fix large file support
Showing
4 changed files
with
78 additions
and
68 deletions
include/qpdf/JSON.hh
| @@ -37,6 +37,7 @@ | @@ -37,6 +37,7 @@ | ||
| 37 | 37 | ||
| 38 | #include <qpdf/DLL.h> | 38 | #include <qpdf/DLL.h> |
| 39 | #include <qpdf/PointerHolder.hh> | 39 | #include <qpdf/PointerHolder.hh> |
| 40 | +#include <qpdf/Types.h> | ||
| 40 | 41 | ||
| 41 | #include <functional> | 42 | #include <functional> |
| 42 | #include <list> | 43 | #include <list> |
| @@ -299,13 +300,13 @@ class JSON | @@ -299,13 +300,13 @@ class JSON | ||
| 299 | // non-inclusive end offsets of an object relative to its input | 300 | // non-inclusive end offsets of an object relative to its input |
| 300 | // string. Otherwise, both values are 0. | 301 | // string. Otherwise, both values are 0. |
| 301 | QPDF_DLL | 302 | QPDF_DLL |
| 302 | - void setStart(size_t); | 303 | + void setStart(qpdf_offset_t); |
| 303 | QPDF_DLL | 304 | QPDF_DLL |
| 304 | - void setEnd(size_t); | 305 | + void setEnd(qpdf_offset_t); |
| 305 | QPDF_DLL | 306 | QPDF_DLL |
| 306 | - size_t getStart() const; | 307 | + qpdf_offset_t getStart() const; |
| 307 | QPDF_DLL | 308 | QPDF_DLL |
| 308 | - size_t getEnd() const; | 309 | + qpdf_offset_t getEnd() const; |
| 309 | 310 | ||
| 310 | private: | 311 | private: |
| 311 | static std::string encode_string(std::string const& utf8); | 312 | static std::string encode_string(std::string const& utf8); |
| @@ -391,8 +392,8 @@ class JSON | @@ -391,8 +392,8 @@ class JSON | ||
| 391 | 392 | ||
| 392 | std::shared_ptr<JSON_value> value; | 393 | std::shared_ptr<JSON_value> value; |
| 393 | // start and end are only populated for objects created by parse | 394 | // start and end are only populated for objects created by parse |
| 394 | - size_t start; | ||
| 395 | - size_t end; | 395 | + qpdf_offset_t start; |
| 396 | + qpdf_offset_t end; | ||
| 396 | }; | 397 | }; |
| 397 | 398 | ||
| 398 | std::shared_ptr<Members> m; | 399 | std::shared_ptr<Members> m; |
include/qpdf/QPDF.hh
| @@ -1046,7 +1046,7 @@ class QPDF | @@ -1046,7 +1046,7 @@ class QPDF | ||
| 1046 | void nestedState(std::string const& key, JSON const& value, state_e); | 1046 | void nestedState(std::string const& key, JSON const& value, state_e); |
| 1047 | void setObjectDescription(QPDFObjectHandle& oh, JSON const& value); | 1047 | void setObjectDescription(QPDFObjectHandle& oh, JSON const& value); |
| 1048 | QPDFObjectHandle makeObject(JSON const& value); | 1048 | QPDFObjectHandle makeObject(JSON const& value); |
| 1049 | - void error(size_t offset, std::string const& message); | 1049 | + void error(qpdf_offset_t offset, std::string const& message); |
| 1050 | QPDFObjectHandle | 1050 | QPDFObjectHandle |
| 1051 | reserveObject(int obj, int gen); | 1051 | reserveObject(int obj, int gen); |
| 1052 | void replaceObject( | 1052 | void replaceObject( |
libqpdf/JSON.cc
| @@ -4,11 +4,19 @@ | @@ -4,11 +4,19 @@ | ||
| 4 | #include <qpdf/Pl_Base64.hh> | 4 | #include <qpdf/Pl_Base64.hh> |
| 5 | #include <qpdf/Pl_Concatenate.hh> | 5 | #include <qpdf/Pl_Concatenate.hh> |
| 6 | #include <qpdf/Pl_String.hh> | 6 | #include <qpdf/Pl_String.hh> |
| 7 | +#include <qpdf/QIntC.hh> | ||
| 7 | #include <qpdf/QTC.hh> | 8 | #include <qpdf/QTC.hh> |
| 8 | #include <qpdf/QUtil.hh> | 9 | #include <qpdf/QUtil.hh> |
| 9 | #include <cstring> | 10 | #include <cstring> |
| 10 | #include <stdexcept> | 11 | #include <stdexcept> |
| 11 | 12 | ||
| 13 | +template <typename T> | ||
| 14 | +static qpdf_offset_t | ||
| 15 | +toO(T const& i) | ||
| 16 | +{ | ||
| 17 | + return QIntC::to_offset(i); | ||
| 18 | +} | ||
| 19 | + | ||
| 12 | JSON::Members::Members(std::shared_ptr<JSON_value> value) : | 20 | JSON::Members::Members(std::shared_ptr<JSON_value> value) : |
| 13 | value(value), | 21 | value(value), |
| 14 | start(0), | 22 | start(0), |
| @@ -591,13 +599,13 @@ namespace | @@ -591,13 +599,13 @@ namespace | ||
| 591 | void getToken(); | 599 | void getToken(); |
| 592 | void handleToken(); | 600 | void handleToken(); |
| 593 | static std::string | 601 | static std::string |
| 594 | - decode_string(std::string const& json, size_t offset); | 602 | + decode_string(std::string const& json, qpdf_offset_t offset); |
| 595 | static void handle_u_code( | 603 | static void handle_u_code( |
| 596 | char const* s, | 604 | char const* s, |
| 597 | - size_t offset, | ||
| 598 | - size_t i, | 605 | + qpdf_offset_t offset, |
| 606 | + qpdf_offset_t i, | ||
| 599 | unsigned long& high_surrogate, | 607 | unsigned long& high_surrogate, |
| 600 | - size_t& high_offset, | 608 | + qpdf_offset_t& high_offset, |
| 601 | std::string& result); | 609 | std::string& result); |
| 602 | 610 | ||
| 603 | enum parser_state_e { | 611 | enum parser_state_e { |
| @@ -633,25 +641,25 @@ namespace | @@ -633,25 +641,25 @@ namespace | ||
| 633 | char buf[16384]; | 641 | char buf[16384]; |
| 634 | size_t bytes; | 642 | size_t bytes; |
| 635 | char const* p; | 643 | char const* p; |
| 636 | - size_t u_count; | ||
| 637 | - size_t offset; | 644 | + qpdf_offset_t u_count; |
| 645 | + qpdf_offset_t offset; | ||
| 638 | bool done; | 646 | bool done; |
| 639 | std::string token; | 647 | std::string token; |
| 640 | parser_state_e parser_state; | 648 | parser_state_e parser_state; |
| 641 | std::vector<std::shared_ptr<JSON>> stack; | 649 | std::vector<std::shared_ptr<JSON>> stack; |
| 642 | std::vector<parser_state_e> ps_stack; | 650 | std::vector<parser_state_e> ps_stack; |
| 643 | std::string dict_key; | 651 | std::string dict_key; |
| 644 | - size_t dict_key_offset; | 652 | + qpdf_offset_t dict_key_offset; |
| 645 | }; | 653 | }; |
| 646 | } // namespace | 654 | } // namespace |
| 647 | 655 | ||
| 648 | void | 656 | void |
| 649 | JSONParser::handle_u_code( | 657 | JSONParser::handle_u_code( |
| 650 | char const* s, | 658 | char const* s, |
| 651 | - size_t offset, | ||
| 652 | - size_t i, | 659 | + qpdf_offset_t offset, |
| 660 | + qpdf_offset_t i, | ||
| 653 | unsigned long& high_surrogate, | 661 | unsigned long& high_surrogate, |
| 654 | - size_t& high_offset, | 662 | + qpdf_offset_t& high_offset, |
| 655 | std::string& result) | 663 | std::string& result) |
| 656 | { | 664 | { |
| 657 | std::string hex = QUtil::hex_decode(std::string(s + i + 1, s + i + 5)); | 665 | std::string hex = QUtil::hex_decode(std::string(s + i + 1, s + i + 5)); |
| @@ -662,14 +670,14 @@ JSONParser::handle_u_code( | @@ -662,14 +670,14 @@ JSONParser::handle_u_code( | ||
| 662 | codepoint += low; | 670 | codepoint += low; |
| 663 | if ((codepoint & 0xFC00) == 0xD800) { | 671 | if ((codepoint & 0xFC00) == 0xD800) { |
| 664 | // high surrogate | 672 | // high surrogate |
| 665 | - size_t new_high_offset = offset + i; | 673 | + qpdf_offset_t new_high_offset = offset + i; |
| 666 | if (high_offset) { | 674 | if (high_offset) { |
| 667 | QTC::TC("libtests", "JSON 16 high high"); | 675 | QTC::TC("libtests", "JSON 16 high high"); |
| 668 | throw std::runtime_error( | 676 | throw std::runtime_error( |
| 669 | - "JSON: offset " + QUtil::uint_to_string(new_high_offset) + | 677 | + "JSON: offset " + QUtil::int_to_string(new_high_offset) + |
| 670 | ": UTF-16 high surrogate found after previous high surrogate" | 678 | ": UTF-16 high surrogate found after previous high surrogate" |
| 671 | " at offset " + | 679 | " at offset " + |
| 672 | - QUtil::uint_to_string(high_offset)); | 680 | + QUtil::int_to_string(high_offset)); |
| 673 | } | 681 | } |
| 674 | high_offset = new_high_offset; | 682 | high_offset = new_high_offset; |
| 675 | high_surrogate = codepoint; | 683 | high_surrogate = codepoint; |
| @@ -678,7 +686,7 @@ JSONParser::handle_u_code( | @@ -678,7 +686,7 @@ JSONParser::handle_u_code( | ||
| 678 | if (offset + i != (high_offset + 6)) { | 686 | if (offset + i != (high_offset + 6)) { |
| 679 | QTC::TC("libtests", "JSON 16 low not after high"); | 687 | QTC::TC("libtests", "JSON 16 low not after high"); |
| 680 | throw std::runtime_error( | 688 | throw std::runtime_error( |
| 681 | - "JSON: offset " + QUtil::uint_to_string(offset + i) + | 689 | + "JSON: offset " + QUtil::int_to_string(offset + i) + |
| 682 | ": UTF-16 low surrogate found not immediately after high" | 690 | ": UTF-16 low surrogate found not immediately after high" |
| 683 | " surrogate"); | 691 | " surrogate"); |
| 684 | } | 692 | } |
| @@ -692,7 +700,7 @@ JSONParser::handle_u_code( | @@ -692,7 +700,7 @@ JSONParser::handle_u_code( | ||
| 692 | } | 700 | } |
| 693 | 701 | ||
| 694 | std::string | 702 | std::string |
| 695 | -JSONParser::decode_string(std::string const& str, size_t offset) | 703 | +JSONParser::decode_string(std::string const& str, qpdf_offset_t offset) |
| 696 | { | 704 | { |
| 697 | // The string has already been validated when this private method | 705 | // The string has already been validated when this private method |
| 698 | // is called, so errors are logic errors instead of runtime | 706 | // is called, so errors are logic errors instead of runtime |
| @@ -708,11 +716,12 @@ JSONParser::decode_string(std::string const& str, size_t offset) | @@ -708,11 +716,12 @@ JSONParser::decode_string(std::string const& str, size_t offset) | ||
| 708 | len -= 2; | 716 | len -= 2; |
| 709 | // Keep track of UTF-16 surrogate pairs. | 717 | // Keep track of UTF-16 surrogate pairs. |
| 710 | unsigned long high_surrogate = 0; | 718 | unsigned long high_surrogate = 0; |
| 711 | - size_t high_offset = 0; | 719 | + qpdf_offset_t high_offset = 0; |
| 712 | std::string result; | 720 | std::string result; |
| 713 | - for (size_t i = 0; i < len; ++i) { | 721 | + qpdf_offset_t olen = toO(len); |
| 722 | + for (qpdf_offset_t i = 0; i < olen; ++i) { | ||
| 714 | if (s[i] == '\\') { | 723 | if (s[i] == '\\') { |
| 715 | - if (i + 1 >= len) { | 724 | + if (i + 1 >= olen) { |
| 716 | throw std::logic_error("JSON parse: nothing after \\"); | 725 | throw std::logic_error("JSON parse: nothing after \\"); |
| 717 | } | 726 | } |
| 718 | char ch = s[++i]; | 727 | char ch = s[++i]; |
| @@ -740,7 +749,7 @@ JSONParser::decode_string(std::string const& str, size_t offset) | @@ -740,7 +749,7 @@ JSONParser::decode_string(std::string const& str, size_t offset) | ||
| 740 | result.append(1, '\t'); | 749 | result.append(1, '\t'); |
| 741 | break; | 750 | break; |
| 742 | case 'u': | 751 | case 'u': |
| 743 | - if (i + 4 >= len) { | 752 | + if (i + 4 >= olen) { |
| 744 | throw std::logic_error( | 753 | throw std::logic_error( |
| 745 | "JSON parse: not enough characters after \\u"); | 754 | "JSON parse: not enough characters after \\u"); |
| 746 | } | 755 | } |
| @@ -759,7 +768,7 @@ JSONParser::decode_string(std::string const& str, size_t offset) | @@ -759,7 +768,7 @@ JSONParser::decode_string(std::string const& str, size_t offset) | ||
| 759 | if (high_offset) { | 768 | if (high_offset) { |
| 760 | QTC::TC("libtests", "JSON 16 dangling high"); | 769 | QTC::TC("libtests", "JSON 16 dangling high"); |
| 761 | throw std::runtime_error( | 770 | throw std::runtime_error( |
| 762 | - "JSON: offset " + QUtil::uint_to_string(high_offset) + | 771 | + "JSON: offset " + QUtil::int_to_string(high_offset) + |
| 763 | ": UTF-16 high surrogate not followed by low surrogate"); | 772 | ": UTF-16 high surrogate not followed by low surrogate"); |
| 764 | } | 773 | } |
| 765 | return result; | 774 | return result; |
| @@ -785,7 +794,7 @@ JSONParser::getToken() | @@ -785,7 +794,7 @@ JSONParser::getToken() | ||
| 785 | QTC::TC("libtests", "JSON parse null character"); | 794 | QTC::TC("libtests", "JSON parse null character"); |
| 786 | throw std::runtime_error( | 795 | throw std::runtime_error( |
| 787 | "JSON: null character at offset " + | 796 | "JSON: null character at offset " + |
| 788 | - QUtil::uint_to_string(offset)); | 797 | + QUtil::int_to_string(offset)); |
| 789 | } | 798 | } |
| 790 | action = append; | 799 | action = append; |
| 791 | switch (lex_state) { | 800 | switch (lex_state) { |
| @@ -822,7 +831,7 @@ JSONParser::getToken() | @@ -822,7 +831,7 @@ JSONParser::getToken() | ||
| 822 | } else { | 831 | } else { |
| 823 | QTC::TC("libtests", "JSON parse bad character"); | 832 | QTC::TC("libtests", "JSON parse bad character"); |
| 824 | throw std::runtime_error( | 833 | throw std::runtime_error( |
| 825 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 834 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 826 | ": unexpected character " + std::string(p, 1)); | 835 | ": unexpected character " + std::string(p, 1)); |
| 827 | } | 836 | } |
| 828 | break; | 837 | break; |
| @@ -840,12 +849,12 @@ JSONParser::getToken() | @@ -840,12 +849,12 @@ JSONParser::getToken() | ||
| 840 | if (number_saw_e) { | 849 | if (number_saw_e) { |
| 841 | QTC::TC("libtests", "JSON parse point after e"); | 850 | QTC::TC("libtests", "JSON parse point after e"); |
| 842 | throw std::runtime_error( | 851 | throw std::runtime_error( |
| 843 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 852 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 844 | ": numeric literal: decimal point after e"); | 853 | ": numeric literal: decimal point after e"); |
| 845 | } else if (number_saw_point) { | 854 | } else if (number_saw_point) { |
| 846 | QTC::TC("libtests", "JSON parse duplicate point"); | 855 | QTC::TC("libtests", "JSON parse duplicate point"); |
| 847 | throw std::runtime_error( | 856 | throw std::runtime_error( |
| 848 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 857 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 849 | ": numeric literal: decimal point already seen"); | 858 | ": numeric literal: decimal point already seen"); |
| 850 | } else { | 859 | } else { |
| 851 | number_saw_point = true; | 860 | number_saw_point = true; |
| @@ -854,7 +863,7 @@ JSONParser::getToken() | @@ -854,7 +863,7 @@ JSONParser::getToken() | ||
| 854 | if (number_saw_e) { | 863 | if (number_saw_e) { |
| 855 | QTC::TC("libtests", "JSON parse duplicate e"); | 864 | QTC::TC("libtests", "JSON parse duplicate e"); |
| 856 | throw std::runtime_error( | 865 | throw std::runtime_error( |
| 857 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 866 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 858 | ": numeric literal: e already seen"); | 867 | ": numeric literal: e already seen"); |
| 859 | } else { | 868 | } else { |
| 860 | number_saw_e = true; | 869 | number_saw_e = true; |
| @@ -865,7 +874,7 @@ JSONParser::getToken() | @@ -865,7 +874,7 @@ JSONParser::getToken() | ||
| 865 | } else { | 874 | } else { |
| 866 | QTC::TC("libtests", "JSON parse unexpected sign"); | 875 | QTC::TC("libtests", "JSON parse unexpected sign"); |
| 867 | throw std::runtime_error( | 876 | throw std::runtime_error( |
| 868 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 877 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 869 | ": numeric literal: unexpected sign"); | 878 | ": numeric literal: unexpected sign"); |
| 870 | } | 879 | } |
| 871 | } else if (QUtil::is_space(*p)) { | 880 | } else if (QUtil::is_space(*p)) { |
| @@ -877,7 +886,7 @@ JSONParser::getToken() | @@ -877,7 +886,7 @@ JSONParser::getToken() | ||
| 877 | } else { | 886 | } else { |
| 878 | QTC::TC("libtests", "JSON parse numeric bad character"); | 887 | QTC::TC("libtests", "JSON parse numeric bad character"); |
| 879 | throw std::runtime_error( | 888 | throw std::runtime_error( |
| 880 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 889 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 881 | ": numeric literal: unexpected character " + | 890 | ": numeric literal: unexpected character " + |
| 882 | std::string(p, 1)); | 891 | std::string(p, 1)); |
| 883 | } | 892 | } |
| @@ -895,7 +904,7 @@ JSONParser::getToken() | @@ -895,7 +904,7 @@ JSONParser::getToken() | ||
| 895 | } else { | 904 | } else { |
| 896 | QTC::TC("libtests", "JSON parse keyword bad character"); | 905 | QTC::TC("libtests", "JSON parse keyword bad character"); |
| 897 | throw std::runtime_error( | 906 | throw std::runtime_error( |
| 898 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 907 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 899 | ": keyword: unexpected character " + std::string(p, 1)); | 908 | ": keyword: unexpected character " + std::string(p, 1)); |
| 900 | } | 909 | } |
| 901 | break; | 910 | break; |
| @@ -918,7 +927,7 @@ JSONParser::getToken() | @@ -918,7 +927,7 @@ JSONParser::getToken() | ||
| 918 | } else { | 927 | } else { |
| 919 | QTC::TC("libtests", "JSON parse backslash bad character"); | 928 | QTC::TC("libtests", "JSON parse backslash bad character"); |
| 920 | throw std::runtime_error( | 929 | throw std::runtime_error( |
| 921 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 930 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 922 | ": invalid character after backslash: " + | 931 | ": invalid character after backslash: " + |
| 923 | std::string(p, 1)); | 932 | std::string(p, 1)); |
| 924 | } | 933 | } |
| @@ -929,7 +938,7 @@ JSONParser::getToken() | @@ -929,7 +938,7 @@ JSONParser::getToken() | ||
| 929 | QTC::TC("libtests", "JSON parse bad hex after u"); | 938 | QTC::TC("libtests", "JSON parse bad hex after u"); |
| 930 | throw std::runtime_error( | 939 | throw std::runtime_error( |
| 931 | "JSON: offset " + | 940 | "JSON: offset " + |
| 932 | - QUtil::uint_to_string(offset - u_count - 1) + | 941 | + QUtil::int_to_string(offset - u_count - 1) + |
| 933 | ": \\u must be followed by four hex digits"); | 942 | ": \\u must be followed by four hex digits"); |
| 934 | } | 943 | } |
| 935 | if (++u_count == 4) { | 944 | if (++u_count == 4) { |
| @@ -969,14 +978,14 @@ JSONParser::getToken() | @@ -969,14 +978,14 @@ JSONParser::getToken() | ||
| 969 | QTC::TC("libtests", "JSON parse premature end of u"); | 978 | QTC::TC("libtests", "JSON parse premature end of u"); |
| 970 | throw std::runtime_error( | 979 | throw std::runtime_error( |
| 971 | "JSON: offset " + | 980 | "JSON: offset " + |
| 972 | - QUtil::uint_to_string(offset - u_count - 1) + | 981 | + QUtil::int_to_string(offset - u_count - 1) + |
| 973 | ": \\u must be followed by four characters"); | 982 | ": \\u must be followed by four characters"); |
| 974 | 983 | ||
| 975 | case ls_string: | 984 | case ls_string: |
| 976 | case ls_backslash: | 985 | case ls_backslash: |
| 977 | QTC::TC("libtests", "JSON parse unterminated string"); | 986 | QTC::TC("libtests", "JSON parse unterminated string"); |
| 978 | throw std::runtime_error( | 987 | throw std::runtime_error( |
| 979 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 988 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 980 | ": unterminated string"); | 989 | ": unterminated string"); |
| 981 | break; | 990 | break; |
| 982 | } | 991 | } |
| @@ -994,7 +1003,7 @@ JSONParser::handleToken() | @@ -994,7 +1003,7 @@ JSONParser::handleToken() | ||
| 994 | if (parser_state == ps_done) { | 1003 | if (parser_state == ps_done) { |
| 995 | QTC::TC("libtests", "JSON parse junk after object"); | 1004 | QTC::TC("libtests", "JSON parse junk after object"); |
| 996 | throw std::runtime_error( | 1005 | throw std::runtime_error( |
| 997 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1006 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 998 | ": material follows end of object: " + token); | 1007 | ": material follows end of object: " + token); |
| 999 | } | 1008 | } |
| 1000 | 1009 | ||
| @@ -1005,7 +1014,7 @@ JSONParser::handleToken() | @@ -1005,7 +1014,7 @@ JSONParser::handleToken() | ||
| 1005 | if (token.length() < 2) { | 1014 | if (token.length() < 2) { |
| 1006 | throw std::logic_error("JSON string length < 2"); | 1015 | throw std::logic_error("JSON string length < 2"); |
| 1007 | } | 1016 | } |
| 1008 | - s_value = decode_string(token, offset - token.length()); | 1017 | + s_value = decode_string(token, offset - toO(token.length())); |
| 1009 | } | 1018 | } |
| 1010 | // Based on the lexical state and value, figure out whether we are | 1019 | // Based on the lexical state and value, figure out whether we are |
| 1011 | // looking at an item or a delimiter. It will always be exactly | 1020 | // looking at an item or a delimiter. It will always be exactly |
| @@ -1020,12 +1029,12 @@ JSONParser::handleToken() | @@ -1020,12 +1029,12 @@ JSONParser::handleToken() | ||
| 1020 | switch (first_char) { | 1029 | switch (first_char) { |
| 1021 | case '{': | 1030 | case '{': |
| 1022 | item = std::make_shared<JSON>(JSON::makeDictionary()); | 1031 | item = std::make_shared<JSON>(JSON::makeDictionary()); |
| 1023 | - item->setStart(offset - token.length()); | 1032 | + item->setStart(offset - toO(token.length())); |
| 1024 | break; | 1033 | break; |
| 1025 | 1034 | ||
| 1026 | case '[': | 1035 | case '[': |
| 1027 | item = std::make_shared<JSON>(JSON::makeArray()); | 1036 | item = std::make_shared<JSON>(JSON::makeArray()); |
| 1028 | - item->setStart(offset - token.length()); | 1037 | + item->setStart(offset - toO(token.length())); |
| 1029 | break; | 1038 | break; |
| 1030 | 1039 | ||
| 1031 | default: | 1040 | default: |
| @@ -1038,7 +1047,7 @@ JSONParser::handleToken() | @@ -1038,7 +1047,7 @@ JSONParser::handleToken() | ||
| 1038 | if (number_saw_point && (number_after_point == 0)) { | 1047 | if (number_saw_point && (number_after_point == 0)) { |
| 1039 | QTC::TC("libtests", "JSON parse decimal with no digits"); | 1048 | QTC::TC("libtests", "JSON parse decimal with no digits"); |
| 1040 | throw std::runtime_error( | 1049 | throw std::runtime_error( |
| 1041 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1050 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1042 | ": decimal point with no digits"); | 1051 | ": decimal point with no digits"); |
| 1043 | } | 1052 | } |
| 1044 | if ((number_before_point > 1) && | 1053 | if ((number_before_point > 1) && |
| @@ -1046,13 +1055,13 @@ JSONParser::handleToken() | @@ -1046,13 +1055,13 @@ JSONParser::handleToken() | ||
| 1046 | ((first_char == '-') && (token.at(1) == '0')))) { | 1055 | ((first_char == '-') && (token.at(1) == '0')))) { |
| 1047 | QTC::TC("libtests", "JSON parse leading zero"); | 1056 | QTC::TC("libtests", "JSON parse leading zero"); |
| 1048 | throw std::runtime_error( | 1057 | throw std::runtime_error( |
| 1049 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1058 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1050 | ": number with leading zero"); | 1059 | ": number with leading zero"); |
| 1051 | } | 1060 | } |
| 1052 | if ((number_before_point == 0) && (number_after_point == 0)) { | 1061 | if ((number_before_point == 0) && (number_after_point == 0)) { |
| 1053 | QTC::TC("libtests", "JSON parse number no digits"); | 1062 | QTC::TC("libtests", "JSON parse number no digits"); |
| 1054 | throw std::runtime_error( | 1063 | throw std::runtime_error( |
| 1055 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1064 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1056 | ": number with no digits"); | 1065 | ": number with no digits"); |
| 1057 | } | 1066 | } |
| 1058 | item = std::make_shared<JSON>(JSON::makeNumber(token)); | 1067 | item = std::make_shared<JSON>(JSON::makeNumber(token)); |
| @@ -1068,7 +1077,7 @@ JSONParser::handleToken() | @@ -1068,7 +1077,7 @@ JSONParser::handleToken() | ||
| 1068 | } else { | 1077 | } else { |
| 1069 | QTC::TC("libtests", "JSON parse invalid keyword"); | 1078 | QTC::TC("libtests", "JSON parse invalid keyword"); |
| 1070 | throw std::runtime_error( | 1079 | throw std::runtime_error( |
| 1071 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1080 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1072 | ": invalid keyword " + token); | 1081 | ": invalid keyword " + token); |
| 1073 | } | 1082 | } |
| 1074 | break; | 1083 | break; |
| @@ -1101,21 +1110,21 @@ JSONParser::handleToken() | @@ -1101,21 +1110,21 @@ JSONParser::handleToken() | ||
| 1101 | case ps_dict_after_key: | 1110 | case ps_dict_after_key: |
| 1102 | QTC::TC("libtests", "JSON parse expected colon"); | 1111 | QTC::TC("libtests", "JSON parse expected colon"); |
| 1103 | throw std::runtime_error( | 1112 | throw std::runtime_error( |
| 1104 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1113 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1105 | ": expected ':'"); | 1114 | ": expected ':'"); |
| 1106 | break; | 1115 | break; |
| 1107 | 1116 | ||
| 1108 | case ps_dict_after_item: | 1117 | case ps_dict_after_item: |
| 1109 | QTC::TC("libtests", "JSON parse expected , or }"); | 1118 | QTC::TC("libtests", "JSON parse expected , or }"); |
| 1110 | throw std::runtime_error( | 1119 | throw std::runtime_error( |
| 1111 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1120 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1112 | ": expected ',' or '}'"); | 1121 | ": expected ',' or '}'"); |
| 1113 | break; | 1122 | break; |
| 1114 | 1123 | ||
| 1115 | case ps_array_after_item: | 1124 | case ps_array_after_item: |
| 1116 | QTC::TC("libtests", "JSON parse expected, or ]"); | 1125 | QTC::TC("libtests", "JSON parse expected, or ]"); |
| 1117 | throw std::runtime_error( | 1126 | throw std::runtime_error( |
| 1118 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1127 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1119 | ": expected ',' or ']'"); | 1128 | ": expected ',' or ']'"); |
| 1120 | break; | 1129 | break; |
| 1121 | 1130 | ||
| @@ -1124,7 +1133,7 @@ JSONParser::handleToken() | @@ -1124,7 +1133,7 @@ JSONParser::handleToken() | ||
| 1124 | if (lex_state != ls_string) { | 1133 | if (lex_state != ls_string) { |
| 1125 | QTC::TC("libtests", "JSON parse string as dict key"); | 1134 | QTC::TC("libtests", "JSON parse string as dict key"); |
| 1126 | throw std::runtime_error( | 1135 | throw std::runtime_error( |
| 1127 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1136 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1128 | ": expect string as dictionary key"); | 1137 | ": expect string as dictionary key"); |
| 1129 | } | 1138 | } |
| 1130 | break; | 1139 | break; |
| @@ -1143,7 +1152,7 @@ JSONParser::handleToken() | @@ -1143,7 +1152,7 @@ JSONParser::handleToken() | ||
| 1143 | { | 1152 | { |
| 1144 | QTC::TC("libtests", "JSON parse unexpected }"); | 1153 | QTC::TC("libtests", "JSON parse unexpected }"); |
| 1145 | throw std::runtime_error( | 1154 | throw std::runtime_error( |
| 1146 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1155 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1147 | ": unexpected dictionary end delimiter"); | 1156 | ": unexpected dictionary end delimiter"); |
| 1148 | } | 1157 | } |
| 1149 | } else if (delimiter == ']') { | 1158 | } else if (delimiter == ']') { |
| @@ -1153,14 +1162,14 @@ JSONParser::handleToken() | @@ -1153,14 +1162,14 @@ JSONParser::handleToken() | ||
| 1153 | { | 1162 | { |
| 1154 | QTC::TC("libtests", "JSON parse unexpected ]"); | 1163 | QTC::TC("libtests", "JSON parse unexpected ]"); |
| 1155 | throw std::runtime_error( | 1164 | throw std::runtime_error( |
| 1156 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1165 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1157 | ": unexpected array end delimiter"); | 1166 | ": unexpected array end delimiter"); |
| 1158 | } | 1167 | } |
| 1159 | } else if (delimiter == ':') { | 1168 | } else if (delimiter == ':') { |
| 1160 | if (parser_state != ps_dict_after_key) { | 1169 | if (parser_state != ps_dict_after_key) { |
| 1161 | QTC::TC("libtests", "JSON parse unexpected :"); | 1170 | QTC::TC("libtests", "JSON parse unexpected :"); |
| 1162 | throw std::runtime_error( | 1171 | throw std::runtime_error( |
| 1163 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1172 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1164 | ": unexpected colon"); | 1173 | ": unexpected colon"); |
| 1165 | } | 1174 | } |
| 1166 | } else if (delimiter == ',') { | 1175 | } else if (delimiter == ',') { |
| @@ -1168,7 +1177,7 @@ JSONParser::handleToken() | @@ -1168,7 +1177,7 @@ JSONParser::handleToken() | ||
| 1168 | (parser_state == ps_array_after_item))) { | 1177 | (parser_state == ps_array_after_item))) { |
| 1169 | QTC::TC("libtests", "JSON parse unexpected ,"); | 1178 | QTC::TC("libtests", "JSON parse unexpected ,"); |
| 1170 | throw std::runtime_error( | 1179 | throw std::runtime_error( |
| 1171 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1180 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1172 | ": unexpected comma"); | 1181 | ": unexpected comma"); |
| 1173 | } | 1182 | } |
| 1174 | } else if (delimiter != '\0') { | 1183 | } else if (delimiter != '\0') { |
| @@ -1206,7 +1215,7 @@ JSONParser::handleToken() | @@ -1206,7 +1215,7 @@ JSONParser::handleToken() | ||
| 1206 | "JSONParser::handleToken: unexpected delimiter in transition"); | 1215 | "JSONParser::handleToken: unexpected delimiter in transition"); |
| 1207 | } else if (item.get()) { | 1216 | } else if (item.get()) { |
| 1208 | if (!(item->isArray() || item->isDictionary())) { | 1217 | if (!(item->isArray() || item->isDictionary())) { |
| 1209 | - item->setStart(offset - token.length()); | 1218 | + item->setStart(offset - toO(token.length())); |
| 1210 | item->setEnd(offset); | 1219 | item->setEnd(offset); |
| 1211 | } | 1220 | } |
| 1212 | 1221 | ||
| @@ -1227,7 +1236,7 @@ JSONParser::handleToken() | @@ -1227,7 +1236,7 @@ JSONParser::handleToken() | ||
| 1227 | if (tos->checkDictionaryKeySeen(dict_key)) { | 1236 | if (tos->checkDictionaryKeySeen(dict_key)) { |
| 1228 | QTC::TC("libtests", "JSON parse duplicate key"); | 1237 | QTC::TC("libtests", "JSON parse duplicate key"); |
| 1229 | throw std::runtime_error( | 1238 | throw std::runtime_error( |
| 1230 | - "JSON: offset " + QUtil::uint_to_string(dict_key_offset) + | 1239 | + "JSON: offset " + QUtil::int_to_string(dict_key_offset) + |
| 1231 | ": duplicated dictionary key"); | 1240 | ": duplicated dictionary key"); |
| 1232 | } | 1241 | } |
| 1233 | if (!reactor || !reactor->dictionaryItem(dict_key, *item)) { | 1242 | if (!reactor || !reactor->dictionaryItem(dict_key, *item)) { |
| @@ -1288,7 +1297,7 @@ JSONParser::handleToken() | @@ -1288,7 +1297,7 @@ JSONParser::handleToken() | ||
| 1288 | } | 1297 | } |
| 1289 | if (ps_stack.size() > 500) { | 1298 | if (ps_stack.size() > 500) { |
| 1290 | throw std::runtime_error( | 1299 | throw std::runtime_error( |
| 1291 | - "JSON: offset " + QUtil::uint_to_string(offset) + | 1300 | + "JSON: offset " + QUtil::int_to_string(offset) + |
| 1292 | ": maximum object depth exceeded"); | 1301 | ": maximum object depth exceeded"); |
| 1293 | } | 1302 | } |
| 1294 | parser_state = next_state; | 1303 | parser_state = next_state; |
| @@ -1329,24 +1338,24 @@ JSON::parse(std::string const& s) | @@ -1329,24 +1338,24 @@ JSON::parse(std::string const& s) | ||
| 1329 | } | 1338 | } |
| 1330 | 1339 | ||
| 1331 | void | 1340 | void |
| 1332 | -JSON::setStart(size_t start) | 1341 | +JSON::setStart(qpdf_offset_t start) |
| 1333 | { | 1342 | { |
| 1334 | this->m->start = start; | 1343 | this->m->start = start; |
| 1335 | } | 1344 | } |
| 1336 | 1345 | ||
| 1337 | void | 1346 | void |
| 1338 | -JSON::setEnd(size_t end) | 1347 | +JSON::setEnd(qpdf_offset_t end) |
| 1339 | { | 1348 | { |
| 1340 | this->m->end = end; | 1349 | this->m->end = end; |
| 1341 | } | 1350 | } |
| 1342 | 1351 | ||
| 1343 | -size_t | 1352 | +qpdf_offset_t |
| 1344 | JSON::getStart() const | 1353 | JSON::getStart() const |
| 1345 | { | 1354 | { |
| 1346 | return this->m->start; | 1355 | return this->m->start; |
| 1347 | } | 1356 | } |
| 1348 | 1357 | ||
| 1349 | -size_t | 1358 | +qpdf_offset_t |
| 1350 | JSON::getEnd() const | 1359 | JSON::getEnd() const |
| 1351 | { | 1360 | { |
| 1352 | return this->m->end; | 1361 | return this->m->end; |
libqpdf/QPDF_json.cc
| @@ -197,14 +197,14 @@ QPDF::test_json_validators() | @@ -197,14 +197,14 @@ QPDF::test_json_validators() | ||
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | static std::function<void(Pipeline*)> | 199 | static std::function<void(Pipeline*)> |
| 200 | -provide_data(std::shared_ptr<InputSource> is, size_t start, size_t end) | 200 | +provide_data(std::shared_ptr<InputSource> is, qpdf_offset_t start, qpdf_offset_t end) |
| 201 | { | 201 | { |
| 202 | return [is, start, end](Pipeline* p) { | 202 | return [is, start, end](Pipeline* p) { |
| 203 | Pl_Base64 decode("base64-decode", p, Pl_Base64::a_decode); | 203 | Pl_Base64 decode("base64-decode", p, Pl_Base64::a_decode); |
| 204 | p = &decode; | 204 | p = &decode; |
| 205 | - size_t bytes = end - start; | 205 | + size_t bytes = QIntC::to_size(end - start); |
| 206 | char buf[8192]; | 206 | char buf[8192]; |
| 207 | - is->seek(QIntC::to_offset(start), SEEK_SET); | 207 | + is->seek(start, SEEK_SET); |
| 208 | size_t len = 0; | 208 | size_t len = 0; |
| 209 | while ((len = is->read(buf, std::min(bytes, sizeof(buf)))) > 0) { | 209 | while ((len = is->read(buf, std::min(bytes, sizeof(buf)))) > 0) { |
| 210 | p->write(buf, len); | 210 | p->write(buf, len); |
| @@ -241,14 +241,14 @@ QPDF::JSONReactor::JSONReactor( | @@ -241,14 +241,14 @@ QPDF::JSONReactor::JSONReactor( | ||
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | void | 243 | void |
| 244 | -QPDF::JSONReactor::error(size_t offset, std::string const& msg) | 244 | +QPDF::JSONReactor::error(qpdf_offset_t offset, std::string const& msg) |
| 245 | { | 245 | { |
| 246 | this->errors = true; | 246 | this->errors = true; |
| 247 | std::string object = this->cur_object; | 247 | std::string object = this->cur_object; |
| 248 | if (is->getName() != pdf.getFilename()) { | 248 | if (is->getName() != pdf.getFilename()) { |
| 249 | object += " from " + is->getName(); | 249 | object += " from " + is->getName(); |
| 250 | } | 250 | } |
| 251 | - this->pdf.warn(qpdf_e_json, object, QIntC::to_offset(offset), msg); | 251 | + this->pdf.warn(qpdf_e_json, object, offset, msg); |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | bool | 254 | bool |
| @@ -616,7 +616,7 @@ QPDF::JSONReactor::setObjectDescription(QPDFObjectHandle& oh, JSON const& value) | @@ -616,7 +616,7 @@ QPDF::JSONReactor::setObjectDescription(QPDFObjectHandle& oh, JSON const& value) | ||
| 616 | if (!this->cur_object.empty()) { | 616 | if (!this->cur_object.empty()) { |
| 617 | description += ", " + this->cur_object; | 617 | description += ", " + this->cur_object; |
| 618 | } | 618 | } |
| 619 | - description += " at offset " + QUtil::uint_to_string(value.getStart()); | 619 | + description += " at offset " + QUtil::int_to_string(value.getStart()); |
| 620 | oh.setObjectDescription(&this->pdf, description); | 620 | oh.setObjectDescription(&this->pdf, description); |
| 621 | } | 621 | } |
| 622 | 622 |