diff options
author | Jay Berkenbilt <ejb@ql.org> | 2013-02-28 23:10:30 +0100 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2013-03-05 19:35:46 +0100 |
commit | fd649593983925356fcc61c04a75c9f55cee3648 (patch) | |
tree | 7a79631772422d1808872e50e21eb4178e2eddeb | |
parent | ac4deac1873ca1bb570ffd479ed2cc1010762f89 (diff) | |
download | qpdf-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-- | ChangeLog | 4 | ||||
-rw-r--r-- | libqpdf/QUtil.cc | 31 | ||||
-rw-r--r-- | qpdf/qpdf-ctest.c | 18 |
3 files changed, 48 insertions, 5 deletions
@@ -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; } |