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 2009-10-19 Jay Berkenbilt <jberkenb@argonst.com> 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 * Include information about the last object read in most error 7 * Include information about the last object read in most error
4 messages. Most of the time, this will provide a good hint as to 8 messages. Most of the time, this will provide a good hint as to
5 which object contains the error, but it's possible that the last 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,6 +24,7 @@ int main(int argc, char* argv[])
24 int warnings = 0; 24 int warnings = 0;
25 int errors = 0; 25 int errors = 0;
26 char* p = 0; 26 char* p = 0;
  27 + qpdf_error e = 0;
27 28
28 if ((p = strrchr(argv[0], '/')) != NULL) 29 if ((p = strrchr(argv[0], '/')) != NULL)
29 { 30 {
@@ -53,12 +54,14 @@ int main(int argc, char* argv[]) @@ -53,12 +54,14 @@ int main(int argc, char* argv[])
53 while (qpdf_more_warnings(qpdf)) 54 while (qpdf_more_warnings(qpdf))
54 { 55 {
55 warnings = 1; 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 errors = 1; 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 qpdf_cleanup(&qpdf); 66 qpdf_cleanup(&qpdf);
64 if (errors) 67 if (errors)
include/qpdf/QPDF.hh
@@ -70,7 +70,7 @@ class DLL_EXPORT QPDF @@ -70,7 +70,7 @@ class DLL_EXPORT QPDF
70 // throws an exception. Note that if setSuppressWarnings was not 70 // throws an exception. Note that if setSuppressWarnings was not
71 // called or was called with a false value, any warnings retrieved 71 // called or was called with a false value, any warnings retrieved
72 // here will have already been issued to stderr. 72 // here will have already been issued to stderr.
73 - std::vector<std::string> getWarnings(); 73 + std::vector<QPDFExc> getWarnings();
74 74
75 std::string getFilename() const; 75 std::string getFilename() const;
76 std::string getPDFVersion() const; 76 std::string getPDFVersion() const;
@@ -761,7 +761,7 @@ class DLL_EXPORT QPDF @@ -761,7 +761,7 @@ class DLL_EXPORT QPDF
761 std::map<ObjGen, ObjCache> obj_cache; 761 std::map<ObjGen, ObjCache> obj_cache;
762 QPDFObjectHandle trailer; 762 QPDFObjectHandle trailer;
763 std::vector<QPDFObjectHandle> all_pages; 763 std::vector<QPDFObjectHandle> all_pages;
764 - std::vector<std::string> warnings; 764 + std::vector<QPDFExc> warnings;
765 765
766 // Linearization data 766 // Linearization data
767 int first_xref_item_offset; // actual value from file 767 int first_xref_item_offset; // actual value from file
include/qpdf/QPDFExc.hh
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 #include <qpdf/DLL.h> 11 #include <qpdf/DLL.h>
12 #include <qpdf/Constants.h> 12 #include <qpdf/Constants.h>
13 #include <stdexcept> 13 #include <stdexcept>
14 -#include <stddef.h> 14 +#include <fcntl.h>
15 15
16 class DLL_EXPORT QPDFExc: public std::runtime_error 16 class DLL_EXPORT QPDFExc: public std::runtime_error
17 { 17 {
@@ -36,8 +36,8 @@ class DLL_EXPORT QPDFExc: public std::runtime_error @@ -36,8 +36,8 @@ class DLL_EXPORT QPDFExc: public std::runtime_error
36 qpdf_error_code_e getErrorCode() const; 36 qpdf_error_code_e getErrorCode() const;
37 std::string const& getFilename() const; 37 std::string const& getFilename() const;
38 std::string const& getObject() const; 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 private: 42 private:
43 static std::string createWhat(std::string const& filename, 43 static std::string createWhat(std::string const& filename,
include/qpdf/qpdf-c.h
@@ -63,12 +63,14 @@ @@ -63,12 +63,14 @@
63 63
64 #include <qpdf/DLL.h> 64 #include <qpdf/DLL.h>
65 #include <qpdf/Constants.h> 65 #include <qpdf/Constants.h>
  66 +#include <fcntl.h>
66 67
67 #ifdef __cplusplus 68 #ifdef __cplusplus
68 extern "C" { 69 extern "C" {
69 #endif 70 #endif
70 71
71 typedef struct _qpdf_data* qpdf_data; 72 typedef struct _qpdf_data* qpdf_data;
  73 + typedef struct _qpdf_error* qpdf_error;
72 74
73 /* Many functions return an integer error code. Codes are defined 75 /* Many functions return an integer error code. Codes are defined
74 * below. See comments at the top of the file for details. Note 76 * below. See comments at the top of the file for details. Note
@@ -97,21 +99,42 @@ extern &quot;C&quot; { @@ -97,21 +99,42 @@ extern &quot;C&quot; {
97 99
98 /* ERROR REPORTING */ 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 DLL_EXPORT 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 DLL_EXPORT 112 DLL_EXPORT
106 QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf); 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 DLL_EXPORT 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 DLL_EXPORT 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 /* By default, warnings are written to stderr. Passing true to 139 /* By default, warnings are written to stderr. Passing true to
117 * this function will prevent warnings from being written to 140 * this function will prevent warnings from being written to
libqpdf/QPDF.cc
@@ -300,10 +300,10 @@ QPDF::setAttemptRecovery(bool val) @@ -300,10 +300,10 @@ QPDF::setAttemptRecovery(bool val)
300 this->attempt_recovery = val; 300 this->attempt_recovery = val;
301 } 301 }
302 302
303 -std::vector<std::string> 303 +std::vector<QPDFExc>
304 QPDF::getWarnings() 304 QPDF::getWarnings()
305 { 305 {
306 - std::vector<std::string> result = this->warnings; 306 + std::vector<QPDFExc> result = this->warnings;
307 this->warnings.clear(); 307 this->warnings.clear();
308 return result; 308 return result;
309 } 309 }
@@ -397,10 +397,10 @@ QPDF::parse() @@ -397,10 +397,10 @@ QPDF::parse()
397 void 397 void
398 QPDF::warn(QPDFExc const& e) 398 QPDF::warn(QPDFExc const& e)
399 { 399 {
400 - this->warnings.push_back(e.what()); 400 + this->warnings.push_back(e);
401 if (! this->suppress_warnings) 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,7 +424,7 @@ QPDF::reconstruct_xref(QPDFExc&amp; e)
424 warn(QPDFExc(qpdf_e_damaged_pdf, this->file.getName(), "", 0, 424 warn(QPDFExc(qpdf_e_damaged_pdf, this->file.getName(), "", 0,
425 "file is damaged")); 425 "file is damaged"));
426 warn(e); 426 warn(e);
427 - warn(QPDFExc(qpdf_e_damaged_pdf, "", "", 0, 427 + warn(QPDFExc(qpdf_e_damaged_pdf, this->file.getName(), "", 0,
428 "Attempting to reconstruct cross-reference table")); 428 "Attempting to reconstruct cross-reference table"));
429 429
430 // Delete all references to type 1 (uncompressed) objects 430 // Delete all references to type 1 (uncompressed) objects
libqpdf/QPDFExc.cc
@@ -54,3 +54,33 @@ QPDFExc::createWhat(std::string const&amp; filename, @@ -54,3 +54,33 @@ QPDFExc::createWhat(std::string const&amp; filename,
54 result += message; 54 result += message;
55 return result; 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,11 +3,17 @@
3 #include <qpdf/QPDF.hh> 3 #include <qpdf/QPDF.hh>
4 #include <qpdf/QPDFWriter.hh> 4 #include <qpdf/QPDFWriter.hh>
5 #include <qpdf/QTC.hh> 5 #include <qpdf/QTC.hh>
  6 +#include <qpdf/QPDFExc.hh>
6 7
7 #include <list> 8 #include <list>
8 #include <string> 9 #include <string>
9 #include <stdexcept> 10 #include <stdexcept>
10 11
  12 +struct _qpdf_error
  13 +{
  14 + PointerHolder<QPDFExc> exc;
  15 +};
  16 +
11 struct _qpdf_data 17 struct _qpdf_data
12 { 18 {
13 _qpdf_data(); 19 _qpdf_data();
@@ -16,9 +22,22 @@ struct _qpdf_data @@ -16,9 +22,22 @@ struct _qpdf_data
16 QPDF* qpdf; 22 QPDF* qpdf;
17 QPDFWriter* qpdf_writer; 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 std::string tmp_string; 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 _qpdf_data::_qpdf_data() : 43 _qpdf_data::_qpdf_data() :
@@ -33,6 +52,65 @@ _qpdf_data::~_qpdf_data() @@ -33,6 +52,65 @@ _qpdf_data::~_qpdf_data()
33 delete qpdf; 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 qpdf_data qpdf_init() 114 qpdf_data qpdf_init()
37 { 115 {
38 QTC::TC("qpdf", "qpdf-c called qpdf_init"); 116 QTC::TC("qpdf", "qpdf-c called qpdf_init");
@@ -48,19 +126,13 @@ void qpdf_cleanup(qpdf_data* qpdf) @@ -48,19 +126,13 @@ void qpdf_cleanup(qpdf_data* qpdf)
48 *qpdf = 0; 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 QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf) 129 QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf)
58 { 130 {
59 QTC::TC("qpdf", "qpdf-c called qpdf_more_warnings"); 131 QTC::TC("qpdf", "qpdf-c called qpdf_more_warnings");
60 132
61 if (qpdf->warnings.empty()) 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 if (! w.empty()) 136 if (! w.empty())
65 { 137 {
66 qpdf->warnings.assign(w.begin(), w.end()); 138 qpdf->warnings.assign(w.begin(), w.end());
@@ -76,14 +148,14 @@ QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf) @@ -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 QTC::TC("qpdf", "qpdf-c qpdf_next_error returned error"); 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 else 160 else
89 { 161 {
@@ -91,14 +163,14 @@ char const* qpdf_next_error(qpdf_data qpdf) @@ -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 if (qpdf_more_warnings(qpdf)) 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 qpdf->warnings.pop_front(); 171 qpdf->warnings.pop_front();
100 QTC::TC("qpdf", "qpdf-c qpdf_next_warning returned warning"); 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 else 175 else
104 { 176 {
@@ -106,6 +178,31 @@ char const* qpdf_next_warning(qpdf_data qpdf) @@ -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 void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value) 206 void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value)
110 { 207 {
111 QTC::TC("qpdf", "qpdf-c called qpdf_set_suppress_warnings"); 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,19 +225,9 @@ QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename,
128 char const* password) 225 char const* password)
129 { 226 {
130 QPDF_ERROR_CODE status = QPDF_SUCCESS; 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 QTC::TC("qpdf", "qpdf-c called qpdf_read", status); 231 QTC::TC("qpdf", "qpdf-c called qpdf_read", status);
145 return status; 232 return status;
146 } 233 }
@@ -228,25 +315,8 @@ QPDF_BOOL qpdf_allow_modify_all(qpdf_data qpdf) @@ -228,25 +315,8 @@ QPDF_BOOL qpdf_allow_modify_all(qpdf_data qpdf)
228 QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename) 315 QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename)
229 { 316 {
230 QPDF_ERROR_CODE status = QPDF_SUCCESS; 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 QTC::TC("qpdf", "qpdf-c called qpdf_init_write", status); 320 QTC::TC("qpdf", "qpdf-c called qpdf_init_write", status);
251 return status; 321 return status;
252 } 322 }
@@ -356,19 +426,7 @@ void qpdf_force_pdf_version(qpdf_data qpdf, char const* version) @@ -356,19 +426,7 @@ void qpdf_force_pdf_version(qpdf_data qpdf, char const* version)
356 QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf) 426 QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf)
357 { 427 {
358 QPDF_ERROR_CODE status = QPDF_SUCCESS; 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 QTC::TC("qpdf", "qpdf-c called qpdf_write", status); 430 QTC::TC("qpdf", "qpdf-c called qpdf_write", status);
373 return status; 431 return status;
374 } 432 }
qpdf/qpdf-ctest.c
@@ -8,13 +8,24 @@ static qpdf_data qpdf = 0; @@ -8,13 +8,24 @@ static qpdf_data qpdf = 0;
8 8
9 static void report_errors() 9 static void report_errors()
10 { 10 {
  11 + qpdf_error e = 0;
11 while (qpdf_more_warnings(qpdf)) 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,7 +120,6 @@ QPDF decoding error warning 0
120 QPDF_Stream ignore non-dictionary DecodeParms 0 120 QPDF_Stream ignore non-dictionary DecodeParms 0
121 qpdf-c called qpdf_init 0 121 qpdf-c called qpdf_init 0
122 qpdf-c called qpdf_cleanup 0 122 qpdf-c called qpdf_cleanup 0
123 -qpdf-c called qpdf_more_errors 0  
124 qpdf-c called qpdf_more_warnings 0 123 qpdf-c called qpdf_more_warnings 0
125 qpdf-c qpdf_next_error returned error 0 124 qpdf-c qpdf_next_error returned error 0
126 qpdf-c qpdf_next_warning returned warning 0 125 qpdf-c qpdf_next_warning returned warning 0
qpdf/qtest/qpdf/append-page-content-damaged-c-check.out
1 WARNING: append-page-content-damaged.pdf: file is damaged 1 WARNING: append-page-content-damaged.pdf: file is damaged
2 WARNING: append-page-content-damaged.pdf: can't find startxref 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 version: 1.3 4 version: 1.3
5 linearized: 0 5 linearized: 0
6 encrypted: 0 6 encrypted: 0
7 warning: append-page-content-damaged.pdf: file is damaged 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 warning: append-page-content-damaged.pdf: can't find startxref 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 WARNING: append-page-content-damaged.pdf: file is damaged 1 WARNING: append-page-content-damaged.pdf: file is damaged
2 WARNING: append-page-content-damaged.pdf: can't find startxref 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 checking append-page-content-damaged.pdf 4 checking append-page-content-damaged.pdf
5 PDF Version: 1.3 5 PDF Version: 1.3
6 File is not encrypted 6 File is not encrypted
qpdf/qtest/qpdf/append-page-content-damaged.out
1 WARNING: append-page-content-damaged.pdf: file is damaged 1 WARNING: append-page-content-damaged.pdf: file is damaged
2 WARNING: append-page-content-damaged.pdf: can't find startxref 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 qpdf: operation succeeded with warnings; resulting file may have some problems 4 qpdf: operation succeeded with warnings; resulting file may have some problems
qpdf/qtest/qpdf/bad10-recover.out
1 WARNING: bad10.pdf: file is damaged 1 WARNING: bad10.pdf: file is damaged
2 WARNING: bad10.pdf (trailer, file position 712): /Size key in trailer dictionary is not an integer 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 /QTest is implicit 4 /QTest is implicit
5 /QTest is direct 5 /QTest is direct
6 /QTest is null 6 /QTest is null
qpdf/qtest/qpdf/bad11-recover.out
1 WARNING: bad11.pdf: file is damaged 1 WARNING: bad11.pdf: file is damaged
2 WARNING: bad11.pdf (trailer, file position 905): /Prev key in trailer dictionary is not an integer 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 /QTest is implicit 4 /QTest is implicit
5 /QTest is direct 5 /QTest is direct
6 /QTest is null 6 /QTest is null
qpdf/qtest/qpdf/bad13-recover.out
1 WARNING: bad13.pdf: file is damaged 1 WARNING: bad13.pdf: file is damaged
2 WARNING: bad13.pdf (trailer, file position 753): unexpected brace token 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 bad13.pdf (trailer, file position 753): unexpected brace token 4 bad13.pdf (trailer, file position 753): unexpected brace token
qpdf/qtest/qpdf/bad14-recover.out
1 WARNING: bad14.pdf: file is damaged 1 WARNING: bad14.pdf: file is damaged
2 WARNING: bad14.pdf (trailer, file position 753): unexpected brace token 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 bad14.pdf (trailer, file position 753): unexpected brace token 4 bad14.pdf (trailer, file position 753): unexpected brace token
qpdf/qtest/qpdf/bad15-recover.out
1 WARNING: bad15.pdf: file is damaged 1 WARNING: bad15.pdf: file is damaged
2 WARNING: bad15.pdf (trailer, file position 753): unexpected array close token 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 bad15.pdf (trailer, file position 753): unexpected array close token 4 bad15.pdf (trailer, file position 753): unexpected array close token
qpdf/qtest/qpdf/bad16-recover.out
1 WARNING: bad16.pdf: file is damaged 1 WARNING: bad16.pdf: file is damaged
2 WARNING: bad16.pdf (trailer, file position 753): unexpected dictionary close token 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 bad16.pdf (trailer, file position 753): unexpected dictionary close token 4 bad16.pdf (trailer, file position 753): unexpected dictionary close token
qpdf/qtest/qpdf/bad17-recover.out
1 WARNING: bad17.pdf: file is damaged 1 WARNING: bad17.pdf: file is damaged
2 WARNING: bad17.pdf (trailer, file position 753): dictionary ending here has an odd number of elements 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 bad17.pdf (trailer, file position 753): dictionary ending here has an odd number of elements 4 bad17.pdf (trailer, file position 753): dictionary ending here has an odd number of elements
qpdf/qtest/qpdf/bad18-recover.out
1 WARNING: bad18.pdf: file is damaged 1 WARNING: bad18.pdf: file is damaged
2 WARNING: bad18.pdf (trailer, file position 753): unexpected ) 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 bad18.pdf (trailer, file position 753): unexpected ) 4 bad18.pdf (trailer, file position 753): unexpected )
qpdf/qtest/qpdf/bad19-recover.out
1 WARNING: bad19.pdf: file is damaged 1 WARNING: bad19.pdf: file is damaged
2 WARNING: bad19.pdf (trailer, file position 753): unexpected > 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 bad19.pdf (trailer, file position 753): unexpected > 4 bad19.pdf (trailer, file position 753): unexpected >
qpdf/qtest/qpdf/bad2-recover.out
1 WARNING: bad2.pdf: file is damaged 1 WARNING: bad2.pdf: file is damaged
2 WARNING: bad2.pdf: can't find startxref 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 /QTest is implicit 4 /QTest is implicit
5 /QTest is direct 5 /QTest is direct
6 /QTest is null 6 /QTest is null
qpdf/qtest/qpdf/bad20-recover.out
1 WARNING: bad20.pdf: file is damaged 1 WARNING: bad20.pdf: file is damaged
2 WARNING: bad20.pdf (trailer, file position 753): invalid character (q) in hexstring 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 bad20.pdf (trailer, file position 753): invalid character (q) in hexstring 4 bad20.pdf (trailer, file position 753): invalid character (q) in hexstring
qpdf/qtest/qpdf/bad21-recover.out
1 WARNING: bad21.pdf: file is damaged 1 WARNING: bad21.pdf: file is damaged
2 WARNING: bad21.pdf (trailer, file position 742): invalid name token 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 bad21.pdf (trailer, file position 742): invalid name token 4 bad21.pdf (trailer, file position 742): invalid name token
qpdf/qtest/qpdf/bad25-recover.out
1 WARNING: bad25.pdf: file is damaged 1 WARNING: bad25.pdf: file is damaged
2 WARNING: bad25.pdf (object 4 0, file position 307): expected n n obj 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 WARNING: bad25.pdf: object 4 0 not found in file after regenerating cross reference table 4 WARNING: bad25.pdf: object 4 0 not found in file after regenerating cross reference table
5 /QTest is implicit 5 /QTest is implicit
6 /QTest is indirect 6 /QTest is indirect
qpdf/qtest/qpdf/bad26-recover.out
1 WARNING: bad26.pdf: file is damaged 1 WARNING: bad26.pdf: file is damaged
2 WARNING: bad26.pdf (object 4 0, file position 307): expected n n obj 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 WARNING: bad26.pdf: object 4 0 not found in file after regenerating cross reference table 4 WARNING: bad26.pdf: object 4 0 not found in file after regenerating cross reference table
5 /QTest is implicit 5 /QTest is implicit
6 /QTest is indirect 6 /QTest is indirect
qpdf/qtest/qpdf/bad27-recover.out
1 WARNING: bad27.pdf: file is damaged 1 WARNING: bad27.pdf: file is damaged
2 WARNING: bad27.pdf (object 4 0, file position 307): expected n n obj 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 WARNING: bad27.pdf: object 4 0 not found in file after regenerating cross reference table 4 WARNING: bad27.pdf: object 4 0 not found in file after regenerating cross reference table
5 /QTest is implicit 5 /QTest is implicit
6 /QTest is indirect 6 /QTest is indirect
qpdf/qtest/qpdf/bad29-recover.out
1 WARNING: bad29.pdf: file is damaged 1 WARNING: bad29.pdf: file is damaged
2 WARNING: bad29.pdf (trailer, file position 742): null character not allowed in name token 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 bad29.pdf (trailer, file position 742): null character not allowed in name token 4 bad29.pdf (trailer, file position 742): null character not allowed in name token
qpdf/qtest/qpdf/bad3-recover.out
1 WARNING: bad3.pdf: file is damaged 1 WARNING: bad3.pdf: file is damaged
2 WARNING: bad3.pdf (file position 542): xref not found 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 /QTest is implicit 4 /QTest is implicit
5 /QTest is direct 5 /QTest is direct
6 /QTest is null 6 /QTest is null
qpdf/qtest/qpdf/bad32-recover.out
1 WARNING: bad32.pdf: file is damaged 1 WARNING: bad32.pdf: file is damaged
2 WARNING: bad32.pdf (object 4 0, file position 307): expected 4 0 obj 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 WARNING: bad32.pdf: object 4 0 not found in file after regenerating cross reference table 4 WARNING: bad32.pdf: object 4 0 not found in file after regenerating cross reference table
5 /QTest is implicit 5 /QTest is implicit
6 /QTest is indirect 6 /QTest is indirect
qpdf/qtest/qpdf/bad33-recover.out
No preview for this file type
qpdf/qtest/qpdf/bad34-recover.out
1 WARNING: bad34.pdf: file is damaged 1 WARNING: bad34.pdf: file is damaged
2 WARNING: bad34.pdf (object 4 0, file position 322): expected n n obj 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 /QTest is indirect 4 /QTest is indirect
5 /QTest is a stream. Dictionary: << /Length 44 /Quack 9 0 R >> 5 /QTest is a stream. Dictionary: << /Length 44 /Quack 9 0 R >>
6 Raw stream data: 6 Raw stream data:
qpdf/qtest/qpdf/bad4-recover.out
1 WARNING: bad4.pdf: file is damaged 1 WARNING: bad4.pdf: file is damaged
2 WARNING: bad4.pdf (xref table, file position 547): xref syntax invalid 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 /QTest is implicit 4 /QTest is implicit
5 /QTest is direct 5 /QTest is direct
6 /QTest is null 6 /QTest is null
qpdf/qtest/qpdf/bad5-recover.out
1 WARNING: bad5.pdf: file is damaged 1 WARNING: bad5.pdf: file is damaged
2 WARNING: bad5.pdf (xref table, file position 591): invalid xref entry (obj=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 /QTest is implicit 4 /QTest is implicit
5 /QTest is direct 5 /QTest is direct
6 /QTest is null 6 /QTest is null
qpdf/qtest/qpdf/bad7-recover.out
1 WARNING: bad7.pdf: file is damaged 1 WARNING: bad7.pdf: file is damaged
2 WARNING: bad7.pdf (file position 698): expected trailer dictionary 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 bad7.pdf: unable to find trailer dictionary while recovering damaged file 4 bad7.pdf: unable to find trailer dictionary while recovering damaged file
qpdf/qtest/qpdf/bad8-recover.out
1 WARNING: bad8.pdf: file is damaged 1 WARNING: bad8.pdf: file is damaged
2 WARNING: bad8.pdf (file position 543): xref not found 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 /QTest is implicit 4 /QTest is implicit
5 /QTest is direct 5 /QTest is direct
6 /QTest is null 6 /QTest is null
qpdf/qtest/qpdf/bad9-recover.out
1 WARNING: bad9.pdf: file is damaged 1 WARNING: bad9.pdf: file is damaged
2 WARNING: bad9.pdf (trailer, file position 712): trailer dictionary lacks /Size key 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 /QTest is implicit 4 /QTest is implicit
5 /QTest is direct 5 /QTest is direct
6 /QTest is null 6 /QTest is null
qpdf/qtest/qpdf/c-no-recovery.out
1 error: bad33.pdf (file position 1771): xref not found 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 error: bad1.pdf: not a PDF file 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 warning: bad17.pdf: file is damaged 1 warning: bad17.pdf: file is damaged
  2 + code: 5
  3 + file: bad17.pdf
  4 + pos : 0
  5 + text: file is damaged
2 warning: bad17.pdf (trailer, file position 753): dictionary ending here has an odd number of elements 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 error: bad17.pdf (trailer, file position 753): dictionary ending here has an odd number of elements 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 error: bad30.pdf (file position 629): stream filter type is not name or array 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 warning: bad33.pdf: file is damaged 1 warning: bad33.pdf: file is damaged
  2 + code: 5
  3 + file: bad33.pdf
  4 + pos : 0
  5 + text: file is damaged
2 warning: bad33.pdf (file position 1771): xref not found 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 error: bad33.pdf (file position 629): stream filter type is not name or array 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 WARNING: heifer.pdf: file is damaged 1 WARNING: heifer.pdf: file is damaged
2 WARNING: heifer.pdf (file position 92741): xref not found 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 WARNING: heifer.pdf (object 2 0, file position 51): attempting to recover stream length 4 WARNING: heifer.pdf (object 2 0, file position 51): attempting to recover stream length
5 qpdf: operation succeeded with warnings; resulting file may have some problems 5 qpdf: operation succeeded with warnings; resulting file may have some problems