Commit 398354b6f0c5e8311496481c2b80c1eb4bec4424

Authored by Jay Berkenbilt
1 parent 3f8c4c27

update C API for error retrieval

git-svn-id: svn+q:///qpdf/trunk@830 71b93d88-0707-0410-a8cf-f5a4172ac649
ChangeLog
1 1 2009-10-19 Jay Berkenbilt <jberkenb@argonst.com>
2 2  
  3 + * include/qpdf/QPDF.hh (QPDF): getWarnings now returns a list of
  4 + QPDFExc rather than a list of strings. This way, warnings may be
  5 + inspected in more detail.
  6 +
3 7 * Include information about the last object read in most error
4 8 messages. Most of the time, this will provide a good hint as to
5 9 which object contains the error, but it's possible that the last
... ...
examples/pdf-linearize.c
... ... @@ -24,6 +24,7 @@ int main(int argc, char* argv[])
24 24 int warnings = 0;
25 25 int errors = 0;
26 26 char* p = 0;
  27 + qpdf_error e = 0;
27 28  
28 29 if ((p = strrchr(argv[0], '/')) != NULL)
29 30 {
... ... @@ -53,12 +54,14 @@ int main(int argc, char* argv[])
53 54 while (qpdf_more_warnings(qpdf))
54 55 {
55 56 warnings = 1;
56   - printf("warning: %s\n", qpdf_next_warning(qpdf));
  57 + printf("warning: %s\n",
  58 + qpdf_get_error_full_text(qpdf, qpdf_next_warning(qpdf)));
57 59 }
58   - while (qpdf_more_errors(qpdf))
  60 + e = qpdf_get_error(qpdf);
  61 + if (e)
59 62 {
60 63 errors = 1;
61   - printf("error: %s\n", qpdf_next_error(qpdf));
  64 + printf("error: %s\n", qpdf_get_error_full_text(qpdf, e));
62 65 }
63 66 qpdf_cleanup(&qpdf);
64 67 if (errors)
... ...
include/qpdf/QPDF.hh
... ... @@ -70,7 +70,7 @@ class DLL_EXPORT QPDF
70 70 // throws an exception. Note that if setSuppressWarnings was not
71 71 // called or was called with a false value, any warnings retrieved
72 72 // here will have already been issued to stderr.
73   - std::vector<std::string> getWarnings();
  73 + std::vector<QPDFExc> getWarnings();
74 74  
75 75 std::string getFilename() const;
76 76 std::string getPDFVersion() const;
... ... @@ -761,7 +761,7 @@ class DLL_EXPORT QPDF
761 761 std::map<ObjGen, ObjCache> obj_cache;
762 762 QPDFObjectHandle trailer;
763 763 std::vector<QPDFObjectHandle> all_pages;
764   - std::vector<std::string> warnings;
  764 + std::vector<QPDFExc> warnings;
765 765  
766 766 // Linearization data
767 767 int first_xref_item_offset; // actual value from file
... ...
include/qpdf/QPDFExc.hh
... ... @@ -11,7 +11,7 @@
11 11 #include <qpdf/DLL.h>
12 12 #include <qpdf/Constants.h>
13 13 #include <stdexcept>
14   -#include <stddef.h>
  14 +#include <fcntl.h>
15 15  
16 16 class DLL_EXPORT QPDFExc: public std::runtime_error
17 17 {
... ... @@ -36,8 +36,8 @@ class DLL_EXPORT QPDFExc: public std::runtime_error
36 36 qpdf_error_code_e getErrorCode() const;
37 37 std::string const& getFilename() const;
38 38 std::string const& getObject() const;
39   - off_t getOffset() const;
40   - std::string const& getMessage() const;
  39 + off_t getFilePosition() const;
  40 + std::string const& getMessageDetail() const;
41 41  
42 42 private:
43 43 static std::string createWhat(std::string const& filename,
... ...
include/qpdf/qpdf-c.h
... ... @@ -63,12 +63,14 @@
63 63  
64 64 #include <qpdf/DLL.h>
65 65 #include <qpdf/Constants.h>
  66 +#include <fcntl.h>
66 67  
67 68 #ifdef __cplusplus
68 69 extern "C" {
69 70 #endif
70 71  
71 72 typedef struct _qpdf_data* qpdf_data;
  73 + typedef struct _qpdf_error* qpdf_error;
72 74  
73 75 /* Many functions return an integer error code. Codes are defined
74 76 * below. See comments at the top of the file for details. Note
... ... @@ -97,21 +99,42 @@ extern &quot;C&quot; {
97 99  
98 100 /* ERROR REPORTING */
99 101  
100   - /* Returns 1 if there are any errors or warnings, and zero
101   - * otherwise.
  102 + /* Returns the error condition, if any. The return value is a
  103 + * pointer to data that will become invalid the next time an error
  104 + * occurs or after this function is called gain.
102 105 */
103 106 DLL_EXPORT
104   - QPDF_BOOL qpdf_more_errors(qpdf_data qpdf);
  107 + qpdf_error qpdf_get_error(qpdf_data qpdf);
  108 +
  109 + /* Returns 1 if there are any unretrieved warnings, and zero
  110 + * otherwise.
  111 + */
105 112 DLL_EXPORT
106 113 QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf);
107 114  
108   - /* If there are any errors/warnings, returns a pointer to the next
109   - * error or warning. Otherwise returns a null pointer.
  115 + /* If there are any warnings, returns a pointer to the next
  116 + * warning. Otherwise returns a null pointer.
110 117 */
111 118 DLL_EXPORT
112   - char const* qpdf_next_error(qpdf_data qpdf);
  119 + qpdf_error qpdf_next_warning(qpdf_data qpdf);
  120 +
  121 + /* Extract fields of the error. */
  122 +
  123 + /* Use this function to get a full error message suitable for
  124 + * showing to the user. */
  125 + DLL_EXPORT
  126 + char const* qpdf_get_error_full_text(qpdf_data q, qpdf_error e);
  127 +
  128 + /* Use these functions to extract individual fields from the
  129 + * error; see QPDFExc.hh for details. */
  130 + DLL_EXPORT
  131 + enum qpdf_error_code_e qpdf_get_error_code(qpdf_data q, qpdf_error e);
  132 + DLL_EXPORT
  133 + char const* qpdf_get_error_filename(qpdf_data q, qpdf_error e);
  134 + DLL_EXPORT
  135 + off_t qpdf_get_error_file_position(qpdf_data q, qpdf_error e);
113 136 DLL_EXPORT
114   - char const* qpdf_next_warning(qpdf_data qpdf);
  137 + char const* qpdf_get_error_message_detail(qpdf_data q, qpdf_error e);
115 138  
116 139 /* By default, warnings are written to stderr. Passing true to
117 140 * this function will prevent warnings from being written to
... ...
libqpdf/QPDF.cc
... ... @@ -300,10 +300,10 @@ QPDF::setAttemptRecovery(bool val)
300 300 this->attempt_recovery = val;
301 301 }
302 302  
303   -std::vector<std::string>
  303 +std::vector<QPDFExc>
304 304 QPDF::getWarnings()
305 305 {
306   - std::vector<std::string> result = this->warnings;
  306 + std::vector<QPDFExc> result = this->warnings;
307 307 this->warnings.clear();
308 308 return result;
309 309 }
... ... @@ -397,10 +397,10 @@ QPDF::parse()
397 397 void
398 398 QPDF::warn(QPDFExc const& e)
399 399 {
400   - this->warnings.push_back(e.what());
  400 + this->warnings.push_back(e);
401 401 if (! this->suppress_warnings)
402 402 {
403   - std::cerr << "WARNING: " << this->warnings.back() << std::endl;
  403 + std::cerr << "WARNING: " << this->warnings.back().what() << std::endl;
404 404 }
405 405 }
406 406  
... ... @@ -424,7 +424,7 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
424 424 warn(QPDFExc(qpdf_e_damaged_pdf, this->file.getName(), "", 0,
425 425 "file is damaged"));
426 426 warn(e);
427   - warn(QPDFExc(qpdf_e_damaged_pdf, "", "", 0,
  427 + warn(QPDFExc(qpdf_e_damaged_pdf, this->file.getName(), "", 0,
428 428 "Attempting to reconstruct cross-reference table"));
429 429  
430 430 // Delete all references to type 1 (uncompressed) objects
... ...
libqpdf/QPDFExc.cc
... ... @@ -54,3 +54,33 @@ QPDFExc::createWhat(std::string const&amp; filename,
54 54 result += message;
55 55 return result;
56 56 }
  57 +
  58 +qpdf_error_code_e
  59 +QPDFExc::getErrorCode() const
  60 +{
  61 + return this->error_code;
  62 +}
  63 +
  64 +std::string const&
  65 +QPDFExc::getFilename() const
  66 +{
  67 + return this->filename;
  68 +}
  69 +
  70 +std::string const&
  71 +QPDFExc::getObject() const
  72 +{
  73 + return this->object;
  74 +}
  75 +
  76 +off_t
  77 +QPDFExc::getFilePosition() const
  78 +{
  79 + return this->offset;
  80 +}
  81 +
  82 +std::string const&
  83 +QPDFExc::getMessageDetail() const
  84 +{
  85 + return this->message;
  86 +}
... ...
libqpdf/qpdf-c.cc
... ... @@ -3,11 +3,17 @@
3 3 #include <qpdf/QPDF.hh>
4 4 #include <qpdf/QPDFWriter.hh>
5 5 #include <qpdf/QTC.hh>
  6 +#include <qpdf/QPDFExc.hh>
6 7  
7 8 #include <list>
8 9 #include <string>
9 10 #include <stdexcept>
10 11  
  12 +struct _qpdf_error
  13 +{
  14 + PointerHolder<QPDFExc> exc;
  15 +};
  16 +
11 17 struct _qpdf_data
12 18 {
13 19 _qpdf_data();
... ... @@ -16,9 +22,22 @@ struct _qpdf_data
16 22 QPDF* qpdf;
17 23 QPDFWriter* qpdf_writer;
18 24  
19   - std::string error;
20   - std::list<std::string> warnings;
  25 + PointerHolder<QPDFExc> error;
  26 + _qpdf_error tmp_error;
  27 + std::list<QPDFExc> warnings;
21 28 std::string tmp_string;
  29 +
  30 + // Parameters for functions we call
  31 + char const* filename;
  32 + char const* password;
  33 +
  34 + // must set filename and password
  35 + void call_read();
  36 +
  37 + // must set filename
  38 + void call_init_write();
  39 +
  40 + void call_write();
22 41 };
23 42  
24 43 _qpdf_data::_qpdf_data() :
... ... @@ -33,6 +52,65 @@ _qpdf_data::~_qpdf_data()
33 52 delete qpdf;
34 53 }
35 54  
  55 +void
  56 +_qpdf_data::call_read()
  57 +{
  58 + qpdf->processFile(filename, password);
  59 +}
  60 +
  61 +void
  62 +_qpdf_data::call_init_write()
  63 +{
  64 + if (qpdf_writer)
  65 + {
  66 + QTC::TC("qpdf", "qpdf-c called qpdf_init_write multiple times");
  67 + delete qpdf_writer;
  68 + qpdf_writer = 0;
  69 + }
  70 + try
  71 + {
  72 + qpdf_writer = new QPDFWriter(*qpdf, filename);
  73 + }
  74 + catch (...)
  75 + {
  76 + throw;
  77 + }
  78 +}
  79 +
  80 +void
  81 +_qpdf_data::call_write()
  82 +{
  83 + qpdf_writer->write();
  84 +}
  85 +
  86 +static QPDF_ERROR_CODE trap_errors(qpdf_data qpdf, void (_qpdf_data::*fn)())
  87 +{
  88 + QPDF_ERROR_CODE status = QPDF_SUCCESS;
  89 + try
  90 + {
  91 + (qpdf->*fn)();
  92 + }
  93 + catch (QPDFExc& e)
  94 + {
  95 + qpdf->error = new QPDFExc(e);
  96 + status |= QPDF_ERRORS;
  97 + }
  98 + catch (std::runtime_error& e)
  99 + {
  100 + qpdf->error = new QPDFExc(qpdf_e_system, "", "", 0, e.what());
  101 + }
  102 + catch (std::exception& e)
  103 + {
  104 + qpdf->error = new QPDFExc(qpdf_e_internal, "", "", 0, e.what());
  105 + }
  106 +
  107 + if (qpdf_more_warnings(qpdf))
  108 + {
  109 + status |= QPDF_WARNINGS;
  110 + }
  111 + return status;
  112 +}
  113 +
36 114 qpdf_data qpdf_init()
37 115 {
38 116 QTC::TC("qpdf", "qpdf-c called qpdf_init");
... ... @@ -48,19 +126,13 @@ void qpdf_cleanup(qpdf_data* qpdf)
48 126 *qpdf = 0;
49 127 }
50 128  
51   -QPDF_BOOL qpdf_more_errors(qpdf_data qpdf)
52   -{
53   - QTC::TC("qpdf", "qpdf-c called qpdf_more_errors");
54   - return (qpdf->error.empty() ? QPDF_FALSE : QPDF_TRUE);
55   -}
56   -
57 129 QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf)
58 130 {
59 131 QTC::TC("qpdf", "qpdf-c called qpdf_more_warnings");
60 132  
61 133 if (qpdf->warnings.empty())
62 134 {
63   - std::vector<std::string> w = qpdf->qpdf->getWarnings();
  135 + std::vector<QPDFExc> w = qpdf->qpdf->getWarnings();
64 136 if (! w.empty())
65 137 {
66 138 qpdf->warnings.assign(w.begin(), w.end());
... ... @@ -76,14 +148,14 @@ QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf)
76 148 }
77 149 }
78 150  
79   -char const* qpdf_next_error(qpdf_data qpdf)
  151 +qpdf_error qpdf_get_error(qpdf_data qpdf)
80 152 {
81   - if (qpdf_more_errors(qpdf))
  153 + if (qpdf->error.getPointer())
82 154 {
83   - qpdf->tmp_string = qpdf->error;
84   - qpdf->error.clear();
  155 + qpdf->tmp_error.exc = qpdf->error;
  156 + qpdf->error = 0;
85 157 QTC::TC("qpdf", "qpdf-c qpdf_next_error returned error");
86   - return qpdf->tmp_string.c_str();
  158 + return &qpdf->tmp_error;
87 159 }
88 160 else
89 161 {
... ... @@ -91,14 +163,14 @@ char const* qpdf_next_error(qpdf_data qpdf)
91 163 }
92 164 }
93 165  
94   -char const* qpdf_next_warning(qpdf_data qpdf)
  166 +qpdf_error qpdf_next_warning(qpdf_data qpdf)
95 167 {
96 168 if (qpdf_more_warnings(qpdf))
97 169 {
98   - qpdf->tmp_string = qpdf->warnings.front();
  170 + qpdf->tmp_error.exc = new QPDFExc(qpdf->warnings.front());
99 171 qpdf->warnings.pop_front();
100 172 QTC::TC("qpdf", "qpdf-c qpdf_next_warning returned warning");
101   - return qpdf->tmp_string.c_str();
  173 + return &qpdf->tmp_error;
102 174 }
103 175 else
104 176 {
... ... @@ -106,6 +178,31 @@ char const* qpdf_next_warning(qpdf_data qpdf)
106 178 }
107 179 }
108 180  
  181 +char const* qpdf_get_error_full_text(qpdf_data qpdf, qpdf_error e)
  182 +{
  183 + return e->exc.getPointer()->what();
  184 +}
  185 +
  186 +enum qpdf_error_code_e qpdf_get_error_code(qpdf_data qpdf, qpdf_error e)
  187 +{
  188 + return e->exc.getPointer()->getErrorCode();
  189 +}
  190 +
  191 +char const* qpdf_get_error_filename(qpdf_data qpdf, qpdf_error e)
  192 +{
  193 + return e->exc.getPointer()->getFilename().c_str();
  194 +}
  195 +
  196 +off_t qpdf_get_error_file_position(qpdf_data qpdf, qpdf_error e)
  197 +{
  198 + return e->exc.getPointer()->getFilePosition();
  199 +}
  200 +
  201 +char const* qpdf_get_error_message_detail(qpdf_data qpdf, qpdf_error e)
  202 +{
  203 + return e->exc.getPointer()->getMessageDetail().c_str();
  204 +}
  205 +
109 206 void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value)
110 207 {
111 208 QTC::TC("qpdf", "qpdf-c called qpdf_set_suppress_warnings");
... ... @@ -128,19 +225,9 @@ QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename,
128 225 char const* password)
129 226 {
130 227 QPDF_ERROR_CODE status = QPDF_SUCCESS;
131   - try
132   - {
133   - qpdf->qpdf->processFile(filename, password);
134   - }
135   - catch (std::exception& e)
136   - {
137   - qpdf->error = e.what();
138   - status |= QPDF_ERRORS;
139   - }
140   - if (qpdf_more_warnings(qpdf))
141   - {
142   - status |= QPDF_WARNINGS;
143   - }
  228 + qpdf->filename = filename;
  229 + qpdf->password = password;
  230 + status = trap_errors(qpdf, &_qpdf_data::call_read);
144 231 QTC::TC("qpdf", "qpdf-c called qpdf_read", status);
145 232 return status;
146 233 }
... ... @@ -228,25 +315,8 @@ QPDF_BOOL qpdf_allow_modify_all(qpdf_data qpdf)
228 315 QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename)
229 316 {
230 317 QPDF_ERROR_CODE status = QPDF_SUCCESS;
231   - if (qpdf->qpdf_writer)
232   - {
233   - QTC::TC("qpdf", "qpdf-c called qpdf_init_write multiple times");
234   - delete qpdf->qpdf_writer;
235   - qpdf->qpdf_writer = 0;
236   - }
237   - try
238   - {
239   - qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf), filename);
240   - }
241   - catch (std::exception& e)
242   - {
243   - qpdf->error = e.what();
244   - status |= QPDF_ERRORS;
245   - }
246   - if (qpdf_more_warnings(qpdf))
247   - {
248   - status |= QPDF_WARNINGS;
249   - }
  318 + qpdf->filename = filename;
  319 + status = trap_errors(qpdf, &_qpdf_data::call_init_write);
250 320 QTC::TC("qpdf", "qpdf-c called qpdf_init_write", status);
251 321 return status;
252 322 }
... ... @@ -356,19 +426,7 @@ void qpdf_force_pdf_version(qpdf_data qpdf, char const* version)
356 426 QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf)
357 427 {
358 428 QPDF_ERROR_CODE status = QPDF_SUCCESS;
359   - try
360   - {
361   - qpdf->qpdf_writer->write();
362   - }
363   - catch (std::exception& e)
364   - {
365   - qpdf->error = e.what();
366   - status |= QPDF_ERRORS;
367   - }
368   - if (qpdf_more_warnings(qpdf))
369   - {
370   - status |= QPDF_WARNINGS;
371   - }
  429 + status = trap_errors(qpdf, &_qpdf_data::call_write);
372 430 QTC::TC("qpdf", "qpdf-c called qpdf_write", status);
373 431 return status;
374 432 }
... ...
qpdf/qpdf-ctest.c
... ... @@ -8,13 +8,24 @@ static qpdf_data qpdf = 0;
8 8  
9 9 static void report_errors()
10 10 {
  11 + qpdf_error e = 0;
11 12 while (qpdf_more_warnings(qpdf))
12 13 {
13   - printf("warning: %s\n", qpdf_next_warning(qpdf));
  14 + e = qpdf_next_warning(qpdf);
  15 + printf("warning: %s\n", qpdf_get_error_full_text(qpdf, e));
  16 + printf(" code: %d\n", qpdf_get_error_code(qpdf, e));
  17 + printf(" file: %s\n", qpdf_get_error_filename(qpdf, e));
  18 + printf(" pos : %ld\n", qpdf_get_error_file_position(qpdf, e));
  19 + printf(" text: %s\n", qpdf_get_error_message_detail(qpdf, e));
14 20 }
15   - while (qpdf_more_errors(qpdf))
  21 + e = qpdf_get_error(qpdf);
  22 + if (e)
16 23 {
17   - printf("error: %s\n", qpdf_next_error(qpdf));
  24 + printf("error: %s\n", qpdf_get_error_full_text(qpdf, e));
  25 + printf(" code: %d\n", qpdf_get_error_code(qpdf, e));
  26 + printf(" file: %s\n", qpdf_get_error_filename(qpdf, e));
  27 + printf(" pos : %ld\n", qpdf_get_error_file_position(qpdf, e));
  28 + printf(" text: %s\n", qpdf_get_error_message_detail(qpdf, e));
18 29 }
19 30 }
20 31  
... ...
qpdf/qpdf.testcov
... ... @@ -120,7 +120,6 @@ QPDF decoding error warning 0
120 120 QPDF_Stream ignore non-dictionary DecodeParms 0
121 121 qpdf-c called qpdf_init 0
122 122 qpdf-c called qpdf_cleanup 0
123   -qpdf-c called qpdf_more_errors 0
124 123 qpdf-c called qpdf_more_warnings 0
125 124 qpdf-c qpdf_next_error returned error 0
126 125 qpdf-c qpdf_next_warning returned warning 0
... ...
qpdf/qtest/qpdf/append-page-content-damaged-c-check.out
1 1 WARNING: append-page-content-damaged.pdf: file is damaged
2 2 WARNING: append-page-content-damaged.pdf: can't find startxref
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: append-page-content-damaged.pdf: Attempting to reconstruct cross-reference table
4 4 version: 1.3
5 5 linearized: 0
6 6 encrypted: 0
7 7 warning: append-page-content-damaged.pdf: file is damaged
  8 + code: 5
  9 + file: append-page-content-damaged.pdf
  10 + pos : 0
  11 + text: file is damaged
8 12 warning: append-page-content-damaged.pdf: can't find startxref
9   -warning: Attempting to reconstruct cross-reference table
  13 + code: 5
  14 + file: append-page-content-damaged.pdf
  15 + pos : 0
  16 + text: can't find startxref
  17 +warning: append-page-content-damaged.pdf: Attempting to reconstruct cross-reference table
  18 + code: 5
  19 + file: append-page-content-damaged.pdf
  20 + pos : 0
  21 + text: Attempting to reconstruct cross-reference table
... ...
qpdf/qtest/qpdf/append-page-content-damaged-check.out
1 1 WARNING: append-page-content-damaged.pdf: file is damaged
2 2 WARNING: append-page-content-damaged.pdf: can't find startxref
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: append-page-content-damaged.pdf: Attempting to reconstruct cross-reference table
4 4 checking append-page-content-damaged.pdf
5 5 PDF Version: 1.3
6 6 File is not encrypted
... ...
qpdf/qtest/qpdf/append-page-content-damaged.out
1 1 WARNING: append-page-content-damaged.pdf: file is damaged
2 2 WARNING: append-page-content-damaged.pdf: can't find startxref
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: append-page-content-damaged.pdf: Attempting to reconstruct cross-reference table
4 4 qpdf: operation succeeded with warnings; resulting file may have some problems
... ...
qpdf/qtest/qpdf/bad10-recover.out
1 1 WARNING: bad10.pdf: file is damaged
2 2 WARNING: bad10.pdf (trailer, file position 712): /Size key in trailer dictionary is not an integer
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad10.pdf: Attempting to reconstruct cross-reference table
4 4 /QTest is implicit
5 5 /QTest is direct
6 6 /QTest is null
... ...
qpdf/qtest/qpdf/bad11-recover.out
1 1 WARNING: bad11.pdf: file is damaged
2 2 WARNING: bad11.pdf (trailer, file position 905): /Prev key in trailer dictionary is not an integer
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad11.pdf: Attempting to reconstruct cross-reference table
4 4 /QTest is implicit
5 5 /QTest is direct
6 6 /QTest is null
... ...
qpdf/qtest/qpdf/bad13-recover.out
1 1 WARNING: bad13.pdf: file is damaged
2 2 WARNING: bad13.pdf (trailer, file position 753): unexpected brace token
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad13.pdf: Attempting to reconstruct cross-reference table
4 4 bad13.pdf (trailer, file position 753): unexpected brace token
... ...
qpdf/qtest/qpdf/bad14-recover.out
1 1 WARNING: bad14.pdf: file is damaged
2 2 WARNING: bad14.pdf (trailer, file position 753): unexpected brace token
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad14.pdf: Attempting to reconstruct cross-reference table
4 4 bad14.pdf (trailer, file position 753): unexpected brace token
... ...
qpdf/qtest/qpdf/bad15-recover.out
1 1 WARNING: bad15.pdf: file is damaged
2 2 WARNING: bad15.pdf (trailer, file position 753): unexpected array close token
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad15.pdf: Attempting to reconstruct cross-reference table
4 4 bad15.pdf (trailer, file position 753): unexpected array close token
... ...
qpdf/qtest/qpdf/bad16-recover.out
1 1 WARNING: bad16.pdf: file is damaged
2 2 WARNING: bad16.pdf (trailer, file position 753): unexpected dictionary close token
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad16.pdf: Attempting to reconstruct cross-reference table
4 4 bad16.pdf (trailer, file position 753): unexpected dictionary close token
... ...
qpdf/qtest/qpdf/bad17-recover.out
1 1 WARNING: bad17.pdf: file is damaged
2 2 WARNING: bad17.pdf (trailer, file position 753): dictionary ending here has an odd number of elements
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad17.pdf: Attempting to reconstruct cross-reference table
4 4 bad17.pdf (trailer, file position 753): dictionary ending here has an odd number of elements
... ...
qpdf/qtest/qpdf/bad18-recover.out
1 1 WARNING: bad18.pdf: file is damaged
2 2 WARNING: bad18.pdf (trailer, file position 753): unexpected )
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad18.pdf: Attempting to reconstruct cross-reference table
4 4 bad18.pdf (trailer, file position 753): unexpected )
... ...
qpdf/qtest/qpdf/bad19-recover.out
1 1 WARNING: bad19.pdf: file is damaged
2 2 WARNING: bad19.pdf (trailer, file position 753): unexpected >
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad19.pdf: Attempting to reconstruct cross-reference table
4 4 bad19.pdf (trailer, file position 753): unexpected >
... ...
qpdf/qtest/qpdf/bad2-recover.out
1 1 WARNING: bad2.pdf: file is damaged
2 2 WARNING: bad2.pdf: can't find startxref
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad2.pdf: Attempting to reconstruct cross-reference table
4 4 /QTest is implicit
5 5 /QTest is direct
6 6 /QTest is null
... ...
qpdf/qtest/qpdf/bad20-recover.out
1 1 WARNING: bad20.pdf: file is damaged
2 2 WARNING: bad20.pdf (trailer, file position 753): invalid character (q) in hexstring
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad20.pdf: Attempting to reconstruct cross-reference table
4 4 bad20.pdf (trailer, file position 753): invalid character (q) in hexstring
... ...
qpdf/qtest/qpdf/bad21-recover.out
1 1 WARNING: bad21.pdf: file is damaged
2 2 WARNING: bad21.pdf (trailer, file position 742): invalid name token
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad21.pdf: Attempting to reconstruct cross-reference table
4 4 bad21.pdf (trailer, file position 742): invalid name token
... ...
qpdf/qtest/qpdf/bad25-recover.out
1 1 WARNING: bad25.pdf: file is damaged
2 2 WARNING: bad25.pdf (object 4 0, file position 307): expected n n obj
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad25.pdf: Attempting to reconstruct cross-reference table
4 4 WARNING: bad25.pdf: object 4 0 not found in file after regenerating cross reference table
5 5 /QTest is implicit
6 6 /QTest is indirect
... ...
qpdf/qtest/qpdf/bad26-recover.out
1 1 WARNING: bad26.pdf: file is damaged
2 2 WARNING: bad26.pdf (object 4 0, file position 307): expected n n obj
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad26.pdf: Attempting to reconstruct cross-reference table
4 4 WARNING: bad26.pdf: object 4 0 not found in file after regenerating cross reference table
5 5 /QTest is implicit
6 6 /QTest is indirect
... ...
qpdf/qtest/qpdf/bad27-recover.out
1 1 WARNING: bad27.pdf: file is damaged
2 2 WARNING: bad27.pdf (object 4 0, file position 307): expected n n obj
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad27.pdf: Attempting to reconstruct cross-reference table
4 4 WARNING: bad27.pdf: object 4 0 not found in file after regenerating cross reference table
5 5 /QTest is implicit
6 6 /QTest is indirect
... ...
qpdf/qtest/qpdf/bad29-recover.out
1 1 WARNING: bad29.pdf: file is damaged
2 2 WARNING: bad29.pdf (trailer, file position 742): null character not allowed in name token
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad29.pdf: Attempting to reconstruct cross-reference table
4 4 bad29.pdf (trailer, file position 742): null character not allowed in name token
... ...
qpdf/qtest/qpdf/bad3-recover.out
1 1 WARNING: bad3.pdf: file is damaged
2 2 WARNING: bad3.pdf (file position 542): xref not found
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad3.pdf: Attempting to reconstruct cross-reference table
4 4 /QTest is implicit
5 5 /QTest is direct
6 6 /QTest is null
... ...
qpdf/qtest/qpdf/bad32-recover.out
1 1 WARNING: bad32.pdf: file is damaged
2 2 WARNING: bad32.pdf (object 4 0, file position 307): expected 4 0 obj
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad32.pdf: Attempting to reconstruct cross-reference table
4 4 WARNING: bad32.pdf: object 4 0 not found in file after regenerating cross reference table
5 5 /QTest is implicit
6 6 /QTest is indirect
... ...
qpdf/qtest/qpdf/bad33-recover.out
No preview for this file type
qpdf/qtest/qpdf/bad34-recover.out
1 1 WARNING: bad34.pdf: file is damaged
2 2 WARNING: bad34.pdf (object 4 0, file position 322): expected n n obj
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad34.pdf: Attempting to reconstruct cross-reference table
4 4 /QTest is indirect
5 5 /QTest is a stream. Dictionary: << /Length 44 /Quack 9 0 R >>
6 6 Raw stream data:
... ...
qpdf/qtest/qpdf/bad4-recover.out
1 1 WARNING: bad4.pdf: file is damaged
2 2 WARNING: bad4.pdf (xref table, file position 547): xref syntax invalid
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad4.pdf: Attempting to reconstruct cross-reference table
4 4 /QTest is implicit
5 5 /QTest is direct
6 6 /QTest is null
... ...
qpdf/qtest/qpdf/bad5-recover.out
1 1 WARNING: bad5.pdf: file is damaged
2 2 WARNING: bad5.pdf (xref table, file position 591): invalid xref entry (obj=2)
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad5.pdf: Attempting to reconstruct cross-reference table
4 4 /QTest is implicit
5 5 /QTest is direct
6 6 /QTest is null
... ...
qpdf/qtest/qpdf/bad7-recover.out
1 1 WARNING: bad7.pdf: file is damaged
2 2 WARNING: bad7.pdf (file position 698): expected trailer dictionary
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad7.pdf: Attempting to reconstruct cross-reference table
4 4 bad7.pdf: unable to find trailer dictionary while recovering damaged file
... ...
qpdf/qtest/qpdf/bad8-recover.out
1 1 WARNING: bad8.pdf: file is damaged
2 2 WARNING: bad8.pdf (file position 543): xref not found
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad8.pdf: Attempting to reconstruct cross-reference table
4 4 /QTest is implicit
5 5 /QTest is direct
6 6 /QTest is null
... ...
qpdf/qtest/qpdf/bad9-recover.out
1 1 WARNING: bad9.pdf: file is damaged
2 2 WARNING: bad9.pdf (trailer, file position 712): trailer dictionary lacks /Size key
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: bad9.pdf: Attempting to reconstruct cross-reference table
4 4 /QTest is implicit
5 5 /QTest is direct
6 6 /QTest is null
... ...
qpdf/qtest/qpdf/c-no-recovery.out
1 1 error: bad33.pdf (file position 1771): xref not found
  2 + code: 5
  3 + file: bad33.pdf
  4 + pos : 1771
  5 + text: xref not found
... ...
qpdf/qtest/qpdf/c-read-errors.out
1 1 error: bad1.pdf: not a PDF file
  2 + code: 5
  3 + file: bad1.pdf
  4 + pos : 0
  5 + text: not a PDF file
... ...
qpdf/qtest/qpdf/c-read-warnings-and-errors.out
1 1 warning: bad17.pdf: file is damaged
  2 + code: 5
  3 + file: bad17.pdf
  4 + pos : 0
  5 + text: file is damaged
2 6 warning: bad17.pdf (trailer, file position 753): dictionary ending here has an odd number of elements
3   -warning: Attempting to reconstruct cross-reference table
  7 + code: 5
  8 + file: bad17.pdf
  9 + pos : 753
  10 + text: dictionary ending here has an odd number of elements
  11 +warning: bad17.pdf: Attempting to reconstruct cross-reference table
  12 + code: 5
  13 + file: bad17.pdf
  14 + pos : 0
  15 + text: Attempting to reconstruct cross-reference table
4 16 error: bad17.pdf (trailer, file position 753): dictionary ending here has an odd number of elements
  17 + code: 5
  18 + file: bad17.pdf
  19 + pos : 753
  20 + text: dictionary ending here has an odd number of elements
... ...
qpdf/qtest/qpdf/c-write-errors.out
1 1 error: bad30.pdf (file position 629): stream filter type is not name or array
  2 + code: 5
  3 + file: bad30.pdf
  4 + pos : 629
  5 + text: stream filter type is not name or array
... ...
qpdf/qtest/qpdf/c-write-warnings-and-errors.out
1 1 warning: bad33.pdf: file is damaged
  2 + code: 5
  3 + file: bad33.pdf
  4 + pos : 0
  5 + text: file is damaged
2 6 warning: bad33.pdf (file position 1771): xref not found
3   -warning: Attempting to reconstruct cross-reference table
  7 + code: 5
  8 + file: bad33.pdf
  9 + pos : 1771
  10 + text: xref not found
  11 +warning: bad33.pdf: Attempting to reconstruct cross-reference table
  12 + code: 5
  13 + file: bad33.pdf
  14 + pos : 0
  15 + text: Attempting to reconstruct cross-reference table
4 16 error: bad33.pdf (file position 629): stream filter type is not name or array
  17 + code: 5
  18 + file: bad33.pdf
  19 + pos : 629
  20 + text: stream filter type is not name or array
... ...
qpdf/qtest/qpdf/heifer.out
1 1 WARNING: heifer.pdf: file is damaged
2 2 WARNING: heifer.pdf (file position 92741): xref not found
3   -WARNING: Attempting to reconstruct cross-reference table
  3 +WARNING: heifer.pdf: Attempting to reconstruct cross-reference table
4 4 WARNING: heifer.pdf (object 2 0, file position 51): attempting to recover stream length
5 5 qpdf: operation succeeded with warnings; resulting file may have some problems
... ...