Commit cdc46d78f441526d566c9da195e79b900617bb13

Authored by Masamichi Hosoda
Committed by Jay Berkenbilt
1 parent 50b329ee

Add QPDFObject::getParsedOffset()

include/qpdf/QPDFObject.hh
... ... @@ -23,6 +23,7 @@
23 23 #define QPDFOBJECT_HH
24 24  
25 25 #include <qpdf/DLL.h>
  26 +#include <qpdf/Types.h>
26 27 #include <qpdf/PointerHolder.hh>
27 28 #include <qpdf/JSON.hh>
28 29  
... ... @@ -92,6 +93,9 @@ class QPDFObject
92 93 bool getDescription(QPDF*&, std::string&);
93 94 bool hasDescription();
94 95  
  96 + void setParsedOffset(qpdf_offset_t offset);
  97 + qpdf_offset_t getParsedOffset();
  98 +
95 99 protected:
96 100 virtual void releaseResolved() {}
97 101  
... ... @@ -108,6 +112,7 @@ class QPDFObject
108 112 Members();
109 113 QPDF* owning_qpdf;
110 114 std::string object_description;
  115 + qpdf_offset_t parsed_offset;
111 116 };
112 117 PointerHolder<Members> m;
113 118 };
... ...
include/qpdf/QPDFObjectHandle.hh
... ... @@ -341,6 +341,14 @@ class QPDFObjectHandle
341 341 StringDecrypter* decrypter,
342 342 QPDF* context);
343 343  
  344 + // Return the offset where the object was found when parsed. A
  345 + // negative value means that the object was created without
  346 + // parsing. If the object is in a stream, the offset is from the
  347 + // beginning of the stream. Otherwise, the offset is from the
  348 + // beginning of the file.
  349 + QPDF_DLL
  350 + qpdf_offset_t getParsedOffset();
  351 +
344 352 // Older method: stream_or_array should be the value of /Contents
345 353 // from a page object. It's more convenient to just call
346 354 // QPDFPageObjectHelper::parsePageContents on the page object, and
... ... @@ -1050,6 +1058,7 @@ class QPDFObjectHandle
1050 1058 QPDFTokenizer& tokenizer, bool& empty,
1051 1059 StringDecrypter* decrypter, QPDF* context,
1052 1060 bool content_stream);
  1061 + void setParsedOffset(qpdf_offset_t offset);
1053 1062 void parseContentStream_internal(
1054 1063 std::string const& description,
1055 1064 ParserCallbacks* callbacks);
... ...
libqpdf/QPDFObject.cc
1 1 #include <qpdf/QPDFObject.hh>
2 2  
3 3 QPDFObject::Members::Members() :
4   - owning_qpdf(0)
  4 + owning_qpdf(0),
  5 + parsed_offset(-1)
5 6 {
6 7 }
7 8  
... ... @@ -34,3 +35,15 @@ QPDFObject::hasDescription()
34 35 {
35 36 return this->m->owning_qpdf != 0;
36 37 }
  38 +
  39 +void
  40 +QPDFObject::setParsedOffset(qpdf_offset_t offset)
  41 +{
  42 + this->m->parsed_offset = offset;
  43 +}
  44 +
  45 +qpdf_offset_t
  46 +QPDFObject::getParsedOffset()
  47 +{
  48 + return this->m->parsed_offset;
  49 +}
... ...
libqpdf/QPDFObjectHandle.cc
... ... @@ -1767,6 +1767,7 @@ QPDFObjectHandle::parseInternal(PointerHolder&lt;InputSource&gt; input,
1767 1767 empty = false;
1768 1768  
1769 1769 QPDFObjectHandle object;
  1770 + bool set_offset = false;
1770 1771  
1771 1772 std::vector<SparseOHArray> olist_stack;
1772 1773 olist_stack.push_back(SparseOHArray());
... ... @@ -1786,6 +1787,7 @@ QPDFObjectHandle::parseInternal(PointerHolder&lt;InputSource&gt; input,
1786 1787 offset = offset_stack.back();
1787 1788  
1788 1789 object = QPDFObjectHandle();
  1790 + set_offset = false;
1789 1791  
1790 1792 QPDFTokenizer::Token token =
1791 1793 tokenizer.readToken(input, object_description, true);
... ... @@ -2054,6 +2056,8 @@ QPDFObjectHandle::parseInternal(PointerHolder&lt;InputSource&gt; input,
2054 2056 setObjectDescriptionFromInput(
2055 2057 object, context, object_description, input,
2056 2058 input->getLastOffset());
  2059 + object.setParsedOffset(input->getLastOffset());
  2060 + set_offset = true;
2057 2061 olist.append(object);
2058 2062 break;
2059 2063  
... ... @@ -2080,6 +2084,14 @@ QPDFObjectHandle::parseInternal(PointerHolder&lt;InputSource&gt; input,
2080 2084 object = QPDFObjectHandle(new QPDF_Array(olist));
2081 2085 setObjectDescriptionFromInput(
2082 2086 object, context, object_description, input, offset);
  2087 + // The `offset` points to the next of "[". Set the
  2088 + // rewind offset to point to the beginning of "[".
  2089 + // This has been explicitly tested with whitespace
  2090 + // surrounding the array start delimiter.
  2091 + // getLastOffset points to the array end token and
  2092 + // therefore can't be used here.
  2093 + object.setParsedOffset(offset - 1);
  2094 + set_offset = true;
2083 2095 }
2084 2096 else if (old_state == st_dictionary)
2085 2097 {
... ... @@ -2159,6 +2171,14 @@ QPDFObjectHandle::parseInternal(PointerHolder&lt;InputSource&gt; input,
2159 2171 object = newDictionary(dict);
2160 2172 setObjectDescriptionFromInput(
2161 2173 object, context, object_description, input, offset);
  2174 + // The `offset` points to the next of "<<". Set the
  2175 + // rewind offset to point to the beginning of "<<".
  2176 + // This has been explicitly tested with whitespace
  2177 + // surrounding the dictionary start delimiter.
  2178 + // getLastOffset points to the dictionary end token
  2179 + // and therefore can't be used here.
  2180 + object.setParsedOffset(offset - 2);
  2181 + set_offset = true;
2162 2182 }
2163 2183 olist_stack.pop_back();
2164 2184 offset_stack.pop_back();
... ... @@ -2173,11 +2193,31 @@ QPDFObjectHandle::parseInternal(PointerHolder&lt;InputSource&gt; input,
2173 2193 }
2174 2194 }
2175 2195  
2176   - setObjectDescriptionFromInput(
2177   - object, context, object_description, input, offset);
  2196 + if (! set_offset)
  2197 + {
  2198 + setObjectDescriptionFromInput(
  2199 + object, context, object_description, input, offset);
  2200 + object.setParsedOffset(offset);
  2201 + }
2178 2202 return object;
2179 2203 }
2180 2204  
  2205 +qpdf_offset_t
  2206 +QPDFObjectHandle::getParsedOffset()
  2207 +{
  2208 + dereference();
  2209 + return this->m->obj->getParsedOffset();
  2210 +}
  2211 +
  2212 +void
  2213 +QPDFObjectHandle::setParsedOffset(qpdf_offset_t offset)
  2214 +{
  2215 + if (this->m->obj.getPointer())
  2216 + {
  2217 + this->m->obj->setParsedOffset(offset);
  2218 + }
  2219 +}
  2220 +
2181 2221 QPDFObjectHandle
2182 2222 QPDFObjectHandle::newIndirect(QPDF* qpdf, int objid, int generation)
2183 2223 {
... ... @@ -2321,9 +2361,14 @@ QPDFObjectHandle::newStream(QPDF* qpdf, int objid, int generation,
2321 2361 QPDFObjectHandle stream_dict,
2322 2362 qpdf_offset_t offset, size_t length)
2323 2363 {
2324   - return QPDFObjectHandle(new QPDF_Stream(
  2364 + QPDFObjectHandle result = QPDFObjectHandle(new QPDF_Stream(
2325 2365 qpdf, objid, generation,
2326 2366 stream_dict, offset, length));
  2367 + if (offset)
  2368 + {
  2369 + result.setParsedOffset(offset);
  2370 + }
  2371 + return result;
2327 2372 }
2328 2373  
2329 2374 QPDFObjectHandle
... ...
qpdf/build.mk
... ... @@ -3,6 +3,7 @@ BINS_qpdf = \
3 3 pdf_from_scratch \
4 4 test_driver \
5 5 test_large_file \
  6 + test_parsedoffset \
6 7 test_pdf_doc_encoding \
7 8 test_pdf_unicode \
8 9 test_renumber \
... ...
qpdf/qtest/qpdf.test
... ... @@ -4095,6 +4095,23 @@ $td-&gt;runtest(&quot;w/ objstm, --preserve-unreferenced&quot;,
4095 4095  
4096 4096 show_ntests();
4097 4097 # ----------
  4098 +$td->notify("--- Parsed Offset ---");
  4099 +$n_tests += 2;
  4100 +
  4101 +$td->runtest("parsed offset without object streams",
  4102 + {$td->COMMAND => "test_parsedoffset minimal.pdf"},
  4103 + {$td->FILE => "minimal-parsedoffset.out",
  4104 + $td->EXIT_STATUS => 0},
  4105 + $td->NORMALIZE_NEWLINES);
  4106 +
  4107 +$td->runtest("parsed offset with object streams",
  4108 + {$td->COMMAND => "test_parsedoffset digitally-signed.pdf"},
  4109 + {$td->FILE => "digitally-signed-parsedoffset.out",
  4110 + $td->EXIT_STATUS => 0},
  4111 + $td->NORMALIZE_NEWLINES);
  4112 +
  4113 +show_ntests();
  4114 +# ----------
4098 4115 $td->notify("--- Large File Tests ---");
4099 4116 my $nlarge = 1;
4100 4117 if (defined $large_file_test_path)
... ...
qpdf/qtest/qpdf/digitally-signed-parsedoffset.out 0 โ†’ 100644
  1 +--- objects not in streams ---
  2 +offset = 25 (0x19), indirect 11/0, dictionary
  3 +offset = 39 (0x27), direct, integer
  4 +offset = 43 (0x2b), direct, integer
  5 +offset = 51 (0x33), direct, integer
  6 +offset = 56 (0x38), direct, integer
  7 +offset = 64 (0x40), direct, integer
  8 +offset = 68 (0x44), direct, integer
  9 +offset = 76 (0x4c), direct, array
  10 +offset = 78 (0x4e), direct, integer
  11 +offset = 82 (0x52), direct, integer
  12 +offset = 125 (0x7d), direct, dictionary
  13 +offset = 139 (0x8b), direct, dictionary
  14 +offset = 150 (0x96), direct, integer
  15 +offset = 162 (0xa2), direct, integer
  16 +offset = 173 (0xad), direct, name
  17 +offset = 188 (0xbc), direct, array
  18 +offset = 189 (0xbd), direct, string
  19 +offset = 223 (0xdf), direct, string
  20 +offset = 264 (0x108), direct, array
  21 +offset = 265 (0x109), direct, integer
  22 +offset = 268 (0x10c), direct, integer
  23 +offset = 291 (0x123), direct, integer
  24 +offset = 299 (0x12b), direct, integer
  25 +offset = 322 (0x142), direct, integer
  26 +offset = 329 (0x149), direct, name
  27 +offset = 336 (0x150), direct, array
  28 +offset = 337 (0x151), direct, integer
  29 +offset = 339 (0x153), direct, integer
  30 +offset = 341 (0x155), direct, integer
  31 +offset = 353 (0x161), indirect 22/0, stream
  32 +offset = 480 (0x1e0), direct, dictionary
  33 +offset = 489 (0x1e9), direct, name
  34 +offset = 504 (0x1f8), direct, integer
  35 +offset = 515 (0x203), direct, integer
  36 +offset = 520 (0x208), direct, integer
  37 +offset = 525 (0x20d), direct, integer
  38 +offset = 537 (0x219), indirect 30/0, stream
  39 +offset = 658 (0x292), indirect 12/0, dictionary
  40 +offset = 708 (0x2c4), direct, name
  41 +offset = 735 (0x2df), indirect 13/0, dictionary
  42 +offset = 775 (0x307), direct, array
  43 +offset = 776 (0x308), direct, integer
  44 +offset = 778 (0x30a), direct, integer
  45 +offset = 780 (0x30c), direct, integer
  46 +offset = 784 (0x310), direct, integer
  47 +offset = 797 (0x31d), direct, array
  48 +offset = 798 (0x31e), direct, integer
  49 +offset = 800 (0x320), direct, integer
  50 +offset = 802 (0x322), direct, integer
  51 +offset = 806 (0x326), direct, integer
  52 +offset = 833 (0x341), direct, dictionary
  53 +offset = 840 (0x348), direct, dictionary
  54 +offset = 879 (0x36f), direct, integer
  55 +offset = 885 (0x375), direct, name
  56 +offset = 909 (0x38d), direct, dictionary
  57 +offset = 916 (0x394), direct, array
  58 +offset = 917 (0x395), direct, real
  59 +offset = 921 (0x399), direct, real
  60 +offset = 925 (0x39d), direct, real
  61 +offset = 933 (0x3a5), direct, real
  62 +offset = 949 (0x3b5), direct, integer
  63 +offset = 960 (0x3c0), direct, dictionary
  64 +offset = 970 (0x3ca), direct, dictionary
  65 +offset = 995 (0x3e3), direct, name
  66 +offset = 1005 (0x3ed), direct, name
  67 +offset = 1023 (0x3ff), indirect 14/0, stream
  68 +offset = 1058 (0x422), direct, dictionary
  69 +offset = 1065 (0x429), direct, array
  70 +offset = 1066 (0x42a), direct, real
  71 +offset = 1070 (0x42e), direct, real
  72 +offset = 1074 (0x432), direct, real
  73 +offset = 1082 (0x43a), direct, real
  74 +offset = 1097 (0x449), direct, name
  75 +offset = 1117 (0x45d), direct, integer
  76 +offset = 1129 (0x469), direct, dictionary
  77 +offset = 1139 (0x473), direct, dictionary
  78 +offset = 1173 (0x495), direct, name
  79 +offset = 1183 (0x49f), direct, name
  80 +offset = 1201 (0x4b1), indirect 15/0, stream
  81 +offset = 1265 (0x4f1), direct, dictionary
  82 +offset = 1272 (0x4f8), direct, array
  83 +offset = 1273 (0x4f9), direct, real
  84 +offset = 1277 (0x4fd), direct, real
  85 +offset = 1281 (0x501), direct, real
  86 +offset = 1287 (0x507), direct, real
  87 +offset = 1301 (0x515), direct, integer
  88 +offset = 1313 (0x521), direct, dictionary
  89 +offset = 1325 (0x52d), direct, name
  90 +offset = 1335 (0x537), direct, name
  91 +offset = 1353 (0x549), indirect 16/0, stream
  92 +offset = 1391 (0x56f), direct, dictionary
  93 +offset = 1398 (0x576), direct, array
  94 +offset = 1399 (0x577), direct, real
  95 +offset = 1403 (0x57b), direct, real
  96 +offset = 1407 (0x57f), direct, real
  97 +offset = 1415 (0x587), direct, real
  98 +offset = 1430 (0x596), direct, name
  99 +offset = 1450 (0x5aa), direct, integer
  100 +offset = 1463 (0x5b7), direct, dictionary
  101 +offset = 1470 (0x5be), direct, dictionary
  102 +offset = 1494 (0x5d6), direct, array
  103 +offset = 1495 (0x5d7), direct, name
  104 +offset = 1499 (0x5db), direct, name
  105 +offset = 1515 (0x5eb), direct, name
  106 +offset = 1525 (0x5f5), direct, name
  107 +offset = 1543 (0x607), indirect 17/0, stream
  108 +offset = 2420 (0x974), direct, dictionary
  109 +offset = 2429 (0x97d), direct, name
  110 +offset = 2449 (0x991), direct, integer
  111 +offset = 2462 (0x99e), direct, name
  112 +offset = 2479 (0x9af), indirect 18/0, stream
  113 +offset = 57714 (0xe172), direct, dictionary
  114 +offset = 57723 (0xe17b), direct, name
  115 +offset = 57742 (0xe18e), direct, integer
  116 +offset = 57752 (0xe198), direct, integer
  117 +offset = 57759 (0xe19f), direct, integer
  118 +offset = 57765 (0xe1a5), direct, name
  119 +offset = 57782 (0xe1b6), indirect 19/0, stream
  120 +offset = 59421 (0xe81d), direct, dictionary
  121 +offset = 59431 (0xe827), direct, integer
  122 +offset = 59443 (0xe833), indirect 20/0, stream
  123 +offset = 59515 (0xe87b), indirect 21/0, dictionary
  124 +offset = 59527 (0xe887), direct, array
  125 +offset = 59529 (0xe889), direct, integer
  126 +offset = 59531 (0xe88b), direct, integer
  127 +offset = 59537 (0xe891), direct, integer
  128 +offset = 59543 (0xe897), direct, integer
  129 +offset = 59599 (0xe8cf), direct, string
  130 +offset = 64094 (0xfa5e), direct, name
  131 +offset = 64110 (0xfa6e), direct, string
  132 +offset = 64140 (0xfa8c), direct, string
  133 +offset = 64161 (0xfaa1), direct, dictionary
  134 +offset = 64167 (0xfaa7), direct, dictionary
  135 +offset = 64174 (0xfaae), direct, name
  136 +offset = 64207 (0xfacf), direct, array
  137 +offset = 64208 (0xfad0), direct, name
  138 +offset = 64216 (0xfad8), direct, integer
  139 +offset = 64227 (0xfae3), direct, string
  140 +offset = 64256 (0xfb00), direct, boolean
  141 +offset = 64269 (0xfb0d), direct, dictionary
  142 +offset = 64276 (0xfb14), direct, string
  143 +offset = 64303 (0xfb2f), direct, name
  144 +offset = 64320 (0xfb40), direct, integer
  145 +offset = 64329 (0xfb49), direct, integer
  146 +offset = 64339 (0xfb53), direct, dictionary
  147 +offset = 64346 (0xfb5a), direct, string
  148 +offset = 64384 (0xfb80), direct, boolean
  149 +offset = 64391 (0xfb87), direct, integer
  150 +offset = 64411 (0xfb9b), direct, name
  151 +offset = 64436 (0xfbb4), direct, name
  152 +offset = 64458 (0xfbca), direct, dictionary
  153 +offset = 64467 (0xfbd3), direct, name
  154 +offset = 64486 (0xfbe6), direct, integer
  155 +offset = 64496 (0xfbf0), direct, integer
  156 +offset = 64502 (0xfbf6), direct, integer
  157 +offset = 64508 (0xfbfc), direct, name
  158 +offset = 64525 (0xfc0d), indirect 1/0, stream
  159 +offset = 65185 (0xfea1), direct, dictionary
  160 +offset = 65195 (0xfeab), direct, integer
  161 +offset = 65207 (0xfeb7), direct, name
  162 +offset = 65216 (0xfec0), direct, name
  163 +offset = 65235 (0xfed3), indirect 2/0, stream
  164 +offset = 68250 (0x10a9a), direct, dictionary
  165 +offset = 68259 (0x10aa3), direct, name
  166 +offset = 68278 (0x10ab6), direct, integer
  167 +offset = 68287 (0x10abf), direct, integer
  168 +offset = 68292 (0x10ac4), direct, integer
  169 +offset = 68298 (0x10aca), direct, name
  170 +offset = 68315 (0x10adb), indirect 3/0, stream
  171 +offset = 68391 (0x10b27), direct, dictionary
  172 +offset = 68400 (0x10b30), direct, name
  173 +offset = 68419 (0x10b43), direct, integer
  174 +offset = 68428 (0x10b4c), direct, integer
  175 +offset = 68433 (0x10b51), direct, integer
  176 +offset = 68439 (0x10b57), direct, name
  177 +offset = 68456 (0x10b68), indirect 4/0, stream
  178 +offset = 68546 (0x10bc2), direct, dictionary
  179 +offset = 68560 (0x10bd0), direct, dictionary
  180 +offset = 68571 (0x10bdb), direct, integer
  181 +offset = 68583 (0x10be7), direct, integer
  182 +offset = 68594 (0x10bf2), direct, name
  183 +offset = 68609 (0x10c01), direct, array
  184 +offset = 68610 (0x10c02), direct, string
  185 +offset = 68644 (0x10c24), direct, string
  186 +offset = 68699 (0x10c5b), direct, integer
  187 +offset = 68719 (0x10c6f), direct, integer
  188 +offset = 68726 (0x10c76), direct, name
  189 +offset = 68733 (0x10c7d), direct, array
  190 +offset = 68734 (0x10c7e), direct, integer
  191 +offset = 68736 (0x10c80), direct, integer
  192 +offset = 68738 (0x10c82), direct, integer
  193 +offset = 68750 (0x10c8e), indirect 5/0, stream
  194 +--- objects in stream 1 ---
  195 +offset = 15 (0xf), indirect 6/0, dictionary
  196 +offset = 26 (0x1a), direct, name
  197 +offset = 56 (0x38), direct, name
  198 +offset = 69 (0x45), direct, name
  199 +offset = 80 (0x50), direct, name
  200 +offset = 87 (0x57), indirect 7/0, dictionary
  201 +offset = 98 (0x62), direct, name
  202 +offset = 116 (0x74), direct, name
  203 +offset = 129 (0x81), direct, name
  204 +offset = 140 (0x8c), direct, name
  205 +offset = 147 (0x93), indirect 8/0, dictionary
  206 +offset = 161 (0xa1), direct, array
  207 +offset = 162 (0xa2), direct, integer
  208 +offset = 164 (0xa4), direct, name
  209 +offset = 170 (0xaa), direct, name
  210 +offset = 176 (0xb0), direct, name
  211 +offset = 187 (0xbb), direct, name
  212 +offset = 197 (0xc5), direct, name
  213 +offset = 210 (0xd2), direct, name
  214 +offset = 217 (0xd9), direct, name
  215 +offset = 222 (0xde), direct, name
  216 +offset = 229 (0xe5), direct, integer
  217 +offset = 231 (0xe7), direct, name
  218 +offset = 244 (0xf4), direct, integer
  219 +offset = 246 (0xf6), direct, name
  220 +offset = 253 (0xfd), direct, integer
  221 +offset = 256 (0x100), direct, name
  222 +offset = 263 (0x107), direct, name
  223 +offset = 270 (0x10e), direct, name
  224 +offset = 280 (0x118), direct, name
  225 +offset = 289 (0x121), direct, name
  226 +offset = 296 (0x128), direct, name
  227 +offset = 303 (0x12f), direct, name
  228 +offset = 310 (0x136), direct, name
  229 +offset = 319 (0x13f), direct, name
  230 +offset = 333 (0x14d), direct, name
  231 +offset = 348 (0x15c), direct, name
  232 +offset = 354 (0x162), direct, name
  233 +offset = 366 (0x16e), direct, name
  234 +offset = 379 (0x17b), direct, name
  235 +offset = 392 (0x188), direct, name
  236 +offset = 406 (0x196), direct, name
  237 +offset = 416 (0x1a0), direct, name
  238 +offset = 427 (0x1ab), direct, name
  239 +offset = 442 (0x1ba), direct, name
  240 +offset = 452 (0x1c4), direct, name
  241 +offset = 455 (0x1c7), direct, name
  242 +offset = 458 (0x1ca), direct, name
  243 +offset = 465 (0x1d1), direct, name
  244 +offset = 468 (0x1d4), direct, name
  245 +offset = 475 (0x1db), direct, name
  246 +offset = 485 (0x1e5), direct, name
  247 +offset = 492 (0x1ec), direct, name
  248 +offset = 501 (0x1f5), direct, name
  249 +offset = 508 (0x1fc), direct, name
  250 +offset = 511 (0x1ff), direct, name
  251 +offset = 518 (0x206), direct, name
  252 +offset = 526 (0x20e), direct, integer
  253 +offset = 529 (0x211), direct, name
  254 +offset = 535 (0x217), direct, integer
  255 +offset = 538 (0x21a), direct, name
  256 +offset = 548 (0x224), direct, integer
  257 +offset = 551 (0x227), direct, name
  258 +offset = 562 (0x232), direct, integer
  259 +offset = 565 (0x235), direct, name
  260 +offset = 574 (0x23e), direct, name
  261 +offset = 584 (0x248), direct, name
  262 +offset = 597 (0x255), direct, integer
  263 +offset = 600 (0x258), direct, name
  264 +offset = 611 (0x263), direct, name
  265 +offset = 619 (0x26b), direct, name
  266 +offset = 630 (0x276), direct, name
  267 +offset = 637 (0x27d), direct, name
  268 +offset = 644 (0x284), direct, name
  269 +offset = 654 (0x28e), direct, name
  270 +offset = 666 (0x29a), direct, name
  271 +offset = 680 (0x2a8), direct, name
  272 +offset = 686 (0x2ae), direct, name
  273 +offset = 690 (0x2b2), direct, integer
  274 +offset = 693 (0x2b5), direct, name
  275 +offset = 708 (0x2c4), direct, name
  276 +offset = 716 (0x2cc), direct, name
  277 +offset = 728 (0x2d8), direct, name
  278 +offset = 742 (0x2e6), direct, integer
  279 +offset = 745 (0x2e9), direct, name
  280 +offset = 756 (0x2f4), direct, name
  281 +offset = 764 (0x2fc), direct, name
  282 +offset = 779 (0x30b), direct, integer
  283 +offset = 782 (0x30e), direct, name
  284 +offset = 789 (0x315), direct, name
  285 +offset = 796 (0x31c), direct, name
  286 +offset = 808 (0x328), direct, name
  287 +offset = 815 (0x32f), direct, name
  288 +offset = 825 (0x339), direct, name
  289 +offset = 831 (0x33f), direct, name
  290 +offset = 834 (0x342), direct, name
  291 +offset = 843 (0x34b), direct, name
  292 +offset = 850 (0x352), direct, name
  293 +offset = 857 (0x359), direct, name
  294 +offset = 869 (0x365), direct, name
  295 +offset = 879 (0x36f), direct, name
  296 +offset = 886 (0x376), direct, name
  297 +offset = 893 (0x37d), direct, name
  298 +offset = 905 (0x389), direct, name
  299 +offset = 915 (0x393), direct, name
  300 +offset = 919 (0x397), direct, name
  301 +offset = 926 (0x39e), direct, name
  302 +offset = 933 (0x3a5), direct, name
  303 +offset = 940 (0x3ac), direct, name
  304 +offset = 952 (0x3b8), direct, name
  305 +offset = 959 (0x3bf), direct, name
  306 +offset = 969 (0x3c9), direct, name
  307 +offset = 978 (0x3d2), direct, name
  308 +offset = 985 (0x3d9), direct, name
  309 +offset = 992 (0x3e0), direct, name
  310 +offset = 999 (0x3e7), direct, name
  311 +offset = 1011 (0x3f3), direct, name
  312 +offset = 1021 (0x3fd), direct, name
  313 +offset = 1028 (0x404), direct, name
  314 +offset = 1034 (0x40a), direct, name
  315 +offset = 1045 (0x415), direct, name
  316 +offset = 1052 (0x41c), direct, name
  317 +offset = 1059 (0x423), direct, name
  318 +offset = 1071 (0x42f), direct, name
  319 +offset = 1078 (0x436), direct, name
  320 +offset = 1088 (0x440), direct, name
  321 +offset = 1094 (0x446), direct, name
  322 +offset = 1097 (0x449), direct, name
  323 +offset = 1106 (0x452), direct, name
  324 +offset = 1113 (0x459), direct, name
  325 +offset = 1120 (0x460), direct, name
  326 +offset = 1132 (0x46c), direct, name
  327 +offset = 1142 (0x476), direct, name
  328 +offset = 1149 (0x47d), direct, name
  329 +offset = 1156 (0x484), direct, name
  330 +offset = 1168 (0x490), direct, name
  331 +offset = 1178 (0x49a), direct, name
  332 +offset = 1182 (0x49e), direct, name
  333 +offset = 1189 (0x4a5), direct, name
  334 +offset = 1196 (0x4ac), direct, name
  335 +offset = 1203 (0x4b3), direct, name
  336 +offset = 1215 (0x4bf), direct, name
  337 +offset = 1222 (0x4c6), direct, name
  338 +offset = 1232 (0x4d0), direct, name
  339 +offset = 1239 (0x4d7), direct, name
  340 +offset = 1246 (0x4de), direct, name
  341 +offset = 1253 (0x4e5), direct, name
  342 +offset = 1260 (0x4ec), direct, name
  343 +offset = 1272 (0x4f8), direct, name
  344 +offset = 1282 (0x502), direct, name
  345 +offset = 1289 (0x509), direct, name
  346 +offset = 1295 (0x50f), direct, name
  347 +offset = 1311 (0x51f), direct, name
  348 +--- objects in stream 3 ---
  349 +offset = 4 (0x4), indirect 9/0, dictionary
  350 +offset = 13 (0xd), direct, integer
  351 +offset = 19 (0x13), direct, array
  352 +offset = 32 (0x20), direct, name
  353 +--- objects in stream 4 ---
  354 +offset = 5 (0x5), indirect 10/0, dictionary
  355 +offset = 20 (0x14), direct, string
  356 +offset = 53 (0x35), direct, string
  357 +--- objects in stream 19 ---
  358 +offset = 50 (0x32), indirect 23/0, dictionary
  359 +offset = 55 (0x37), direct, string
  360 +offset = 75 (0x4b), direct, dictionary
  361 +offset = 86 (0x56), direct, dictionary
  362 +offset = 116 (0x74), direct, dictionary
  363 +offset = 176 (0xb0), direct, array
  364 +offset = 194 (0xc2), direct, integer
  365 +offset = 197 (0xc5), indirect 24/0, array
  366 +offset = 205 (0xcd), indirect 25/0, dictionary
  367 +offset = 210 (0xd2), direct, dictionary
  368 +offset = 226 (0xe2), direct, string
  369 +offset = 263 (0x107), direct, integer
  370 +offset = 269 (0x10d), direct, name
  371 +offset = 276 (0x114), direct, dictionary
  372 +offset = 294 (0x126), direct, array
  373 +offset = 295 (0x127), direct, real
  374 +offset = 303 (0x12f), direct, real
  375 +offset = 310 (0x136), direct, real
  376 +offset = 318 (0x13e), direct, real
  377 +offset = 334 (0x14e), direct, name
  378 +offset = 343 (0x157), direct, string
  379 +offset = 360 (0x168), direct, name
  380 +offset = 377 (0x179), indirect 26/0, dictionary
  381 +offset = 388 (0x184), direct, name
  382 +offset = 415 (0x19f), direct, name
  383 +offset = 442 (0x1ba), direct, integer
  384 +offset = 475 (0x1db), direct, integer
  385 +offset = 486 (0x1e6), direct, name
  386 +offset = 497 (0x1f1), direct, name
  387 +offset = 509 (0x1fd), direct, array
  388 +offset = 510 (0x1fe), direct, integer
  389 +offset = 514 (0x202), direct, integer
  390 +offset = 518 (0x206), direct, integer
  391 +offset = 522 (0x20a), direct, integer
  392 +offset = 526 (0x20e), direct, integer
  393 +offset = 530 (0x212), direct, integer
  394 +offset = 534 (0x216), direct, integer
  395 +offset = 538 (0x21a), direct, integer
  396 +offset = 542 (0x21e), direct, integer
  397 +offset = 546 (0x222), direct, integer
  398 +offset = 550 (0x226), direct, integer
  399 +offset = 554 (0x22a), direct, integer
  400 +offset = 558 (0x22e), direct, integer
  401 +offset = 562 (0x232), direct, integer
  402 +offset = 566 (0x236), direct, integer
  403 +offset = 570 (0x23a), direct, integer
  404 +offset = 574 (0x23e), direct, integer
  405 +offset = 578 (0x242), direct, integer
  406 +offset = 582 (0x246), direct, integer
  407 +offset = 586 (0x24a), direct, integer
  408 +offset = 590 (0x24e), direct, integer
  409 +offset = 594 (0x252), direct, integer
  410 +offset = 598 (0x256), direct, integer
  411 +offset = 602 (0x25a), direct, integer
  412 +offset = 606 (0x25e), direct, integer
  413 +offset = 610 (0x262), direct, integer
  414 +offset = 614 (0x266), direct, integer
  415 +offset = 618 (0x26a), direct, integer
  416 +offset = 622 (0x26e), direct, integer
  417 +offset = 626 (0x272), direct, integer
  418 +offset = 630 (0x276), direct, integer
  419 +offset = 634 (0x27a), direct, integer
  420 +offset = 638 (0x27e), direct, integer
  421 +offset = 642 (0x282), direct, integer
  422 +offset = 646 (0x286), direct, integer
  423 +offset = 650 (0x28a), direct, integer
  424 +offset = 654 (0x28e), direct, integer
  425 +offset = 658 (0x292), direct, integer
  426 +offset = 662 (0x296), direct, integer
  427 +offset = 666 (0x29a), direct, integer
  428 +offset = 670 (0x29e), direct, integer
  429 +offset = 674 (0x2a2), direct, integer
  430 +offset = 678 (0x2a6), direct, integer
  431 +offset = 682 (0x2aa), direct, integer
  432 +offset = 686 (0x2ae), direct, integer
  433 +offset = 690 (0x2b2), direct, integer
  434 +offset = 694 (0x2b6), direct, integer
  435 +offset = 698 (0x2ba), direct, integer
  436 +offset = 702 (0x2be), direct, integer
  437 +offset = 706 (0x2c2), direct, integer
  438 +offset = 710 (0x2c6), direct, integer
  439 +offset = 714 (0x2ca), direct, integer
  440 +offset = 718 (0x2ce), direct, integer
  441 +offset = 722 (0x2d2), direct, integer
  442 +offset = 726 (0x2d6), direct, integer
  443 +offset = 730 (0x2da), direct, integer
  444 +offset = 734 (0x2de), direct, integer
  445 +offset = 738 (0x2e2), direct, integer
  446 +offset = 742 (0x2e6), direct, integer
  447 +offset = 746 (0x2ea), direct, integer
  448 +offset = 750 (0x2ee), direct, integer
  449 +offset = 754 (0x2f2), direct, integer
  450 +offset = 758 (0x2f6), direct, integer
  451 +offset = 762 (0x2fa), direct, integer
  452 +offset = 766 (0x2fe), direct, integer
  453 +offset = 770 (0x302), direct, integer
  454 +offset = 774 (0x306), direct, integer
  455 +offset = 778 (0x30a), direct, integer
  456 +offset = 782 (0x30e), direct, integer
  457 +offset = 786 (0x312), direct, integer
  458 +offset = 790 (0x316), direct, integer
  459 +offset = 794 (0x31a), direct, integer
  460 +offset = 798 (0x31e), direct, integer
  461 +offset = 802 (0x322), direct, integer
  462 +offset = 806 (0x326), direct, integer
  463 +offset = 810 (0x32a), direct, integer
  464 +offset = 814 (0x32e), direct, integer
  465 +offset = 818 (0x332), direct, integer
  466 +offset = 822 (0x336), direct, integer
  467 +offset = 826 (0x33a), direct, integer
  468 +offset = 830 (0x33e), direct, integer
  469 +offset = 834 (0x342), direct, integer
  470 +offset = 838 (0x346), direct, integer
  471 +offset = 842 (0x34a), direct, integer
  472 +offset = 846 (0x34e), direct, integer
  473 +offset = 850 (0x352), direct, integer
  474 +offset = 854 (0x356), direct, integer
  475 +offset = 858 (0x35a), direct, integer
  476 +offset = 862 (0x35e), direct, integer
  477 +offset = 866 (0x362), direct, integer
  478 +offset = 870 (0x366), direct, integer
  479 +offset = 874 (0x36a), direct, integer
  480 +offset = 878 (0x36e), direct, integer
  481 +offset = 882 (0x372), direct, integer
  482 +offset = 886 (0x376), direct, integer
  483 +offset = 890 (0x37a), direct, integer
  484 +offset = 894 (0x37e), direct, integer
  485 +offset = 898 (0x382), direct, integer
  486 +offset = 902 (0x386), direct, integer
  487 +offset = 906 (0x38a), direct, integer
  488 +offset = 910 (0x38e), direct, integer
  489 +offset = 914 (0x392), direct, integer
  490 +offset = 918 (0x396), direct, integer
  491 +offset = 922 (0x39a), direct, integer
  492 +offset = 926 (0x39e), direct, integer
  493 +offset = 930 (0x3a2), direct, integer
  494 +offset = 934 (0x3a6), direct, integer
  495 +offset = 938 (0x3aa), direct, integer
  496 +offset = 942 (0x3ae), direct, integer
  497 +offset = 946 (0x3b2), direct, integer
  498 +offset = 950 (0x3b6), direct, integer
  499 +offset = 954 (0x3ba), direct, integer
  500 +offset = 958 (0x3be), direct, integer
  501 +offset = 962 (0x3c2), direct, integer
  502 +offset = 966 (0x3c6), direct, integer
  503 +offset = 970 (0x3ca), direct, integer
  504 +offset = 974 (0x3ce), direct, integer
  505 +offset = 978 (0x3d2), direct, integer
  506 +offset = 982 (0x3d6), direct, integer
  507 +offset = 986 (0x3da), direct, integer
  508 +offset = 990 (0x3de), direct, integer
  509 +offset = 994 (0x3e2), direct, integer
  510 +offset = 998 (0x3e6), direct, integer
  511 +offset = 1002 (0x3ea), direct, integer
  512 +offset = 1006 (0x3ee), direct, integer
  513 +offset = 1010 (0x3f2), direct, integer
  514 +offset = 1014 (0x3f6), direct, integer
  515 +offset = 1018 (0x3fa), direct, integer
  516 +offset = 1022 (0x3fe), direct, integer
  517 +offset = 1026 (0x402), direct, integer
  518 +offset = 1030 (0x406), direct, integer
  519 +offset = 1034 (0x40a), direct, integer
  520 +offset = 1038 (0x40e), direct, integer
  521 +offset = 1042 (0x412), direct, integer
  522 +offset = 1047 (0x417), direct, integer
  523 +offset = 1051 (0x41b), direct, integer
  524 +offset = 1055 (0x41f), direct, integer
  525 +offset = 1059 (0x423), direct, integer
  526 +offset = 1064 (0x428), direct, integer
  527 +offset = 1068 (0x42c), direct, integer
  528 +offset = 1072 (0x430), direct, integer
  529 +offset = 1076 (0x434), direct, integer
  530 +offset = 1080 (0x438), direct, integer
  531 +offset = 1084 (0x43c), direct, integer
  532 +offset = 1088 (0x440), direct, integer
  533 +offset = 1092 (0x444), direct, integer
  534 +offset = 1096 (0x448), direct, integer
  535 +offset = 1100 (0x44c), direct, integer
  536 +offset = 1104 (0x450), direct, integer
  537 +offset = 1108 (0x454), direct, integer
  538 +offset = 1112 (0x458), direct, integer
  539 +offset = 1116 (0x45c), direct, integer
  540 +offset = 1121 (0x461), direct, integer
  541 +offset = 1125 (0x465), direct, integer
  542 +offset = 1129 (0x469), direct, integer
  543 +offset = 1133 (0x46d), direct, integer
  544 +offset = 1137 (0x471), direct, integer
  545 +offset = 1141 (0x475), direct, integer
  546 +offset = 1145 (0x479), direct, integer
  547 +offset = 1149 (0x47d), direct, integer
  548 +offset = 1153 (0x481), direct, integer
  549 +offset = 1157 (0x485), direct, integer
  550 +offset = 1161 (0x489), direct, integer
  551 +offset = 1165 (0x48d), direct, integer
  552 +offset = 1169 (0x491), direct, integer
  553 +offset = 1173 (0x495), direct, integer
  554 +offset = 1177 (0x499), direct, integer
  555 +offset = 1181 (0x49d), direct, integer
  556 +offset = 1185 (0x4a1), direct, integer
  557 +offset = 1189 (0x4a5), direct, integer
  558 +offset = 1193 (0x4a9), direct, integer
  559 +offset = 1197 (0x4ad), direct, integer
  560 +offset = 1201 (0x4b1), direct, integer
  561 +offset = 1205 (0x4b5), direct, integer
  562 +offset = 1209 (0x4b9), direct, integer
  563 +offset = 1213 (0x4bd), direct, integer
  564 +offset = 1217 (0x4c1), direct, integer
  565 +offset = 1221 (0x4c5), direct, integer
  566 +offset = 1225 (0x4c9), direct, integer
  567 +offset = 1229 (0x4cd), direct, integer
  568 +offset = 1233 (0x4d1), direct, integer
  569 +offset = 1237 (0x4d5), direct, integer
  570 +offset = 1241 (0x4d9), direct, integer
  571 +offset = 1245 (0x4dd), direct, integer
  572 +offset = 1249 (0x4e1), direct, integer
  573 +offset = 1253 (0x4e5), direct, integer
  574 +offset = 1257 (0x4e9), direct, integer
  575 +offset = 1261 (0x4ed), direct, integer
  576 +offset = 1265 (0x4f1), direct, integer
  577 +offset = 1269 (0x4f5), direct, integer
  578 +offset = 1273 (0x4f9), direct, integer
  579 +offset = 1277 (0x4fd), direct, integer
  580 +offset = 1281 (0x501), direct, integer
  581 +offset = 1285 (0x505), direct, integer
  582 +offset = 1289 (0x509), direct, integer
  583 +offset = 1293 (0x50d), direct, integer
  584 +offset = 1297 (0x511), direct, integer
  585 +offset = 1301 (0x515), direct, integer
  586 +offset = 1305 (0x519), direct, integer
  587 +offset = 1309 (0x51d), direct, integer
  588 +offset = 1313 (0x521), direct, integer
  589 +offset = 1317 (0x525), direct, integer
  590 +offset = 1321 (0x529), direct, integer
  591 +offset = 1325 (0x52d), direct, integer
  592 +offset = 1329 (0x531), direct, integer
  593 +offset = 1333 (0x535), direct, integer
  594 +offset = 1337 (0x539), direct, integer
  595 +offset = 1341 (0x53d), direct, integer
  596 +offset = 1345 (0x541), direct, integer
  597 +offset = 1349 (0x545), direct, integer
  598 +offset = 1353 (0x549), direct, integer
  599 +offset = 1357 (0x54d), direct, integer
  600 +offset = 1361 (0x551), direct, integer
  601 +offset = 1365 (0x555), direct, integer
  602 +offset = 1369 (0x559), direct, integer
  603 +offset = 1373 (0x55d), direct, integer
  604 +offset = 1377 (0x561), direct, integer
  605 +offset = 1381 (0x565), direct, integer
  606 +offset = 1385 (0x569), direct, integer
  607 +offset = 1389 (0x56d), direct, integer
  608 +offset = 1393 (0x571), direct, integer
  609 +offset = 1397 (0x575), direct, integer
  610 +offset = 1401 (0x579), direct, integer
  611 +offset = 1405 (0x57d), direct, integer
  612 +offset = 1409 (0x581), direct, integer
  613 +offset = 1413 (0x585), direct, integer
  614 +offset = 1417 (0x589), direct, integer
  615 +offset = 1421 (0x58d), direct, integer
  616 +offset = 1425 (0x591), direct, integer
  617 +offset = 1429 (0x595), direct, integer
  618 +offset = 1433 (0x599), direct, integer
  619 +offset = 1437 (0x59d), direct, integer
  620 +offset = 1441 (0x5a1), direct, integer
  621 +offset = 1445 (0x5a5), direct, integer
  622 +offset = 1449 (0x5a9), direct, integer
  623 +offset = 1453 (0x5ad), direct, integer
  624 +offset = 1457 (0x5b1), direct, integer
  625 +offset = 1461 (0x5b5), direct, integer
  626 +offset = 1465 (0x5b9), direct, integer
  627 +offset = 1469 (0x5bd), direct, integer
  628 +offset = 1473 (0x5c1), direct, integer
  629 +offset = 1477 (0x5c5), direct, integer
  630 +offset = 1481 (0x5c9), direct, integer
  631 +offset = 1485 (0x5cd), direct, integer
  632 +offset = 1489 (0x5d1), direct, integer
  633 +offset = 1493 (0x5d5), direct, integer
  634 +offset = 1497 (0x5d9), direct, integer
  635 +offset = 1501 (0x5dd), direct, integer
  636 +offset = 1505 (0x5e1), direct, integer
  637 +offset = 1509 (0x5e5), direct, integer
  638 +offset = 1513 (0x5e9), direct, integer
  639 +offset = 1517 (0x5ed), direct, integer
  640 +offset = 1521 (0x5f1), direct, integer
  641 +offset = 1525 (0x5f5), direct, integer
  642 +offset = 1529 (0x5f9), direct, integer
  643 +offset = 1533 (0x5fd), direct, integer
  644 +offset = 1539 (0x603), indirect 27/0, dictionary
  645 +offset = 1549 (0x60d), direct, integer
  646 +offset = 1563 (0x61b), direct, integer
  647 +offset = 1574 (0x626), direct, string
  648 +offset = 3413 (0xd55), direct, integer
  649 +offset = 3424 (0xd60), direct, integer
  650 +offset = 3435 (0xd6b), direct, array
  651 +offset = 3436 (0xd6c), direct, integer
  652 +offset = 3441 (0xd71), direct, integer
  653 +offset = 3446 (0xd76), direct, integer
  654 +offset = 3451 (0xd7b), direct, integer
  655 +offset = 3466 (0xd8a), direct, string
  656 +offset = 3504 (0xdb0), direct, name
  657 +offset = 3534 (0xdce), direct, name
  658 +offset = 3553 (0xde1), direct, integer
  659 +offset = 3569 (0xdf1), direct, integer
  660 +offset = 3577 (0xdf9), direct, integer
  661 +offset = 3584 (0xe00), direct, name
  662 +offset = 3608 (0xe18), direct, integer
  663 +offset = 3613 (0xe1d), indirect 28/0, dictionary
  664 +offset = 3624 (0xe28), direct, name
  665 +offset = 3643 (0xe3b), direct, name
  666 +offset = 3664 (0xe50), direct, name
  667 +offset = 3675 (0xe5b), direct, name
  668 +offset = 3686 (0xe66), direct, name
  669 +offset = 3693 (0xe6d), indirect 29/0, array
  670 +offset = 3694 (0xe6e), direct, name
  671 +offset = 3698 (0xe72), direct, name
  672 +succeeded
... ...
qpdf/qtest/qpdf/minimal-parsedoffset.out 0 โ†’ 100644
  1 +--- objects not in streams ---
  2 +offset = 17 (0x11), indirect 1/0, dictionary
  3 +offset = 28 (0x1c), direct, name
  4 +offset = 71 (0x47), indirect 2/0, dictionary
  5 +offset = 82 (0x52), direct, name
  6 +offset = 97 (0x61), direct, array
  7 +offset = 122 (0x7a), direct, integer
  8 +offset = 143 (0x8f), indirect 3/0, dictionary
  9 +offset = 154 (0x9a), direct, name
  10 +offset = 188 (0xbc), direct, array
  11 +offset = 189 (0xbd), direct, integer
  12 +offset = 191 (0xbf), direct, integer
  13 +offset = 193 (0xc1), direct, integer
  14 +offset = 197 (0xc5), direct, integer
  15 +offset = 233 (0xe9), direct, dictionary
  16 +offset = 265 (0x109), direct, dictionary
  17 +offset = 315 (0x13b), direct, dictionary
  18 +offset = 328 (0x148), direct, integer
  19 +offset = 341 (0x155), indirect 4/0, stream
  20 +offset = 411 (0x19b), indirect 5/0, array
  21 +offset = 415 (0x19f), direct, name
  22 +offset = 422 (0x1a6), direct, name
  23 +offset = 446 (0x1be), indirect 6/0, dictionary
  24 +offset = 457 (0x1c9), direct, name
  25 +offset = 474 (0x1da), direct, name
  26 +offset = 489 (0x1e9), direct, name
  27 +offset = 505 (0x1f9), direct, name
  28 +offset = 528 (0x210), direct, name
  29 +succeeded
... ...
qpdf/test_parsedoffset.cc 0 โ†’ 100644
  1 +#include <qpdf/QPDF.hh>
  2 +#include <qpdf/QPDFObjectHandle.hh>
  3 +
  4 +#include <algorithm>
  5 +#include <iostream>
  6 +#include <map>
  7 +#include <set>
  8 +#include <sstream>
  9 +#include <string>
  10 +#include <vector>
  11 +#include <cstdlib>
  12 +
  13 +void usage()
  14 +{
  15 + std::cerr
  16 + << "Usage: test_parsedoffset INPUT.pdf"
  17 + << std::endl;
  18 +}
  19 +
  20 +std::string make_objdesc(qpdf_offset_t offset, QPDFObjectHandle obj)
  21 +{
  22 + std::stringstream ss;
  23 + ss << "offset = "
  24 + << offset
  25 + << " (0x"
  26 + << std::hex << offset << std::dec
  27 + << "), ";
  28 +
  29 + if (obj.isIndirect())
  30 + {
  31 + ss << "indirect "
  32 + << obj.getObjectID()
  33 + << "/"
  34 + << obj.getGeneration()
  35 + << ", ";
  36 + }
  37 + else
  38 + {
  39 + ss << "direct, ";
  40 + }
  41 +
  42 + ss << obj.getTypeName();
  43 +
  44 + return ss.str();
  45 +}
  46 +
  47 +void walk(size_t stream_number, QPDFObjectHandle obj,
  48 + std::vector<
  49 + std::vector<
  50 + std::pair<qpdf_offset_t, std::string>
  51 + >
  52 + >
  53 + &result)
  54 +{
  55 + qpdf_offset_t offset = obj.getParsedOffset();
  56 + std::pair<qpdf_offset_t, std::string> p =
  57 + std::make_pair(offset, make_objdesc(offset, obj));
  58 +
  59 + if (result.size() < stream_number + 1)
  60 + {
  61 + result.resize(stream_number + 1);
  62 + }
  63 + result[stream_number].push_back(p);
  64 +
  65 + if (obj.isArray())
  66 + {
  67 + std::vector<QPDFObjectHandle> array = obj.getArrayAsVector();
  68 + for(std::vector<QPDFObjectHandle>::iterator iter = array.begin();
  69 + iter != array.end(); ++iter)
  70 + {
  71 + if (!iter->isIndirect())
  72 + {
  73 + // QPDF::GetAllObjects() enumerates all indirect objects.
  74 + // So only the direct objects are recursed here.
  75 + walk(stream_number, *iter, result);
  76 + }
  77 + }
  78 + }
  79 + else if(obj.isDictionary())
  80 + {
  81 + std::set<std::string> keys = obj.getKeys();
  82 + for(std::set<std::string>::iterator iter = keys.begin();
  83 + iter != keys.end(); ++iter)
  84 + {
  85 + QPDFObjectHandle item = obj.getKey(*iter);
  86 + if (!item.isIndirect())
  87 + {
  88 + // QPDF::GetAllObjects() enumerates all indirect objects.
  89 + // So only the direct objects are recursed here.
  90 + walk(stream_number, item, result);
  91 + }
  92 + }
  93 + }
  94 + else if(obj.isStream())
  95 + {
  96 + walk(stream_number, obj.getDict(), result);
  97 + }
  98 +}
  99 +
  100 +void process(std::string fn,
  101 + std::vector<
  102 + std::vector<
  103 + std::pair<qpdf_offset_t, std::string>
  104 + >
  105 + > &result)
  106 +{
  107 + QPDF qpdf;
  108 + qpdf.processFile(fn.c_str());
  109 + std::vector<QPDFObjectHandle> objs = qpdf.getAllObjects();
  110 + std::map<QPDFObjGen, QPDFXRefEntry> xrefs = qpdf.getXRefTable();
  111 +
  112 + for (std::vector<QPDFObjectHandle>::iterator iter = objs.begin();
  113 + iter != objs.end(); ++iter)
  114 + {
  115 + if (xrefs.count(iter->getObjGen()) == 0)
  116 + {
  117 + std::cerr
  118 + << iter->getObjectID()
  119 + << "/"
  120 + << iter->getGeneration()
  121 + << " is not found in xref table"
  122 + << std::endl;
  123 + std::exit(2);
  124 + }
  125 +
  126 + QPDFXRefEntry xref = xrefs[iter->getObjGen()];
  127 + size_t stream_number;
  128 +
  129 + switch (xref.getType())
  130 + {
  131 + case 0:
  132 + std::cerr
  133 + << iter->getObjectID()
  134 + << "/"
  135 + << iter->getGeneration()
  136 + << " xref entry is free"
  137 + << std::endl;
  138 + std::exit(2);
  139 + case 1:
  140 + stream_number = 0;
  141 + break;
  142 + case 2:
  143 + stream_number = static_cast<size_t>(xref.getObjStreamNumber());
  144 + break;
  145 + default:
  146 + std::cerr << "unknown xref entry type" << std::endl;
  147 + std::exit(2);
  148 + }
  149 +
  150 + walk(stream_number, *iter, result);
  151 + }
  152 +}
  153 +
  154 +int main(int argc, char *argv[])
  155 +{
  156 + if (argc != 2)
  157 + {
  158 + usage();
  159 + std::exit(2);
  160 + }
  161 +
  162 + try
  163 + {
  164 + std::vector<
  165 + std::vector<
  166 + std::pair<qpdf_offset_t, std::string>
  167 + >
  168 + > table;
  169 +
  170 + process(argv[1], table);
  171 +
  172 + for (size_t i = 0; i < table.size(); ++i)
  173 + {
  174 + if (table[i].size() == 0)
  175 + {
  176 + continue;
  177 + }
  178 +
  179 + std::sort(table[i].begin(), table[i].end());
  180 + if (i == 0)
  181 + {
  182 + std::cout << "--- objects not in streams ---" << std::endl;
  183 + }
  184 + else
  185 + {
  186 + std::cout
  187 + << "--- objects in stream " << i << " ---" << std::endl;
  188 + }
  189 +
  190 + for (std::vector<
  191 + std::pair<qpdf_offset_t, std::string>
  192 + >::iterator
  193 + iter = table[i].begin();
  194 + iter != table[i].end(); ++iter)
  195 + {
  196 + std::cout
  197 + << iter->second
  198 + << std::endl;
  199 + }
  200 + }
  201 +
  202 + std::cout << "succeeded" << std::endl;
  203 + }
  204 + catch (std::exception& e)
  205 + {
  206 + std::cerr << e.what() << std::endl;
  207 + std::exit(2);
  208 + }
  209 +
  210 + return 0;
  211 +}
... ...