summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2013-02-28 23:10:30 +0100
committerJay Berkenbilt <ejb@ql.org>2013-03-05 19:35:46 +0100
commitfd649593983925356fcc61c04a75c9f55cee3648 (patch)
tree7a79631772422d1808872e50e21eb4178e2eddeb
parentac4deac1873ca1bb570ffd479ed2cc1010762f89 (diff)
downloadqpdf-fd649593983925356fcc61c04a75c9f55cee3648.tar.zst
Favor strerror_s and fopen_s on MSVC
Make remaining calls to fopen and strerror use strerror_s and fopen_s on MSVC.
-rw-r--r--ChangeLog4
-rw-r--r--libqpdf/QUtil.cc31
-rw-r--r--qpdf/qpdf-ctest.c18
3 files changed, 48 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index d8f4da71..90b110e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2013-02-28 Jay Berkenbilt <ejb@ql.org>
+ * Favor fopen_s and strerror_s on MSVC to avoid CRT security
+ warnings. This is useful for people who may want to use qpdf in
+ an application that is Windows 8 certified.
+
* New method QUtil::safe_fopen to wrap calls to fopen. This is
less cumbersome than calling QUtil::fopen_wrapper.
diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc
index b7cdb9b2..adcb1515 100644
--- a/libqpdf/QUtil.cc
+++ b/libqpdf/QUtil.cc
@@ -96,7 +96,22 @@ QUtil::unsigned_char_pointer(char const* str)
void
QUtil::throw_system_error(std::string const& description)
{
- throw std::runtime_error(description + ": " + strerror(errno)); // XXXX
+#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
}
int
@@ -112,8 +127,18 @@ QUtil::os_wrapper(std::string const& description, int status)
FILE*
QUtil::safe_fopen(char const* filename, char const* mode)
{
- return fopen_wrapper(std::string("open ") + filename,
- fopen(filename, mode)); // XXXX
+ FILE* f = 0;
+#ifdef _MSC_VER
+ errno_t err = fopen_s(&f, filename, mode);
+ if (err != 0)
+ {
+ errno = err;
+ throw_system_error(std::string("open ") + filename);
+ }
+#else
+ f = fopen_wrapper(std::string("open ") + filename, fopen(filename, mode));
+#endif
+ return f;
}
FILE*
diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c
index 12f6a4cc..c535aa23 100644
--- a/qpdf/qpdf-ctest.c
+++ b/qpdf/qpdf-ctest.c
@@ -10,13 +10,27 @@ static qpdf_data qpdf = 0;
static FILE* safe_fopen(char const* filename, char const* mode)
{
- FILE* f = fopen(filename, mode); /* XXXX */
+ // This function is basically a "C" port of QUtil::safe_fopen.
+ FILE* f = 0;
+#ifdef _MSC_VER
+ errno_t err = fopen_s(&f, filename, mode);
+ if (err != 0)
+ {
+ char buf[94];
+ strerror_s(buf, sizeof(buf), errno);
+ fprintf(stderr, "%s: unable to open %s: %s\n",
+ whoami, filename, buf);
+ exit(2);
+ }
+#else
+ f = fopen(filename, mode);
if (f == NULL)
{
fprintf(stderr, "%s: unable to open %s: %s\n",
- whoami, filename, strerror(errno)); /* XXXX */
+ whoami, filename, strerror(errno));
exit(2);
}
+#endif
return f;
}