Commit fd649593983925356fcc61c04a75c9f55cee3648

Authored by Jay Berkenbilt
1 parent ac4deac1

Favor strerror_s and fopen_s on MSVC

Make remaining calls to fopen and strerror use strerror_s and fopen_s
on MSVC.
ChangeLog
1 1 2013-02-28 Jay Berkenbilt <ejb@ql.org>
2 2  
  3 + * Favor fopen_s and strerror_s on MSVC to avoid CRT security
  4 + warnings. This is useful for people who may want to use qpdf in
  5 + an application that is Windows 8 certified.
  6 +
3 7 * New method QUtil::safe_fopen to wrap calls to fopen. This is
4 8 less cumbersome than calling QUtil::fopen_wrapper.
5 9  
... ...
libqpdf/QUtil.cc
... ... @@ -96,7 +96,22 @@ QUtil::unsigned_char_pointer(char const* str)
96 96 void
97 97 QUtil::throw_system_error(std::string const& description)
98 98 {
99   - throw std::runtime_error(description + ": " + strerror(errno)); // XXXX
  99 +#ifdef _MSC_VER
  100 + // "94" is mentioned in the MSVC docs, but it's still safe if the
  101 + // message is longer. strerror_s is a templated function that
  102 + // knows the size of buf and truncates.
  103 + char buf[94];
  104 + if (strerror_s(buf, errno) != 0)
  105 + {
  106 + throw std::runtime_error(description + ": failed with an unknown error");
  107 + }
  108 + else
  109 + {
  110 + throw std::runtime_error(description + ": " + buf);
  111 + }
  112 +#else
  113 + throw std::runtime_error(description + ": " + strerror(errno));
  114 +#endif
100 115 }
101 116  
102 117 int
... ... @@ -112,8 +127,18 @@ QUtil::os_wrapper(std::string const&amp; description, int status)
112 127 FILE*
113 128 QUtil::safe_fopen(char const* filename, char const* mode)
114 129 {
115   - return fopen_wrapper(std::string("open ") + filename,
116   - fopen(filename, mode)); // XXXX
  130 + FILE* f = 0;
  131 +#ifdef _MSC_VER
  132 + errno_t err = fopen_s(&f, filename, mode);
  133 + if (err != 0)
  134 + {
  135 + errno = err;
  136 + throw_system_error(std::string("open ") + filename);
  137 + }
  138 +#else
  139 + f = fopen_wrapper(std::string("open ") + filename, fopen(filename, mode));
  140 +#endif
  141 + return f;
117 142 }
118 143  
119 144 FILE*
... ...
qpdf/qpdf-ctest.c
... ... @@ -10,13 +10,27 @@ static qpdf_data qpdf = 0;
10 10  
11 11 static FILE* safe_fopen(char const* filename, char const* mode)
12 12 {
13   - FILE* f = fopen(filename, mode); /* XXXX */
  13 + // This function is basically a "C" port of QUtil::safe_fopen.
  14 + FILE* f = 0;
  15 +#ifdef _MSC_VER
  16 + errno_t err = fopen_s(&f, filename, mode);
  17 + if (err != 0)
  18 + {
  19 + char buf[94];
  20 + strerror_s(buf, sizeof(buf), errno);
  21 + fprintf(stderr, "%s: unable to open %s: %s\n",
  22 + whoami, filename, buf);
  23 + exit(2);
  24 + }
  25 +#else
  26 + f = fopen(filename, mode);
14 27 if (f == NULL)
15 28 {
16 29 fprintf(stderr, "%s: unable to open %s: %s\n",
17   - whoami, filename, strerror(errno)); /* XXXX */
  30 + whoami, filename, strerror(errno));
18 31 exit(2);
19 32 }
  33 +#endif
20 34 return f;
21 35 }
22 36  
... ...