Commit c56a9ca7f6484925627aa1da374a236949c07cb2

Authored by Jay Berkenbilt
1 parent 47c093c4

JSON: Fix large file support

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&amp; str, size_t offset) @@ -708,11 +716,12 @@ JSONParser::decode_string(std::string const&amp; 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&amp; str, size_t offset) @@ -740,7 +749,7 @@ JSONParser::decode_string(std::string const&amp; 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&amp; str, size_t offset) @@ -759,7 +768,7 @@ JSONParser::decode_string(std::string const&amp; 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&amp; s) @@ -1329,24 +1338,24 @@ JSON::parse(std::string const&amp; 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&amp; oh, JSON const&amp; value) @@ -616,7 +616,7 @@ QPDF::JSONReactor::setObjectDescription(QPDFObjectHandle&amp; oh, JSON const&amp; 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