aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2018-08-14 01:48:02 +0200
committerJay Berkenbilt <ejb@ql.org>2018-08-14 02:01:51 +0200
commitb4bdc42b4fd627529e1c4a4636d1631254a2f26e (patch)
tree4a3526842ce36c08fef94ec7f60da585a505d6ce
parent164cbdde46d7ec6924782a60f346a6a465a79a26 (diff)
downloadqpdf-b4bdc42b4fd627529e1c4a4636d1631254a2f26e.tar.zst
New exception class QPDFSystemError (fixes #221)
-rw-r--r--ChangeLog6
-rw-r--r--include/qpdf/QPDFSystemError.hh58
-rw-r--r--include/qpdf/QUtil.hh9
-rw-r--r--libqpdf/QPDFSystemError.cc51
-rw-r--r--libqpdf/QUtil.cc18
-rw-r--r--libqpdf/build.mk1
-rw-r--r--libtests/qutil.cc5
7 files changed, 129 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 5570e04c..5d74f7c3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-08-13 Jay Berkenbilt <ejb@ql.org>
+
+ * Add new class QPDFSystemError, derived from std::runtime_error,
+ which is now thrown by QUtil::throw_system_error. This enables the
+ triggering errno value to be retrieved. Fixes #221.
+
2018-08-12 Jay Berkenbilt <ejb@ql.org>
* qpdf command line: add --no-warn option to suppress issuing
diff --git a/include/qpdf/QPDFSystemError.hh b/include/qpdf/QPDFSystemError.hh
new file mode 100644
index 00000000..037bbe0a
--- /dev/null
+++ b/include/qpdf/QPDFSystemError.hh
@@ -0,0 +1,58 @@
+// Copyright (c) 2005-2018 Jay Berkenbilt
+//
+// This file is part of qpdf.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Versions of qpdf prior to version 7 were released under the terms
+// of version 2.0 of the Artistic License. At your option, you may
+// continue to consider qpdf to be licensed under those terms. Please
+// see the manual for additional information.
+
+#ifndef QPDFSYSTEMERROR_HH
+#define QPDFSYSTEMERROR_HH
+
+#include <qpdf/DLL.h>
+#include <qpdf/Types.h>
+
+#include <qpdf/Constants.h>
+#include <string>
+#include <stdexcept>
+
+class QPDFSystemError: public std::runtime_error
+{
+ public:
+ QPDF_DLL
+ QPDFSystemError(std::string const& description,
+ int system_errno);
+ QPDF_DLL
+ virtual ~QPDFSystemError() throw ();
+
+ // To get a complete error string, call what(), provided by
+ // std::exception. The accessors below return the original values
+ // used to create the exception.
+
+ QPDF_DLL
+ std::string const& getDescription() const;
+ QPDF_DLL
+ int getErrno() const;
+
+ private:
+ static std::string createWhat(std::string const& description,
+ int system_errno);
+
+ std::string description;
+ int system_errno;
+};
+
+#endif // QPDFSYSTEMERROR_HH
diff --git a/include/qpdf/QUtil.hh b/include/qpdf/QUtil.hh
index 68e64370..bcedd4d3 100644
--- a/include/qpdf/QUtil.hh
+++ b/include/qpdf/QUtil.hh
@@ -61,9 +61,14 @@ namespace QUtil
QPDF_DLL
unsigned char* unsigned_char_pointer(char const* str);
- // Throw std::runtime_error with a string formed by appending to
+ // Throw QPDFSystemError, which is derived from
+ // std::runtime_error, with a string formed by appending to
// "description: " the standard string corresponding to the
- // current value of errno.
+ // current value of errno. You can retrieve the value of errno by
+ // calling getErrno() on the QPDFSystemError. Prior to qpdf 8.2.0,
+ // this method threw system::runtime_error directly, but since
+ // QPDFSystemError is derived from system::runtime_error, old code
+ // that specifically catches std::runtime_error will still work.
QPDF_DLL
void throw_system_error(std::string const& description);
diff --git a/libqpdf/QPDFSystemError.cc b/libqpdf/QPDFSystemError.cc
new file mode 100644
index 00000000..094341cd
--- /dev/null
+++ b/libqpdf/QPDFSystemError.cc
@@ -0,0 +1,51 @@
+#include <qpdf/QPDFSystemError.hh>
+#include <qpdf/QUtil.hh>
+#include <string.h>
+
+QPDFSystemError::QPDFSystemError(std::string const& description,
+ int system_errno) :
+ std::runtime_error(createWhat(description, system_errno)),
+ description(description),
+ system_errno(system_errno)
+{
+}
+
+QPDFSystemError::~QPDFSystemError() throw ()
+{
+}
+
+std::string
+QPDFSystemError::createWhat(std::string const& description,
+ int system_errno)
+{
+ std::string message;
+#ifdef _MSC_VER
+ // "94" is mentioned in the MSVC docs, but it's still safe if the
+ // message is longer. strerror_s is a templated function that
+ // knows the size of buf and truncates.
+ char buf[94];
+ if (strerror_s(buf, errno) != 0)
+ {
+ message = description + ": failed with an unknown error";
+ }
+ else
+ {
+ message = description + ": " + buf;
+ }
+#else
+ message = description + ": " + strerror(errno);
+#endif
+ return message;
+}
+
+std::string const&
+QPDFSystemError::getDescription() const
+{
+ return this->description;
+}
+
+int
+QPDFSystemError::getErrno() const
+{
+ return this->system_errno;
+}
diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc
index e2bc0bac..56bac386 100644
--- a/libqpdf/QUtil.cc
+++ b/libqpdf/QUtil.cc
@@ -7,6 +7,7 @@
# include <qpdf/InsecureRandomDataProvider.hh>
#endif
#include <qpdf/SecureRandomDataProvider.hh>
+#include <qpdf/QPDFSystemError.hh>
#include <cmath>
#include <iomanip>
@@ -132,22 +133,7 @@ QUtil::unsigned_char_pointer(char const* str)
void
QUtil::throw_system_error(std::string const& description)
{
-#ifdef _MSC_VER
- // "94" is mentioned in the MSVC docs, but it's still safe if the
- // message is longer. strerror_s is a templated function that
- // knows the size of buf and truncates.
- char buf[94];
- if (strerror_s(buf, errno) != 0)
- {
- throw std::runtime_error(description + ": failed with an unknown error");
- }
- else
- {
- throw std::runtime_error(description + ": " + buf);
- }
-#else
- throw std::runtime_error(description + ": " + strerror(errno));
-#endif
+ throw QPDFSystemError(description, errno);
}
int
diff --git a/libqpdf/build.mk b/libqpdf/build.mk
index 528456f8..61ea4b2d 100644
--- a/libqpdf/build.mk
+++ b/libqpdf/build.mk
@@ -45,6 +45,7 @@ SRCS_libqpdf = \
libqpdf/QPDFObjectHandle.cc \
libqpdf/QPDFPageDocumentHelper.cc \
libqpdf/QPDFPageObjectHelper.cc \
+ libqpdf/QPDFSystemError.cc \
libqpdf/QPDFTokenizer.cc \
libqpdf/QPDFWriter.cc \
libqpdf/QPDFXRefEntry.cc \
diff --git a/libtests/qutil.cc b/libtests/qutil.cc
index 78c52156..025f4e43 100644
--- a/libtests/qutil.cc
+++ b/libtests/qutil.cc
@@ -5,8 +5,10 @@
#include <fcntl.h>
#include <qpdf/QUtil.hh>
#include <qpdf/PointerHolder.hh>
+#include <qpdf/QPDFSystemError.hh>
#include <string.h>
#include <limits.h>
+#include <assert.h>
#ifdef _WIN32
# include <io.h>
@@ -137,9 +139,10 @@ void fopen_wrapper_test()
std::cout << "after fopen" << std::endl;
(void) fclose(f);
}
- catch (std::runtime_error& s)
+ catch (QPDFSystemError& s)
{
std::cout << "exception: " << s.what() << std::endl;
+ assert(s.getErrno() != 0);
}
}