Commit 1ecc6bb29e24a4f89470ff91b2682b46e0576ad4

Authored by Jay Berkenbilt
1 parent 467e5d62

Don't lose character after \d or \dd parsing string (fixes #1050)

ChangeLog
  1 +2023-10-14 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Fix serious bug: qpdf could discard a the character after an
  4 + escaped octal string. For content, this would only happen with QDF
  5 + or when normalizing content, but it could have happened in a
  6 + binary string. This bug was introduced between 10.6.3 and 11.0.0.
  7 + Fixes #1050.
  8 +
1 9 2023-10-07 Jay Berkenbilt <ejb@ql.org>
2 10  
3 11 * 11.6.2: release
... ...
libqpdf/QPDFTokenizer.cc
... ... @@ -145,9 +145,8 @@ QPDFTokenizer::presentCharacter(char ch)
145 145 void
146 146 QPDFTokenizer::handleCharacter(char ch)
147 147 {
148   - // State machine is implemented such that the final character may not be handled. This happens
149   - // whenever you have to use a character from the next token to detect the end of the current
150   - // token.
  148 + // In some cases, functions called below may call a second handler. This happens whenever you
  149 + // have to use a character from the next token to detect the end of the current token.
151 150  
152 151 switch (this->state) {
153 152 case st_top:
... ... @@ -692,16 +691,21 @@ QPDFTokenizer::inHexstring2nd(char ch)
692 691 void
693 692 QPDFTokenizer::inCharCode(char ch)
694 693 {
  694 + bool handled = false;
695 695 if (('0' <= ch) && (ch <= '7')) {
696 696 this->char_code = 8 * this->char_code + (int(ch) - int('0'));
697 697 if (++(this->digit_count) < 3) {
698 698 return;
699 699 }
700   - // We've accumulated \ddd. PDF Spec says to ignore high-order overflow.
  700 + handled = true;
701 701 }
  702 + // We've accumulated \ddd or we have \d or \dd followed by other than an octal digit. The PDF
  703 + // Spec says to ignore high-order overflow.
702 704 this->val += char(this->char_code % 256);
703 705 this->state = st_in_string;
704   - return;
  706 + if (!handled) {
  707 + inString(ch);
  708 + }
705 709 }
706 710  
707 711 void
... ...
qpdf/qtest/qpdf/tokens-maxlen.out
... ... @@ -181,352 +181,352 @@ skipping to endstream
181 181 7121: space: \x0a
182 182 7122: word: stream
183 183 skipping to endstream
184   -7469: word: endstream
185   -7478: space: \x0a
186   -7479: word: endobj
187   -7485: space: \x0a\x0a
188   -7487: integer: 44
189   -7489: space:
190   -7490: integer: 0
191   -7491: space:
192   -7492: word: obj
193   -7495: space: \x0a
194   -7496: integer: 340
195   -7499: space: \x0a
196   -7500: word: endobj
197   -7506: space: \x0a\x0a
198   -7508: comment: %% Contents for page 5
199   -7530: space: \x0a
200   -7531: comment: %% Original object ID: 41 0
201   -7558: space: \x0a
202   -7559: integer: 45
203   -7561: space:
204   -7562: integer: 0
205   -7563: space:
206   -7564: word: obj
207   -7567: space: \x0a
208   -7568: dict_open: <<
209   -7570: space: \x0a
210   -7573: name: /Length
211   -7580: space:
212   -7581: integer: 46
213   -7583: space:
214   -7584: integer: 0
215   -7585: space:
216   -7586: word: R
217   -7587: space: \x0a
218   -7588: dict_close: >>
219   -7590: space: \x0a
220   -7591: word: stream
  184 +7524: word: endstream
  185 +7533: space: \x0a
  186 +7534: word: endobj
  187 +7540: space: \x0a\x0a
  188 +7542: integer: 44
  189 +7544: space:
  190 +7545: integer: 0
  191 +7546: space:
  192 +7547: word: obj
  193 +7550: space: \x0a
  194 +7551: integer: 395
  195 +7554: space: \x0a
  196 +7555: word: endobj
  197 +7561: space: \x0a\x0a
  198 +7563: comment: %% Contents for page 5
  199 +7585: space: \x0a
  200 +7586: comment: %% Original object ID: 41 0
  201 +7613: space: \x0a
  202 +7614: integer: 45
  203 +7616: space:
  204 +7617: integer: 0
  205 +7618: space:
  206 +7619: word: obj
  207 +7622: space: \x0a
  208 +7623: dict_open: <<
  209 +7625: space: \x0a
  210 +7628: name: /Length
  211 +7635: space:
  212 +7636: integer: 46
  213 +7638: space:
  214 +7639: integer: 0
  215 +7640: space:
  216 +7641: word: R
  217 +7642: space: \x0a
  218 +7643: dict_close: >>
  219 +7645: space: \x0a
  220 +7646: word: stream
221 221 skipping to endstream
222   -7666: word: endstream
223   -7675: space: \x0a
224   -7676: word: endobj
225   -7682: space: \x0a
226   -7683: comment: %QDF: ignore_newline
227   -7703: space: \x0a\x0a
228   -7705: integer: 46
229   -7707: space:
230   -7708: integer: 0
231   -7709: space:
232   -7710: word: obj
233   -7713: space: \x0a
234   -7714: integer: 67
235   -7716: space: \x0a
236   -7717: word: endobj
237   -7723: space: \x0a\x0a
238   -7725: comment: %% Contents for page 6
239   -7747: space: \x0a
240   -7748: comment: %% Original object ID: 42 0
241   -7775: space: \x0a
242   -7776: integer: 47
243   -7778: space:
244   -7779: integer: 0
245   -7780: space:
246   -7781: word: obj
247   -7784: space: \x0a
248   -7785: dict_open: <<
249   -7787: space: \x0a
250   -7790: name: /Length
251   -7797: space:
252   -7798: integer: 48
253   -7800: space:
254   -7801: integer: 0
255   -7802: space:
256   -7803: word: R
257   -7804: space: \x0a
258   -7805: dict_close: >>
259   -7807: space: \x0a
260   -7808: word: stream
  222 +7721: word: endstream
  223 +7730: space: \x0a
  224 +7731: word: endobj
  225 +7737: space: \x0a
  226 +7738: comment: %QDF: ignore_newline
  227 +7758: space: \x0a\x0a
  228 +7760: integer: 46
  229 +7762: space:
  230 +7763: integer: 0
  231 +7764: space:
  232 +7765: word: obj
  233 +7768: space: \x0a
  234 +7769: integer: 67
  235 +7771: space: \x0a
  236 +7772: word: endobj
  237 +7778: space: \x0a\x0a
  238 +7780: comment: %% Contents for page 6
  239 +7802: space: \x0a
  240 +7803: comment: %% Original object ID: 42 0
  241 +7830: space: \x0a
  242 +7831: integer: 47
  243 +7833: space:
  244 +7834: integer: 0
  245 +7835: space:
  246 +7836: word: obj
  247 +7839: space: \x0a
  248 +7840: dict_open: <<
  249 +7842: space: \x0a
  250 +7845: name: /Length
  251 +7852: space:
  252 +7853: integer: 48
  253 +7855: space:
  254 +7856: integer: 0
  255 +7857: space:
  256 +7858: word: R
  257 +7859: space: \x0a
  258 +7860: dict_close: >>
  259 +7862: space: \x0a
  260 +7863: word: stream
261 261 skipping to endstream
262   -7859: word: endstream
263   -7868: space: \x0a
264   -7869: word: endobj
265   -7875: space: \x0a\x0a
266   -7877: integer: 48
267   -7879: space:
268   -7880: integer: 0
269   -7881: space:
270   -7882: word: obj
271   -7885: space: \x0a
272   -7886: integer: 44
273   -7888: space: \x0a
274   -7889: word: endobj
275   -7895: space: \x0a\x0a
276   -7897: comment: %% Contents for page 7
277   -7919: space: \x0a
278   -7920: comment: %% Original object ID: 43 0
279   -7947: space: \x0a
280   -7948: integer: 49
281   -7950: space:
282   -7951: integer: 0
283   -7952: space:
284   -7953: word: obj
285   -7956: space: \x0a
286   -7957: dict_open: <<
287   -7959: space: \x0a
288   -7962: name: /Length
289   -7969: space:
290   -7970: integer: 50
291   -7972: space:
292   -7973: integer: 0
293   -7974: space:
294   -7975: word: R
295   -7976: space: \x0a
296   -7977: dict_close: >>
297   -7979: space: \x0a
298   -7980: word: stream
  262 +7914: word: endstream
  263 +7923: space: \x0a
  264 +7924: word: endobj
  265 +7930: space: \x0a\x0a
  266 +7932: integer: 48
  267 +7934: space:
  268 +7935: integer: 0
  269 +7936: space:
  270 +7937: word: obj
  271 +7940: space: \x0a
  272 +7941: integer: 44
  273 +7943: space: \x0a
  274 +7944: word: endobj
  275 +7950: space: \x0a\x0a
  276 +7952: comment: %% Contents for page 7
  277 +7974: space: \x0a
  278 +7975: comment: %% Original object ID: 43 0
  279 +8002: space: \x0a
  280 +8003: integer: 49
  281 +8005: space:
  282 +8006: integer: 0
  283 +8007: space:
  284 +8008: word: obj
  285 +8011: space: \x0a
  286 +8012: dict_open: <<
  287 +8014: space: \x0a
  288 +8017: name: /Length
  289 +8024: space:
  290 +8025: integer: 50
  291 +8027: space:
  292 +8028: integer: 0
  293 +8029: space:
  294 +8030: word: R
  295 +8031: space: \x0a
  296 +8032: dict_close: >>
  297 +8034: space: \x0a
  298 +8035: word: stream
299 299 skipping to endstream
300   -8306: word: endstream
301   -8315: space: \x0a
302   -8316: word: endobj
303   -8322: space: \x0a
304   -8323: comment: %QDF: ignore_newline
305   -8343: space: \x0a\x0a
306   -8345: integer: 50
307   -8347: space:
308   -8348: integer: 0
309   -8349: space:
310   -8350: word: obj
311   -8353: space: \x0a
312   -8354: integer: 318
313   -8357: space: \x0a
314   -8358: word: endobj
315   -8364: space: \x0a\x0a
316   -8366: comment: %% Contents for page 8
317   -8388: space: \x0a
318   -8389: comment: %% Original object ID: 44 0
319   -8416: space: \x0a
320   -8417: integer: 51
321   -8419: space:
322   -8420: integer: 0
323   -8421: space:
324   -8422: word: obj
325   -8425: space: \x0a
326   -8426: dict_open: <<
327   -8428: space: \x0a
328   -8431: name: /Length
329   -8438: space:
330   -8439: integer: 52
331   -8441: space:
332   -8442: integer: 0
333   -8443: space:
334   -8444: word: R
335   -8445: space: \x0a
336   -8446: dict_close: >>
337   -8448: space: \x0a
338   -8449: word: stream
  300 +8361: word: endstream
  301 +8370: space: \x0a
  302 +8371: word: endobj
  303 +8377: space: \x0a
  304 +8378: comment: %QDF: ignore_newline
  305 +8398: space: \x0a\x0a
  306 +8400: integer: 50
  307 +8402: space:
  308 +8403: integer: 0
  309 +8404: space:
  310 +8405: word: obj
  311 +8408: space: \x0a
  312 +8409: integer: 318
  313 +8412: space: \x0a
  314 +8413: word: endobj
  315 +8419: space: \x0a\x0a
  316 +8421: comment: %% Contents for page 8
  317 +8443: space: \x0a
  318 +8444: comment: %% Original object ID: 44 0
  319 +8471: space: \x0a
  320 +8472: integer: 51
  321 +8474: space:
  322 +8475: integer: 0
  323 +8476: space:
  324 +8477: word: obj
  325 +8480: space: \x0a
  326 +8481: dict_open: <<
  327 +8483: space: \x0a
  328 +8486: name: /Length
  329 +8493: space:
  330 +8494: integer: 52
  331 +8496: space:
  332 +8497: integer: 0
  333 +8498: space:
  334 +8499: word: R
  335 +8500: space: \x0a
  336 +8501: dict_close: >>
  337 +8503: space: \x0a
  338 +8504: word: stream
339 339 skipping to endstream
340   -8500: word: endstream
341   -8509: space: \x0a
342   -8510: word: endobj
343   -8516: space: \x0a\x0a
344   -8518: integer: 52
345   -8520: space:
346   -8521: integer: 0
347   -8522: space:
348   -8523: word: obj
349   -8526: space: \x0a
350   -8527: integer: 44
351   -8529: space: \x0a
352   -8530: word: endobj
353   -8536: space: \x0a\x0a
354   -8538: comment: %% Contents for page 9
355   -8560: space: \x0a
356   -8561: comment: %% Original object ID: 45 0
357   -8588: space: \x0a
358   -8589: integer: 53
359   -8591: space:
360   -8592: integer: 0
361   -8593: space:
362   -8594: word: obj
363   -8597: space: \x0a
364   -8598: dict_open: <<
365   -8600: space: \x0a
366   -8603: name: /Length
367   -8610: space:
368   -8611: integer: 54
369   -8613: space:
370   -8614: integer: 0
371   -8615: space:
372   -8616: word: R
373   -8617: space: \x0a
374   -8618: dict_close: >>
375   -8620: space: \x0a
376   -8621: word: stream
  340 +8555: word: endstream
  341 +8564: space: \x0a
  342 +8565: word: endobj
  343 +8571: space: \x0a\x0a
  344 +8573: integer: 52
  345 +8575: space:
  346 +8576: integer: 0
  347 +8577: space:
  348 +8578: word: obj
  349 +8581: space: \x0a
  350 +8582: integer: 44
  351 +8584: space: \x0a
  352 +8585: word: endobj
  353 +8591: space: \x0a\x0a
  354 +8593: comment: %% Contents for page 9
  355 +8615: space: \x0a
  356 +8616: comment: %% Original object ID: 45 0
  357 +8643: space: \x0a
  358 +8644: integer: 53
  359 +8646: space:
  360 +8647: integer: 0
  361 +8648: space:
  362 +8649: word: obj
  363 +8652: space: \x0a
  364 +8653: dict_open: <<
  365 +8655: space: \x0a
  366 +8658: name: /Length
  367 +8665: space:
  368 +8666: integer: 54
  369 +8668: space:
  370 +8669: integer: 0
  371 +8670: space:
  372 +8671: word: R
  373 +8672: space: \x0a
  374 +8673: dict_close: >>
  375 +8675: space: \x0a
  376 +8676: word: stream
377 377 skipping to endstream
378   -8672: word: endstream
379   -8681: space: \x0a
380   -8682: word: endobj
381   -8688: space: \x0a\x0a
382   -8690: integer: 54
383   -8692: space:
384   -8693: integer: 0
385   -8694: space:
386   -8695: word: obj
387   -8698: space: \x0a
388   -8699: integer: 44
389   -8701: space: \x0a
390   -8702: word: endobj
391   -8708: space: \x0a\x0a
392   -8710: comment: %% Contents for page 10
393   -8733: space: \x0a
394   -8734: comment: %% Original object ID: 46 0
395   -8761: space: \x0a
396   -8762: integer: 55
397   -8764: space:
398   -8765: integer: 0
399   -8766: space:
400   -8767: word: obj
401   -8770: space: \x0a
402   -8771: dict_open: <<
403   -8773: space: \x0a
404   -8776: name: /Length
405   -8783: space:
406   -8784: integer: 56
407   -8786: space:
408   -8787: integer: 0
409   -8788: space:
410   -8789: word: R
411   -8790: space: \x0a
412   -8791: dict_close: >>
413   -8793: space: \x0a
414   -8794: word: stream
  378 +8727: word: endstream
  379 +8736: space: \x0a
  380 +8737: word: endobj
  381 +8743: space: \x0a\x0a
  382 +8745: integer: 54
  383 +8747: space:
  384 +8748: integer: 0
  385 +8749: space:
  386 +8750: word: obj
  387 +8753: space: \x0a
  388 +8754: integer: 44
  389 +8756: space: \x0a
  390 +8757: word: endobj
  391 +8763: space: \x0a\x0a
  392 +8765: comment: %% Contents for page 10
  393 +8788: space: \x0a
  394 +8789: comment: %% Original object ID: 46 0
  395 +8816: space: \x0a
  396 +8817: integer: 55
  397 +8819: space:
  398 +8820: integer: 0
  399 +8821: space:
  400 +8822: word: obj
  401 +8825: space: \x0a
  402 +8826: dict_open: <<
  403 +8828: space: \x0a
  404 +8831: name: /Length
  405 +8838: space:
  406 +8839: integer: 56
  407 +8841: space:
  408 +8842: integer: 0
  409 +8843: space:
  410 +8844: word: R
  411 +8845: space: \x0a
  412 +8846: dict_close: >>
  413 +8848: space: \x0a
  414 +8849: word: stream
415 415 skipping to endstream
416   -8845: word: endstream
417   -8854: space: \x0a
418   -8855: word: endobj
419   -8861: space: \x0a\x0a
420   -8863: integer: 56
421   -8865: space:
422   -8866: integer: 0
423   -8867: space:
424   -8868: word: obj
425   -8871: space: \x0a
426   -8872: integer: 44
427   -8874: space: \x0a
428   -8875: word: endobj
429   -8881: space: \x0a\x0a
430   -8883: comment: %% Contents for page 11
431   -8906: space: \x0a
432   -8907: comment: %% Original object ID: 47 0
433   -8934: space: \x0a
434   -8935: integer: 57
435   -8937: space:
436   -8938: integer: 0
437   -8939: space:
438   -8940: word: obj
439   -8943: space: \x0a
440   -8944: dict_open: <<
441   -8946: space: \x0a
442   -8949: name: /Length
443   -8956: space:
444   -8957: integer: 58
445   -8959: space:
446   -8960: integer: 0
447   -8961: space:
448   -8962: word: R
449   -8963: space: \x0a
450   -8964: dict_close: >>
451   -8966: space: \x0a
452   -8967: word: stream
  416 +8900: word: endstream
  417 +8909: space: \x0a
  418 +8910: word: endobj
  419 +8916: space: \x0a\x0a
  420 +8918: integer: 56
  421 +8920: space:
  422 +8921: integer: 0
  423 +8922: space:
  424 +8923: word: obj
  425 +8926: space: \x0a
  426 +8927: integer: 44
  427 +8929: space: \x0a
  428 +8930: word: endobj
  429 +8936: space: \x0a\x0a
  430 +8938: comment: %% Contents for page 11
  431 +8961: space: \x0a
  432 +8962: comment: %% Original object ID: 47 0
  433 +8989: space: \x0a
  434 +8990: integer: 57
  435 +8992: space:
  436 +8993: integer: 0
  437 +8994: space:
  438 +8995: word: obj
  439 +8998: space: \x0a
  440 +8999: dict_open: <<
  441 +9001: space: \x0a
  442 +9004: name: /Length
  443 +9011: space:
  444 +9012: integer: 58
  445 +9014: space:
  446 +9015: integer: 0
  447 +9016: space:
  448 +9017: word: R
  449 +9018: space: \x0a
  450 +9019: dict_close: >>
  451 +9021: space: \x0a
  452 +9022: word: stream
453 453 skipping to endstream
454   -9018: word: endstream
455   -9027: space: \x0a
456   -9028: word: endobj
457   -9034: space: \x0a\x0a
458   -9036: integer: 58
459   -9038: space:
460   -9039: integer: 0
461   -9040: space:
462   -9041: word: obj
463   -9044: space: \x0a
464   -9045: integer: 44
465   -9047: space: \x0a
466   -9048: word: endobj
467   -9054: space: \x0a\x0a
468   -9056: integer: 59
469   -9058: space:
470   -9059: integer: 0
471   -9060: space:
472   -9061: word: obj
473   -9064: space: \x0a
474   -9065: dict_open: <<
475   -9067: space: \x0a
476   -9070: name: /Type
477   -9075: space:
478   -9076: name: /XRef
479   -9081: space: \x0a
480   -9084: name: /Length
481   -9091: space:
482   -9092: integer: 240
483   -9095: space: \x0a
484   -9098: name: /W
485   -9100: space:
486   -9101: array_open: [
487   -9102: space:
488   -9103: integer: 1
489   -9104: space:
490   -9105: integer: 2
491   -9106: space:
492   -9107: integer: 1
493   -9108: space:
494   -9109: array_close: ]
495   -9110: space: \x0a
496   -9113: name: /Root
497   -9118: space:
498   -9119: integer: 2
499   -9120: space:
500   -9121: integer: 0
501   -9122: space:
502   -9123: word: R
503   -9124: space: \x0a
504   -9127: name: /Size
505   -9132: space:
506   -9133: integer: 60
507   -9135: space: \x0a
508   -9138: name: /ID
509   -9141: space:
510   -9142: array_open: [
511   -9143: string: \x88\x04\x8e\x17\xc9a\xe0\x94\xff\xec\xe9\x8c\xb8\x8cF\xd0 (raw: <88048e17c961e094ffece98cb88c46d0>)
512   -9177: string: \xed\xd6\x0f\xe8\xee\x87\xf8\x871\xa8o\x81\x9f\xe6Q\x99 (raw: <edd60fe8ee87f88731a86f819fe65199>)
513   -9211: array_close: ]
514   -9212: space: \x0a
515   -9213: dict_close: >>
516   -9215: space: \x0a
517   -9216: word: stream
  454 +9073: word: endstream
  455 +9082: space: \x0a
  456 +9083: word: endobj
  457 +9089: space: \x0a\x0a
  458 +9091: integer: 58
  459 +9093: space:
  460 +9094: integer: 0
  461 +9095: space:
  462 +9096: word: obj
  463 +9099: space: \x0a
  464 +9100: integer: 44
  465 +9102: space: \x0a
  466 +9103: word: endobj
  467 +9109: space: \x0a\x0a
  468 +9111: integer: 59
  469 +9113: space:
  470 +9114: integer: 0
  471 +9115: space:
  472 +9116: word: obj
  473 +9119: space: \x0a
  474 +9120: dict_open: <<
  475 +9122: space: \x0a
  476 +9125: name: /Type
  477 +9130: space:
  478 +9131: name: /XRef
  479 +9136: space: \x0a
  480 +9139: name: /Length
  481 +9146: space:
  482 +9147: integer: 240
  483 +9150: space: \x0a
  484 +9153: name: /W
  485 +9155: space:
  486 +9156: array_open: [
  487 +9157: space:
  488 +9158: integer: 1
  489 +9159: space:
  490 +9160: integer: 2
  491 +9161: space:
  492 +9162: integer: 1
  493 +9163: space:
  494 +9164: array_close: ]
  495 +9165: space: \x0a
  496 +9168: name: /Root
  497 +9173: space:
  498 +9174: integer: 2
  499 +9175: space:
  500 +9176: integer: 0
  501 +9177: space:
  502 +9178: word: R
  503 +9179: space: \x0a
  504 +9182: name: /Size
  505 +9187: space:
  506 +9188: integer: 60
  507 +9190: space: \x0a
  508 +9193: name: /ID
  509 +9196: space:
  510 +9197: array_open: [
  511 +9198: string: \x88\x04\x8e\x17\xc9a\xe0\x94\xff\xec\xe9\x8c\xb8\x8cF\xd0 (raw: <88048e17c961e094ffece98cb88c46d0>)
  512 +9232: string: \xed\xd6\x0f\xe8\xee\x87\xf8\x871\xa8o\x81\x9f\xe6Q\x99 (raw: <edd60fe8ee87f88731a86f819fe65199>)
  513 +9266: array_close: ]
  514 +9267: space: \x0a
  515 +9268: dict_close: >>
  516 +9270: space: \x0a
  517 +9271: word: stream
518 518 skipping to endstream
519   -9464: word: endstream
520   -9473: space: \x0a
521   -9474: word: endobj
522   -9480: space: \x0a\x0a
523   -9482: word: startxref
524   -9491: space: \x0a
525   -9492: integer: 9056
526   -9496: space: \x0a
527   -9497: comment: %%EOF
528   -9502: space: \x0a
529   -9503: eof
  519 +9519: word: endstream
  520 +9528: space: \x0a
  521 +9529: word: endobj
  522 +9535: space: \x0a\x0a
  523 +9537: word: startxref
  524 +9546: space: \x0a
  525 +9547: integer: 9111
  526 +9551: space: \x0a
  527 +9552: comment: %%EOF
  528 +9557: space: \x0a
  529 +9558: eof
530 530 --- END FILE ---
531 531 --- BEGIN PAGE 1 ---
532 532 0: word: BT
... ... @@ -669,69 +669,73 @@ skipping to endstream
669 669 117: space: \x0a
670 670 120: string: qu\x0a\x0a\x0a\x0a\x0a\x0aack (raw: (qu\x0a\x0d\x0a\x0a\x0d\x0d\x0a\x0aack))
671 671 135: space: \x0a
672   -138: integer: 72
673   -140: space:
674   -141: integer: 720
675   -144: space:
676   -145: word: Td
677   -147: space: \x0a
678   -150: real: 3.14
679   -154: space: \x0a
680   -157: real: 3.
681   -159: space: \x0a
682   -162: real: .14
683   -165: space: \x0a
684   -168: real: +3.14
685   -173: space: \x0a
686   -176: real: +3.
687   -179: space: \x0a
688   -182: real: +.14
689   -186: space: \x0a
690   -189: real: -3.14
691   -194: space: \x0a
692   -197: real: -3.
693   -200: space: \x0a
694   -203: real: -.14
695   -207: space: \x0a
696   -210: integer: +16059
697   -216: space: \x0a
698   -219: integer: -16059
699   -225: space: \x0a
700   -228: word: +.
701   -230: space: \x0a
702   -233: bad: <fade\x0aET (invalid character (T) in hexstring)
703   -241: space: \x0a
704   -242: bad: ) (unexpected ))
705   -243: bad: > (unexpected >)
706   -244: word: quack
707   -249: space:
708   -250: name: /name\x00oops (raw: /name#oops) (name with stray # will not work with PDF >= 1.2)
709   -260: space:
710   -261: name: /name (raw: /n#61me)
711   -268: space:
712   -269: word: one
713   -272: space:
714   -273: bool: true
715   -277: space:
716   -278: word: two
717   -281: space:
718   -282: bool: false
719   -287: space:
720   -288: word: three
721   -293: space:
722   -294: null: null
723   -298: space:
724   -299: word: four
725   -303: space: \x0a
726   -304: word: !@#$^&
727   -310: brace_open: {
728   -311: brace_close: }
729   -312: word: *-_+=
730   -317: space: \x0a
731   -318: word: abc123def3.14true
732   -335: space: \x0a
733   -336: bad: <ff\x0a (EOF while reading token)
734   -340: eof
  672 +138: string: \x048!8Q\x04!Q\x04 (raw: (\48\418\121\4\41\121\4))
  673 +162: space: \x0a
  674 +165: string: \x048!8Q\x04!Q! (raw: (\48\418\121\4\41\121\41))
  675 +190: space: \x0a
  676 +193: integer: 72
  677 +195: space:
  678 +196: integer: 720
  679 +199: space:
  680 +200: word: Td
  681 +202: space: \x0a
  682 +205: real: 3.14
  683 +209: space: \x0a
  684 +212: real: 3.
  685 +214: space: \x0a
  686 +217: real: .14
  687 +220: space: \x0a
  688 +223: real: +3.14
  689 +228: space: \x0a
  690 +231: real: +3.
  691 +234: space: \x0a
  692 +237: real: +.14
  693 +241: space: \x0a
  694 +244: real: -3.14
  695 +249: space: \x0a
  696 +252: real: -3.
  697 +255: space: \x0a
  698 +258: real: -.14
  699 +262: space: \x0a
  700 +265: integer: +16059
  701 +271: space: \x0a
  702 +274: integer: -16059
  703 +280: space: \x0a
  704 +283: word: +.
  705 +285: space: \x0a
  706 +288: bad: <fade\x0aET (invalid character (T) in hexstring)
  707 +296: space: \x0a
  708 +297: bad: ) (unexpected ))
  709 +298: bad: > (unexpected >)
  710 +299: word: quack
  711 +304: space:
  712 +305: name: /name\x00oops (raw: /name#oops) (name with stray # will not work with PDF >= 1.2)
  713 +315: space:
  714 +316: name: /name (raw: /n#61me)
  715 +323: space:
  716 +324: word: one
  717 +327: space:
  718 +328: bool: true
  719 +332: space:
  720 +333: word: two
  721 +336: space:
  722 +337: bool: false
  723 +342: space:
  724 +343: word: three
  725 +348: space:
  726 +349: null: null
  727 +353: space:
  728 +354: word: four
  729 +358: space: \x0a
  730 +359: word: !@#$^&
  731 +365: brace_open: {
  732 +366: brace_close: }
  733 +367: word: *-_+=
  734 +372: space: \x0a
  735 +373: word: abc123def3.14true
  736 +390: space: \x0a
  737 +391: bad: <ff\x0a (EOF while reading token)
  738 +395: eof
735 739 --- END PAGE 4 ---
736 740 --- BEGIN PAGE 5 ---
737 741 0: word: BT
... ...
qpdf/qtest/qpdf/tokens-no-ignorable.out
... ... @@ -81,172 +81,172 @@ skipping to endstream
81 81 7119: dict_close: >>
82 82 7122: word: stream
83 83 skipping to endstream
84   -7469: word: endstream
85   -7479: word: endobj
86   -7487: integer: 44
87   -7490: integer: 0
88   -7492: word: obj
89   -7496: integer: 340
90   -7500: word: endobj
91   -7559: integer: 45
92   -7562: integer: 0
93   -7564: word: obj
94   -7568: dict_open: <<
95   -7573: name: /Length
96   -7581: integer: 46
97   -7584: integer: 0
98   -7586: word: R
99   -7588: dict_close: >>
100   -7591: word: stream
  84 +7524: word: endstream
  85 +7534: word: endobj
  86 +7542: integer: 44
  87 +7545: integer: 0
  88 +7547: word: obj
  89 +7551: integer: 395
  90 +7555: word: endobj
  91 +7614: integer: 45
  92 +7617: integer: 0
  93 +7619: word: obj
  94 +7623: dict_open: <<
  95 +7628: name: /Length
  96 +7636: integer: 46
  97 +7639: integer: 0
  98 +7641: word: R
  99 +7643: dict_close: >>
  100 +7646: word: stream
101 101 skipping to endstream
102   -7666: word: endstream
103   -7676: word: endobj
104   -7705: integer: 46
105   -7708: integer: 0
106   -7710: word: obj
107   -7714: integer: 67
108   -7717: word: endobj
109   -7776: integer: 47
110   -7779: integer: 0
111   -7781: word: obj
112   -7785: dict_open: <<
113   -7790: name: /Length
114   -7798: integer: 48
115   -7801: integer: 0
116   -7803: word: R
117   -7805: dict_close: >>
118   -7808: word: stream
  102 +7721: word: endstream
  103 +7731: word: endobj
  104 +7760: integer: 46
  105 +7763: integer: 0
  106 +7765: word: obj
  107 +7769: integer: 67
  108 +7772: word: endobj
  109 +7831: integer: 47
  110 +7834: integer: 0
  111 +7836: word: obj
  112 +7840: dict_open: <<
  113 +7845: name: /Length
  114 +7853: integer: 48
  115 +7856: integer: 0
  116 +7858: word: R
  117 +7860: dict_close: >>
  118 +7863: word: stream
119 119 skipping to endstream
120   -7859: word: endstream
121   -7869: word: endobj
122   -7877: integer: 48
123   -7880: integer: 0
124   -7882: word: obj
125   -7886: integer: 44
126   -7889: word: endobj
127   -7948: integer: 49
128   -7951: integer: 0
129   -7953: word: obj
130   -7957: dict_open: <<
131   -7962: name: /Length
132   -7970: integer: 50
133   -7973: integer: 0
134   -7975: word: R
135   -7977: dict_close: >>
136   -7980: word: stream
  120 +7914: word: endstream
  121 +7924: word: endobj
  122 +7932: integer: 48
  123 +7935: integer: 0
  124 +7937: word: obj
  125 +7941: integer: 44
  126 +7944: word: endobj
  127 +8003: integer: 49
  128 +8006: integer: 0
  129 +8008: word: obj
  130 +8012: dict_open: <<
  131 +8017: name: /Length
  132 +8025: integer: 50
  133 +8028: integer: 0
  134 +8030: word: R
  135 +8032: dict_close: >>
  136 +8035: word: stream
137 137 skipping to endstream
138   -8306: word: endstream
139   -8316: word: endobj
140   -8345: integer: 50
141   -8348: integer: 0
142   -8350: word: obj
143   -8354: integer: 318
144   -8358: word: endobj
145   -8417: integer: 51
146   -8420: integer: 0
147   -8422: word: obj
148   -8426: dict_open: <<
149   -8431: name: /Length
150   -8439: integer: 52
151   -8442: integer: 0
152   -8444: word: R
153   -8446: dict_close: >>
154   -8449: word: stream
  138 +8361: word: endstream
  139 +8371: word: endobj
  140 +8400: integer: 50
  141 +8403: integer: 0
  142 +8405: word: obj
  143 +8409: integer: 318
  144 +8413: word: endobj
  145 +8472: integer: 51
  146 +8475: integer: 0
  147 +8477: word: obj
  148 +8481: dict_open: <<
  149 +8486: name: /Length
  150 +8494: integer: 52
  151 +8497: integer: 0
  152 +8499: word: R
  153 +8501: dict_close: >>
  154 +8504: word: stream
155 155 skipping to endstream
156   -8500: word: endstream
157   -8510: word: endobj
158   -8518: integer: 52
159   -8521: integer: 0
160   -8523: word: obj
161   -8527: integer: 44
162   -8530: word: endobj
163   -8589: integer: 53
164   -8592: integer: 0
165   -8594: word: obj
166   -8598: dict_open: <<
167   -8603: name: /Length
168   -8611: integer: 54
169   -8614: integer: 0
170   -8616: word: R
171   -8618: dict_close: >>
172   -8621: word: stream
  156 +8555: word: endstream
  157 +8565: word: endobj
  158 +8573: integer: 52
  159 +8576: integer: 0
  160 +8578: word: obj
  161 +8582: integer: 44
  162 +8585: word: endobj
  163 +8644: integer: 53
  164 +8647: integer: 0
  165 +8649: word: obj
  166 +8653: dict_open: <<
  167 +8658: name: /Length
  168 +8666: integer: 54
  169 +8669: integer: 0
  170 +8671: word: R
  171 +8673: dict_close: >>
  172 +8676: word: stream
173 173 skipping to endstream
174   -8672: word: endstream
175   -8682: word: endobj
176   -8690: integer: 54
177   -8693: integer: 0
178   -8695: word: obj
179   -8699: integer: 44
180   -8702: word: endobj
181   -8762: integer: 55
182   -8765: integer: 0
183   -8767: word: obj
184   -8771: dict_open: <<
185   -8776: name: /Length
186   -8784: integer: 56
187   -8787: integer: 0
188   -8789: word: R
189   -8791: dict_close: >>
190   -8794: word: stream
  174 +8727: word: endstream
  175 +8737: word: endobj
  176 +8745: integer: 54
  177 +8748: integer: 0
  178 +8750: word: obj
  179 +8754: integer: 44
  180 +8757: word: endobj
  181 +8817: integer: 55
  182 +8820: integer: 0
  183 +8822: word: obj
  184 +8826: dict_open: <<
  185 +8831: name: /Length
  186 +8839: integer: 56
  187 +8842: integer: 0
  188 +8844: word: R
  189 +8846: dict_close: >>
  190 +8849: word: stream
191 191 skipping to endstream
192   -8845: word: endstream
193   -8855: word: endobj
194   -8863: integer: 56
195   -8866: integer: 0
196   -8868: word: obj
197   -8872: integer: 44
198   -8875: word: endobj
199   -8935: integer: 57
200   -8938: integer: 0
201   -8940: word: obj
202   -8944: dict_open: <<
203   -8949: name: /Length
204   -8957: integer: 58
205   -8960: integer: 0
206   -8962: word: R
207   -8964: dict_close: >>
208   -8967: word: stream
  192 +8900: word: endstream
  193 +8910: word: endobj
  194 +8918: integer: 56
  195 +8921: integer: 0
  196 +8923: word: obj
  197 +8927: integer: 44
  198 +8930: word: endobj
  199 +8990: integer: 57
  200 +8993: integer: 0
  201 +8995: word: obj
  202 +8999: dict_open: <<
  203 +9004: name: /Length
  204 +9012: integer: 58
  205 +9015: integer: 0
  206 +9017: word: R
  207 +9019: dict_close: >>
  208 +9022: word: stream
209 209 skipping to endstream
210   -9018: word: endstream
211   -9028: word: endobj
212   -9036: integer: 58
213   -9039: integer: 0
214   -9041: word: obj
215   -9045: integer: 44
216   -9048: word: endobj
217   -9056: integer: 59
218   -9059: integer: 0
219   -9061: word: obj
220   -9065: dict_open: <<
221   -9070: name: /Type
222   -9076: name: /XRef
223   -9084: name: /Length
224   -9092: integer: 240
225   -9098: name: /W
226   -9101: array_open: [
227   -9103: integer: 1
228   -9105: integer: 2
229   -9107: integer: 1
230   -9109: array_close: ]
231   -9113: name: /Root
232   -9119: integer: 2
233   -9121: integer: 0
234   -9123: word: R
235   -9127: name: /Size
236   -9133: integer: 60
237   -9138: name: /ID
238   -9142: array_open: [
239   -9143: string: \x88\x04\x8e\x17\xc9a\xe0\x94\xff\xec\xe9\x8c\xb8\x8cF\xd0 (raw: <88048e17c961e094ffece98cb88c46d0>)
240   -9177: string: \xed\xd6\x0f\xe8\xee\x87\xf8\x871\xa8o\x81\x9f\xe6Q\x99 (raw: <edd60fe8ee87f88731a86f819fe65199>)
241   -9211: array_close: ]
242   -9213: dict_close: >>
243   -9216: word: stream
  210 +9073: word: endstream
  211 +9083: word: endobj
  212 +9091: integer: 58
  213 +9094: integer: 0
  214 +9096: word: obj
  215 +9100: integer: 44
  216 +9103: word: endobj
  217 +9111: integer: 59
  218 +9114: integer: 0
  219 +9116: word: obj
  220 +9120: dict_open: <<
  221 +9125: name: /Type
  222 +9131: name: /XRef
  223 +9139: name: /Length
  224 +9147: integer: 240
  225 +9153: name: /W
  226 +9156: array_open: [
  227 +9158: integer: 1
  228 +9160: integer: 2
  229 +9162: integer: 1
  230 +9164: array_close: ]
  231 +9168: name: /Root
  232 +9174: integer: 2
  233 +9176: integer: 0
  234 +9178: word: R
  235 +9182: name: /Size
  236 +9188: integer: 60
  237 +9193: name: /ID
  238 +9197: array_open: [
  239 +9198: string: \x88\x04\x8e\x17\xc9a\xe0\x94\xff\xec\xe9\x8c\xb8\x8cF\xd0 (raw: <88048e17c961e094ffece98cb88c46d0>)
  240 +9232: string: \xed\xd6\x0f\xe8\xee\x87\xf8\x871\xa8o\x81\x9f\xe6Q\x99 (raw: <edd60fe8ee87f88731a86f819fe65199>)
  241 +9266: array_close: ]
  242 +9268: dict_close: >>
  243 +9271: word: stream
244 244 skipping to endstream
245   -9464: word: endstream
246   -9474: word: endobj
247   -9482: word: startxref
248   -9492: integer: 9056
249   -9503: eof
  245 +9519: word: endstream
  246 +9529: word: endobj
  247 +9537: word: startxref
  248 +9547: integer: 9111
  249 +9558: eof
250 250 --- END FILE ---
251 251 --- BEGIN PAGE 1 ---
252 252 0: word: BT
... ... @@ -330,41 +330,43 @@ skipping to endstream
330 330 87: string: qu\x0aack (raw: (qu\\x0d\x0dack))
331 331 100: string: qu\x0a\x0a\x0a\x0a\x0a\x0aack (raw: (qu\\x0a\x0a\x0d\x0a\x0a\x0d\x0d\x0a\x0aack))
332 332 120: string: qu\x0a\x0a\x0a\x0a\x0a\x0aack (raw: (qu\x0a\x0d\x0a\x0a\x0d\x0d\x0a\x0aack))
333   -138: integer: 72
334   -141: integer: 720
335   -145: word: Td
336   -150: real: 3.14
337   -157: real: 3.
338   -162: real: .14
339   -168: real: +3.14
340   -176: real: +3.
341   -182: real: +.14
342   -189: real: -3.14
343   -197: real: -3.
344   -203: real: -.14
345   -210: integer: +16059
346   -219: integer: -16059
347   -228: word: +.
348   -233: bad: <fade\x0aET (invalid character (T) in hexstring)
349   -242: bad: ) (unexpected ))
350   -243: bad: > (unexpected >)
351   -244: word: quack
352   -250: name: /name\x00oops (raw: /name#oops) (name with stray # will not work with PDF >= 1.2)
353   -261: name: /name (raw: /n#61me)
354   -269: word: one
355   -273: bool: true
356   -278: word: two
357   -282: bool: false
358   -288: word: three
359   -294: null: null
360   -299: word: four
361   -304: word: !@#$^&
362   -310: brace_open: {
363   -311: brace_close: }
364   -312: word: *-_+=
365   -318: word: abc123def3.14true
366   -336: bad: <ff\x0a (EOF while reading token)
367   -340: eof
  333 +138: string: \x048!8Q\x04!Q\x04 (raw: (\48\418\121\4\41\121\4))
  334 +165: string: \x048!8Q\x04!Q! (raw: (\48\418\121\4\41\121\41))
  335 +193: integer: 72
  336 +196: integer: 720
  337 +200: word: Td
  338 +205: real: 3.14
  339 +212: real: 3.
  340 +217: real: .14
  341 +223: real: +3.14
  342 +231: real: +3.
  343 +237: real: +.14
  344 +244: real: -3.14
  345 +252: real: -3.
  346 +258: real: -.14
  347 +265: integer: +16059
  348 +274: integer: -16059
  349 +283: word: +.
  350 +288: bad: <fade\x0aET (invalid character (T) in hexstring)
  351 +297: bad: ) (unexpected ))
  352 +298: bad: > (unexpected >)
  353 +299: word: quack
  354 +305: name: /name\x00oops (raw: /name#oops) (name with stray # will not work with PDF >= 1.2)
  355 +316: name: /name (raw: /n#61me)
  356 +324: word: one
  357 +328: bool: true
  358 +333: word: two
  359 +337: bool: false
  360 +343: word: three
  361 +349: null: null
  362 +354: word: four
  363 +359: word: !@#$^&
  364 +365: brace_open: {
  365 +366: brace_close: }
  366 +367: word: *-_+=
  367 +373: word: abc123def3.14true
  368 +391: bad: <ff\x0a (EOF while reading token)
  369 +395: eof
368 370 --- END PAGE 4 ---
369 371 --- BEGIN PAGE 5 ---
370 372 0: word: BT
... ...
qpdf/qtest/qpdf/tokens.out
... ... @@ -181,352 +181,352 @@ skipping to endstream
181 181 7121: space: \x0a
182 182 7122: word: stream
183 183 skipping to endstream
184   -7469: word: endstream
185   -7478: space: \x0a
186   -7479: word: endobj
187   -7485: space: \x0a\x0a
188   -7487: integer: 44
189   -7489: space:
190   -7490: integer: 0
191   -7491: space:
192   -7492: word: obj
193   -7495: space: \x0a
194   -7496: integer: 340
195   -7499: space: \x0a
196   -7500: word: endobj
197   -7506: space: \x0a\x0a
198   -7508: comment: %% Contents for page 5
199   -7530: space: \x0a
200   -7531: comment: %% Original object ID: 41 0
201   -7558: space: \x0a
202   -7559: integer: 45
203   -7561: space:
204   -7562: integer: 0
205   -7563: space:
206   -7564: word: obj
207   -7567: space: \x0a
208   -7568: dict_open: <<
209   -7570: space: \x0a
210   -7573: name: /Length
211   -7580: space:
212   -7581: integer: 46
213   -7583: space:
214   -7584: integer: 0
215   -7585: space:
216   -7586: word: R
217   -7587: space: \x0a
218   -7588: dict_close: >>
219   -7590: space: \x0a
220   -7591: word: stream
  184 +7524: word: endstream
  185 +7533: space: \x0a
  186 +7534: word: endobj
  187 +7540: space: \x0a\x0a
  188 +7542: integer: 44
  189 +7544: space:
  190 +7545: integer: 0
  191 +7546: space:
  192 +7547: word: obj
  193 +7550: space: \x0a
  194 +7551: integer: 395
  195 +7554: space: \x0a
  196 +7555: word: endobj
  197 +7561: space: \x0a\x0a
  198 +7563: comment: %% Contents for page 5
  199 +7585: space: \x0a
  200 +7586: comment: %% Original object ID: 41 0
  201 +7613: space: \x0a
  202 +7614: integer: 45
  203 +7616: space:
  204 +7617: integer: 0
  205 +7618: space:
  206 +7619: word: obj
  207 +7622: space: \x0a
  208 +7623: dict_open: <<
  209 +7625: space: \x0a
  210 +7628: name: /Length
  211 +7635: space:
  212 +7636: integer: 46
  213 +7638: space:
  214 +7639: integer: 0
  215 +7640: space:
  216 +7641: word: R
  217 +7642: space: \x0a
  218 +7643: dict_close: >>
  219 +7645: space: \x0a
  220 +7646: word: stream
221 221 skipping to endstream
222   -7666: word: endstream
223   -7675: space: \x0a
224   -7676: word: endobj
225   -7682: space: \x0a
226   -7683: comment: %QDF: ignore_newline
227   -7703: space: \x0a\x0a
228   -7705: integer: 46
229   -7707: space:
230   -7708: integer: 0
231   -7709: space:
232   -7710: word: obj
233   -7713: space: \x0a
234   -7714: integer: 67
235   -7716: space: \x0a
236   -7717: word: endobj
237   -7723: space: \x0a\x0a
238   -7725: comment: %% Contents for page 6
239   -7747: space: \x0a
240   -7748: comment: %% Original object ID: 42 0
241   -7775: space: \x0a
242   -7776: integer: 47
243   -7778: space:
244   -7779: integer: 0
245   -7780: space:
246   -7781: word: obj
247   -7784: space: \x0a
248   -7785: dict_open: <<
249   -7787: space: \x0a
250   -7790: name: /Length
251   -7797: space:
252   -7798: integer: 48
253   -7800: space:
254   -7801: integer: 0
255   -7802: space:
256   -7803: word: R
257   -7804: space: \x0a
258   -7805: dict_close: >>
259   -7807: space: \x0a
260   -7808: word: stream
  222 +7721: word: endstream
  223 +7730: space: \x0a
  224 +7731: word: endobj
  225 +7737: space: \x0a
  226 +7738: comment: %QDF: ignore_newline
  227 +7758: space: \x0a\x0a
  228 +7760: integer: 46
  229 +7762: space:
  230 +7763: integer: 0
  231 +7764: space:
  232 +7765: word: obj
  233 +7768: space: \x0a
  234 +7769: integer: 67
  235 +7771: space: \x0a
  236 +7772: word: endobj
  237 +7778: space: \x0a\x0a
  238 +7780: comment: %% Contents for page 6
  239 +7802: space: \x0a
  240 +7803: comment: %% Original object ID: 42 0
  241 +7830: space: \x0a
  242 +7831: integer: 47
  243 +7833: space:
  244 +7834: integer: 0
  245 +7835: space:
  246 +7836: word: obj
  247 +7839: space: \x0a
  248 +7840: dict_open: <<
  249 +7842: space: \x0a
  250 +7845: name: /Length
  251 +7852: space:
  252 +7853: integer: 48
  253 +7855: space:
  254 +7856: integer: 0
  255 +7857: space:
  256 +7858: word: R
  257 +7859: space: \x0a
  258 +7860: dict_close: >>
  259 +7862: space: \x0a
  260 +7863: word: stream
261 261 skipping to endstream
262   -7859: word: endstream
263   -7868: space: \x0a
264   -7869: word: endobj
265   -7875: space: \x0a\x0a
266   -7877: integer: 48
267   -7879: space:
268   -7880: integer: 0
269   -7881: space:
270   -7882: word: obj
271   -7885: space: \x0a
272   -7886: integer: 44
273   -7888: space: \x0a
274   -7889: word: endobj
275   -7895: space: \x0a\x0a
276   -7897: comment: %% Contents for page 7
277   -7919: space: \x0a
278   -7920: comment: %% Original object ID: 43 0
279   -7947: space: \x0a
280   -7948: integer: 49
281   -7950: space:
282   -7951: integer: 0
283   -7952: space:
284   -7953: word: obj
285   -7956: space: \x0a
286   -7957: dict_open: <<
287   -7959: space: \x0a
288   -7962: name: /Length
289   -7969: space:
290   -7970: integer: 50
291   -7972: space:
292   -7973: integer: 0
293   -7974: space:
294   -7975: word: R
295   -7976: space: \x0a
296   -7977: dict_close: >>
297   -7979: space: \x0a
298   -7980: word: stream
  262 +7914: word: endstream
  263 +7923: space: \x0a
  264 +7924: word: endobj
  265 +7930: space: \x0a\x0a
  266 +7932: integer: 48
  267 +7934: space:
  268 +7935: integer: 0
  269 +7936: space:
  270 +7937: word: obj
  271 +7940: space: \x0a
  272 +7941: integer: 44
  273 +7943: space: \x0a
  274 +7944: word: endobj
  275 +7950: space: \x0a\x0a
  276 +7952: comment: %% Contents for page 7
  277 +7974: space: \x0a
  278 +7975: comment: %% Original object ID: 43 0
  279 +8002: space: \x0a
  280 +8003: integer: 49
  281 +8005: space:
  282 +8006: integer: 0
  283 +8007: space:
  284 +8008: word: obj
  285 +8011: space: \x0a
  286 +8012: dict_open: <<
  287 +8014: space: \x0a
  288 +8017: name: /Length
  289 +8024: space:
  290 +8025: integer: 50
  291 +8027: space:
  292 +8028: integer: 0
  293 +8029: space:
  294 +8030: word: R
  295 +8031: space: \x0a
  296 +8032: dict_close: >>
  297 +8034: space: \x0a
  298 +8035: word: stream
299 299 skipping to endstream
300   -8306: word: endstream
301   -8315: space: \x0a
302   -8316: word: endobj
303   -8322: space: \x0a
304   -8323: comment: %QDF: ignore_newline
305   -8343: space: \x0a\x0a
306   -8345: integer: 50
307   -8347: space:
308   -8348: integer: 0
309   -8349: space:
310   -8350: word: obj
311   -8353: space: \x0a
312   -8354: integer: 318
313   -8357: space: \x0a
314   -8358: word: endobj
315   -8364: space: \x0a\x0a
316   -8366: comment: %% Contents for page 8
317   -8388: space: \x0a
318   -8389: comment: %% Original object ID: 44 0
319   -8416: space: \x0a
320   -8417: integer: 51
321   -8419: space:
322   -8420: integer: 0
323   -8421: space:
324   -8422: word: obj
325   -8425: space: \x0a
326   -8426: dict_open: <<
327   -8428: space: \x0a
328   -8431: name: /Length
329   -8438: space:
330   -8439: integer: 52
331   -8441: space:
332   -8442: integer: 0
333   -8443: space:
334   -8444: word: R
335   -8445: space: \x0a
336   -8446: dict_close: >>
337   -8448: space: \x0a
338   -8449: word: stream
  300 +8361: word: endstream
  301 +8370: space: \x0a
  302 +8371: word: endobj
  303 +8377: space: \x0a
  304 +8378: comment: %QDF: ignore_newline
  305 +8398: space: \x0a\x0a
  306 +8400: integer: 50
  307 +8402: space:
  308 +8403: integer: 0
  309 +8404: space:
  310 +8405: word: obj
  311 +8408: space: \x0a
  312 +8409: integer: 318
  313 +8412: space: \x0a
  314 +8413: word: endobj
  315 +8419: space: \x0a\x0a
  316 +8421: comment: %% Contents for page 8
  317 +8443: space: \x0a
  318 +8444: comment: %% Original object ID: 44 0
  319 +8471: space: \x0a
  320 +8472: integer: 51
  321 +8474: space:
  322 +8475: integer: 0
  323 +8476: space:
  324 +8477: word: obj
  325 +8480: space: \x0a
  326 +8481: dict_open: <<
  327 +8483: space: \x0a
  328 +8486: name: /Length
  329 +8493: space:
  330 +8494: integer: 52
  331 +8496: space:
  332 +8497: integer: 0
  333 +8498: space:
  334 +8499: word: R
  335 +8500: space: \x0a
  336 +8501: dict_close: >>
  337 +8503: space: \x0a
  338 +8504: word: stream
339 339 skipping to endstream
340   -8500: word: endstream
341   -8509: space: \x0a
342   -8510: word: endobj
343   -8516: space: \x0a\x0a
344   -8518: integer: 52
345   -8520: space:
346   -8521: integer: 0
347   -8522: space:
348   -8523: word: obj
349   -8526: space: \x0a
350   -8527: integer: 44
351   -8529: space: \x0a
352   -8530: word: endobj
353   -8536: space: \x0a\x0a
354   -8538: comment: %% Contents for page 9
355   -8560: space: \x0a
356   -8561: comment: %% Original object ID: 45 0
357   -8588: space: \x0a
358   -8589: integer: 53
359   -8591: space:
360   -8592: integer: 0
361   -8593: space:
362   -8594: word: obj
363   -8597: space: \x0a
364   -8598: dict_open: <<
365   -8600: space: \x0a
366   -8603: name: /Length
367   -8610: space:
368   -8611: integer: 54
369   -8613: space:
370   -8614: integer: 0
371   -8615: space:
372   -8616: word: R
373   -8617: space: \x0a
374   -8618: dict_close: >>
375   -8620: space: \x0a
376   -8621: word: stream
  340 +8555: word: endstream
  341 +8564: space: \x0a
  342 +8565: word: endobj
  343 +8571: space: \x0a\x0a
  344 +8573: integer: 52
  345 +8575: space:
  346 +8576: integer: 0
  347 +8577: space:
  348 +8578: word: obj
  349 +8581: space: \x0a
  350 +8582: integer: 44
  351 +8584: space: \x0a
  352 +8585: word: endobj
  353 +8591: space: \x0a\x0a
  354 +8593: comment: %% Contents for page 9
  355 +8615: space: \x0a
  356 +8616: comment: %% Original object ID: 45 0
  357 +8643: space: \x0a
  358 +8644: integer: 53
  359 +8646: space:
  360 +8647: integer: 0
  361 +8648: space:
  362 +8649: word: obj
  363 +8652: space: \x0a
  364 +8653: dict_open: <<
  365 +8655: space: \x0a
  366 +8658: name: /Length
  367 +8665: space:
  368 +8666: integer: 54
  369 +8668: space:
  370 +8669: integer: 0
  371 +8670: space:
  372 +8671: word: R
  373 +8672: space: \x0a
  374 +8673: dict_close: >>
  375 +8675: space: \x0a
  376 +8676: word: stream
377 377 skipping to endstream
378   -8672: word: endstream
379   -8681: space: \x0a
380   -8682: word: endobj
381   -8688: space: \x0a\x0a
382   -8690: integer: 54
383   -8692: space:
384   -8693: integer: 0
385   -8694: space:
386   -8695: word: obj
387   -8698: space: \x0a
388   -8699: integer: 44
389   -8701: space: \x0a
390   -8702: word: endobj
391   -8708: space: \x0a\x0a
392   -8710: comment: %% Contents for page 10
393   -8733: space: \x0a
394   -8734: comment: %% Original object ID: 46 0
395   -8761: space: \x0a
396   -8762: integer: 55
397   -8764: space:
398   -8765: integer: 0
399   -8766: space:
400   -8767: word: obj
401   -8770: space: \x0a
402   -8771: dict_open: <<
403   -8773: space: \x0a
404   -8776: name: /Length
405   -8783: space:
406   -8784: integer: 56
407   -8786: space:
408   -8787: integer: 0
409   -8788: space:
410   -8789: word: R
411   -8790: space: \x0a
412   -8791: dict_close: >>
413   -8793: space: \x0a
414   -8794: word: stream
  378 +8727: word: endstream
  379 +8736: space: \x0a
  380 +8737: word: endobj
  381 +8743: space: \x0a\x0a
  382 +8745: integer: 54
  383 +8747: space:
  384 +8748: integer: 0
  385 +8749: space:
  386 +8750: word: obj
  387 +8753: space: \x0a
  388 +8754: integer: 44
  389 +8756: space: \x0a
  390 +8757: word: endobj
  391 +8763: space: \x0a\x0a
  392 +8765: comment: %% Contents for page 10
  393 +8788: space: \x0a
  394 +8789: comment: %% Original object ID: 46 0
  395 +8816: space: \x0a
  396 +8817: integer: 55
  397 +8819: space:
  398 +8820: integer: 0
  399 +8821: space:
  400 +8822: word: obj
  401 +8825: space: \x0a
  402 +8826: dict_open: <<
  403 +8828: space: \x0a
  404 +8831: name: /Length
  405 +8838: space:
  406 +8839: integer: 56
  407 +8841: space:
  408 +8842: integer: 0
  409 +8843: space:
  410 +8844: word: R
  411 +8845: space: \x0a
  412 +8846: dict_close: >>
  413 +8848: space: \x0a
  414 +8849: word: stream
415 415 skipping to endstream
416   -8845: word: endstream
417   -8854: space: \x0a
418   -8855: word: endobj
419   -8861: space: \x0a\x0a
420   -8863: integer: 56
421   -8865: space:
422   -8866: integer: 0
423   -8867: space:
424   -8868: word: obj
425   -8871: space: \x0a
426   -8872: integer: 44
427   -8874: space: \x0a
428   -8875: word: endobj
429   -8881: space: \x0a\x0a
430   -8883: comment: %% Contents for page 11
431   -8906: space: \x0a
432   -8907: comment: %% Original object ID: 47 0
433   -8934: space: \x0a
434   -8935: integer: 57
435   -8937: space:
436   -8938: integer: 0
437   -8939: space:
438   -8940: word: obj
439   -8943: space: \x0a
440   -8944: dict_open: <<
441   -8946: space: \x0a
442   -8949: name: /Length
443   -8956: space:
444   -8957: integer: 58
445   -8959: space:
446   -8960: integer: 0
447   -8961: space:
448   -8962: word: R
449   -8963: space: \x0a
450   -8964: dict_close: >>
451   -8966: space: \x0a
452   -8967: word: stream
  416 +8900: word: endstream
  417 +8909: space: \x0a
  418 +8910: word: endobj
  419 +8916: space: \x0a\x0a
  420 +8918: integer: 56
  421 +8920: space:
  422 +8921: integer: 0
  423 +8922: space:
  424 +8923: word: obj
  425 +8926: space: \x0a
  426 +8927: integer: 44
  427 +8929: space: \x0a
  428 +8930: word: endobj
  429 +8936: space: \x0a\x0a
  430 +8938: comment: %% Contents for page 11
  431 +8961: space: \x0a
  432 +8962: comment: %% Original object ID: 47 0
  433 +8989: space: \x0a
  434 +8990: integer: 57
  435 +8992: space:
  436 +8993: integer: 0
  437 +8994: space:
  438 +8995: word: obj
  439 +8998: space: \x0a
  440 +8999: dict_open: <<
  441 +9001: space: \x0a
  442 +9004: name: /Length
  443 +9011: space:
  444 +9012: integer: 58
  445 +9014: space:
  446 +9015: integer: 0
  447 +9016: space:
  448 +9017: word: R
  449 +9018: space: \x0a
  450 +9019: dict_close: >>
  451 +9021: space: \x0a
  452 +9022: word: stream
453 453 skipping to endstream
454   -9018: word: endstream
455   -9027: space: \x0a
456   -9028: word: endobj
457   -9034: space: \x0a\x0a
458   -9036: integer: 58
459   -9038: space:
460   -9039: integer: 0
461   -9040: space:
462   -9041: word: obj
463   -9044: space: \x0a
464   -9045: integer: 44
465   -9047: space: \x0a
466   -9048: word: endobj
467   -9054: space: \x0a\x0a
468   -9056: integer: 59
469   -9058: space:
470   -9059: integer: 0
471   -9060: space:
472   -9061: word: obj
473   -9064: space: \x0a
474   -9065: dict_open: <<
475   -9067: space: \x0a
476   -9070: name: /Type
477   -9075: space:
478   -9076: name: /XRef
479   -9081: space: \x0a
480   -9084: name: /Length
481   -9091: space:
482   -9092: integer: 240
483   -9095: space: \x0a
484   -9098: name: /W
485   -9100: space:
486   -9101: array_open: [
487   -9102: space:
488   -9103: integer: 1
489   -9104: space:
490   -9105: integer: 2
491   -9106: space:
492   -9107: integer: 1
493   -9108: space:
494   -9109: array_close: ]
495   -9110: space: \x0a
496   -9113: name: /Root
497   -9118: space:
498   -9119: integer: 2
499   -9120: space:
500   -9121: integer: 0
501   -9122: space:
502   -9123: word: R
503   -9124: space: \x0a
504   -9127: name: /Size
505   -9132: space:
506   -9133: integer: 60
507   -9135: space: \x0a
508   -9138: name: /ID
509   -9141: space:
510   -9142: array_open: [
511   -9143: string: \x88\x04\x8e\x17\xc9a\xe0\x94\xff\xec\xe9\x8c\xb8\x8cF\xd0 (raw: <88048e17c961e094ffece98cb88c46d0>)
512   -9177: string: \xed\xd6\x0f\xe8\xee\x87\xf8\x871\xa8o\x81\x9f\xe6Q\x99 (raw: <edd60fe8ee87f88731a86f819fe65199>)
513   -9211: array_close: ]
514   -9212: space: \x0a
515   -9213: dict_close: >>
516   -9215: space: \x0a
517   -9216: word: stream
  454 +9073: word: endstream
  455 +9082: space: \x0a
  456 +9083: word: endobj
  457 +9089: space: \x0a\x0a
  458 +9091: integer: 58
  459 +9093: space:
  460 +9094: integer: 0
  461 +9095: space:
  462 +9096: word: obj
  463 +9099: space: \x0a
  464 +9100: integer: 44
  465 +9102: space: \x0a
  466 +9103: word: endobj
  467 +9109: space: \x0a\x0a
  468 +9111: integer: 59
  469 +9113: space:
  470 +9114: integer: 0
  471 +9115: space:
  472 +9116: word: obj
  473 +9119: space: \x0a
  474 +9120: dict_open: <<
  475 +9122: space: \x0a
  476 +9125: name: /Type
  477 +9130: space:
  478 +9131: name: /XRef
  479 +9136: space: \x0a
  480 +9139: name: /Length
  481 +9146: space:
  482 +9147: integer: 240
  483 +9150: space: \x0a
  484 +9153: name: /W
  485 +9155: space:
  486 +9156: array_open: [
  487 +9157: space:
  488 +9158: integer: 1
  489 +9159: space:
  490 +9160: integer: 2
  491 +9161: space:
  492 +9162: integer: 1
  493 +9163: space:
  494 +9164: array_close: ]
  495 +9165: space: \x0a
  496 +9168: name: /Root
  497 +9173: space:
  498 +9174: integer: 2
  499 +9175: space:
  500 +9176: integer: 0
  501 +9177: space:
  502 +9178: word: R
  503 +9179: space: \x0a
  504 +9182: name: /Size
  505 +9187: space:
  506 +9188: integer: 60
  507 +9190: space: \x0a
  508 +9193: name: /ID
  509 +9196: space:
  510 +9197: array_open: [
  511 +9198: string: \x88\x04\x8e\x17\xc9a\xe0\x94\xff\xec\xe9\x8c\xb8\x8cF\xd0 (raw: <88048e17c961e094ffece98cb88c46d0>)
  512 +9232: string: \xed\xd6\x0f\xe8\xee\x87\xf8\x871\xa8o\x81\x9f\xe6Q\x99 (raw: <edd60fe8ee87f88731a86f819fe65199>)
  513 +9266: array_close: ]
  514 +9267: space: \x0a
  515 +9268: dict_close: >>
  516 +9270: space: \x0a
  517 +9271: word: stream
518 518 skipping to endstream
519   -9464: word: endstream
520   -9473: space: \x0a
521   -9474: word: endobj
522   -9480: space: \x0a\x0a
523   -9482: word: startxref
524   -9491: space: \x0a
525   -9492: integer: 9056
526   -9496: space: \x0a
527   -9497: comment: %%EOF
528   -9502: space: \x0a
529   -9503: eof
  519 +9519: word: endstream
  520 +9528: space: \x0a
  521 +9529: word: endobj
  522 +9535: space: \x0a\x0a
  523 +9537: word: startxref
  524 +9546: space: \x0a
  525 +9547: integer: 9111
  526 +9551: space: \x0a
  527 +9552: comment: %%EOF
  528 +9557: space: \x0a
  529 +9558: eof
530 530 --- END FILE ---
531 531 --- BEGIN PAGE 1 ---
532 532 0: word: BT
... ... @@ -669,69 +669,73 @@ skipping to endstream
669 669 117: space: \x0a
670 670 120: string: qu\x0a\x0a\x0a\x0a\x0a\x0aack (raw: (qu\x0a\x0d\x0a\x0a\x0d\x0d\x0a\x0aack))
671 671 135: space: \x0a
672   -138: integer: 72
673   -140: space:
674   -141: integer: 720
675   -144: space:
676   -145: word: Td
677   -147: space: \x0a
678   -150: real: 3.14
679   -154: space: \x0a
680   -157: real: 3.
681   -159: space: \x0a
682   -162: real: .14
683   -165: space: \x0a
684   -168: real: +3.14
685   -173: space: \x0a
686   -176: real: +3.
687   -179: space: \x0a
688   -182: real: +.14
689   -186: space: \x0a
690   -189: real: -3.14
691   -194: space: \x0a
692   -197: real: -3.
693   -200: space: \x0a
694   -203: real: -.14
695   -207: space: \x0a
696   -210: integer: +16059
697   -216: space: \x0a
698   -219: integer: -16059
699   -225: space: \x0a
700   -228: word: +.
701   -230: space: \x0a
702   -233: bad: <fade\x0aET (invalid character (T) in hexstring)
703   -241: space: \x0a
704   -242: bad: ) (unexpected ))
705   -243: bad: > (unexpected >)
706   -244: word: quack
707   -249: space:
708   -250: name: /name\x00oops (raw: /name#oops) (name with stray # will not work with PDF >= 1.2)
709   -260: space:
710   -261: name: /name (raw: /n#61me)
711   -268: space:
712   -269: word: one
713   -272: space:
714   -273: bool: true
715   -277: space:
716   -278: word: two
717   -281: space:
718   -282: bool: false
719   -287: space:
720   -288: word: three
721   -293: space:
722   -294: null: null
723   -298: space:
724   -299: word: four
725   -303: space: \x0a
726   -304: word: !@#$^&
727   -310: brace_open: {
728   -311: brace_close: }
729   -312: word: *-_+=
730   -317: space: \x0a
731   -318: word: abc123def3.14true
732   -335: space: \x0a
733   -336: bad: <ff\x0a (EOF while reading token)
734   -340: eof
  672 +138: string: \x048!8Q\x04!Q\x04 (raw: (\48\418\121\4\41\121\4))
  673 +162: space: \x0a
  674 +165: string: \x048!8Q\x04!Q! (raw: (\48\418\121\4\41\121\41))
  675 +190: space: \x0a
  676 +193: integer: 72
  677 +195: space:
  678 +196: integer: 720
  679 +199: space:
  680 +200: word: Td
  681 +202: space: \x0a
  682 +205: real: 3.14
  683 +209: space: \x0a
  684 +212: real: 3.
  685 +214: space: \x0a
  686 +217: real: .14
  687 +220: space: \x0a
  688 +223: real: +3.14
  689 +228: space: \x0a
  690 +231: real: +3.
  691 +234: space: \x0a
  692 +237: real: +.14
  693 +241: space: \x0a
  694 +244: real: -3.14
  695 +249: space: \x0a
  696 +252: real: -3.
  697 +255: space: \x0a
  698 +258: real: -.14
  699 +262: space: \x0a
  700 +265: integer: +16059
  701 +271: space: \x0a
  702 +274: integer: -16059
  703 +280: space: \x0a
  704 +283: word: +.
  705 +285: space: \x0a
  706 +288: bad: <fade\x0aET (invalid character (T) in hexstring)
  707 +296: space: \x0a
  708 +297: bad: ) (unexpected ))
  709 +298: bad: > (unexpected >)
  710 +299: word: quack
  711 +304: space:
  712 +305: name: /name\x00oops (raw: /name#oops) (name with stray # will not work with PDF >= 1.2)
  713 +315: space:
  714 +316: name: /name (raw: /n#61me)
  715 +323: space:
  716 +324: word: one
  717 +327: space:
  718 +328: bool: true
  719 +332: space:
  720 +333: word: two
  721 +336: space:
  722 +337: bool: false
  723 +342: space:
  724 +343: word: three
  725 +348: space:
  726 +349: null: null
  727 +353: space:
  728 +354: word: four
  729 +358: space: \x0a
  730 +359: word: !@#$^&
  731 +365: brace_open: {
  732 +366: brace_close: }
  733 +367: word: *-_+=
  734 +372: space: \x0a
  735 +373: word: abc123def3.14true
  736 +390: space: \x0a
  737 +391: bad: <ff\x0a (EOF while reading token)
  738 +395: eof
735 739 --- END PAGE 4 ---
736 740 --- BEGIN PAGE 5 ---
737 741 0: word: BT
... ...
qpdf/qtest/qpdf/tokens.pdf
No preview for this file type
qpdf/qtest/tokenizer.test
... ... @@ -14,7 +14,7 @@ cleanup();
14 14  
15 15 my $td = new TestDriver('tokenizer');
16 16  
17   -my $n_tests = 4;
  17 +my $n_tests = 5;
18 18  
19 19 $td->runtest("tokenizer with no ignorable",
20 20 {$td->COMMAND => "test_tokenizer -no-ignorable tokens.pdf"},
... ... @@ -38,5 +38,11 @@ $td-&gt;runtest(&quot;ignore bad token&quot;,
38 38 $td->EXIT_STATUS => 0},
39 39 $td->NORMALIZE_NEWLINES);
40 40  
  41 +$td->runtest("quoted char edge cases",
  42 + {$td->COMMAND => "test_driver 96 -"},
  43 + {$td->STRING => "test 96 done\n",
  44 + $td->EXIT_STATUS => 0},
  45 + $td->NORMALIZE_NEWLINES);
  46 +
41 47 cleanup();
42 48 $td->report($n_tests);
... ...
qpdf/test_driver.cc
... ... @@ -3341,6 +3341,17 @@ test_95(QPDF&amp; pdf, char const* arg2)
3341 3341 assert(!oh_d.isScalar());
3342 3342 }
3343 3343  
  3344 +static void
  3345 +test_96(QPDF& pdf, char const* arg2)
  3346 +{
  3347 + // Test edge cases with quoted characters
  3348 +
  3349 + auto s = R"((\48\418\121\4))"_qpdf;
  3350 + assert(s.unparseBinary() == "<043821385104>");
  3351 + s = R"((\48\418\121\41))"_qpdf;
  3352 + assert(s.unparseBinary() == "<043821385121>");
  3353 +}
  3354 +
3344 3355 void
3345 3356 runtest(int n, char const* filename1, char const* arg2)
3346 3357 {
... ... @@ -3348,7 +3359,7 @@ runtest(int n, char const* filename1, char const* arg2)
3348 3359 // the test suite to see how the test is invoked to find the file
3349 3360 // that the test is supposed to operate on.
3350 3361  
3351   - std::set<int> ignore_filename = {61, 81, 83, 84, 85, 86, 87, 92, 95};
  3362 + std::set<int> ignore_filename = {61, 81, 83, 84, 85, 86, 87, 92, 95, 96};
3352 3363  
3353 3364 if (n == 0) {
3354 3365 // Throw in some random test cases that don't fit anywhere
... ... @@ -3441,7 +3452,8 @@ runtest(int n, char const* filename1, char const* arg2)
3441 3452 {72, test_72}, {73, test_73}, {74, test_74}, {75, test_75}, {76, test_76}, {77, test_77},
3442 3453 {78, test_78}, {79, test_79}, {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83},
3443 3454 {84, test_84}, {85, test_85}, {86, test_86}, {87, test_87}, {88, test_88}, {89, test_89},
3444   - {90, test_90}, {91, test_91}, {92, test_92}, {93, test_93}, {94, test_94}, {95, test_95}};
  3455 + {90, test_90}, {91, test_91}, {92, test_92}, {93, test_93}, {94, test_94}, {95, test_95},
  3456 + {96, test_96}};
3445 3457  
3446 3458 auto fn = test_functions.find(n);
3447 3459 if (fn == test_functions.end()) {
... ...