Favor strerror_s and fopen_s on MSVC

Make remaining calls to fopen and strerror use strerror_s and fopen_s
on MSVC.
This commit is contained in:
Jay Berkenbilt 2013-02-28 17:10:30 -05:00
parent ac4deac187
commit fd64959398
3 changed files with 48 additions and 5 deletions

View File

@ -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.

View File

@ -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*

View File

@ -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;
}