Commit fd649593983925356fcc61c04a75c9f55cee3648
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.
Showing
3 changed files
with
48 additions
and
5 deletions
ChangeLog
| 1 | 2013-02-28 Jay Berkenbilt <ejb@ql.org> | 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 | * New method QUtil::safe_fopen to wrap calls to fopen. This is | 7 | * New method QUtil::safe_fopen to wrap calls to fopen. This is |
| 4 | less cumbersome than calling QUtil::fopen_wrapper. | 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,7 +96,22 @@ QUtil::unsigned_char_pointer(char const* str) | ||
| 96 | void | 96 | void |
| 97 | QUtil::throw_system_error(std::string const& description) | 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 | int | 117 | int |
| @@ -112,8 +127,18 @@ QUtil::os_wrapper(std::string const& description, int status) | @@ -112,8 +127,18 @@ QUtil::os_wrapper(std::string const& description, int status) | ||
| 112 | FILE* | 127 | FILE* |
| 113 | QUtil::safe_fopen(char const* filename, char const* mode) | 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 | FILE* | 144 | FILE* |
qpdf/qpdf-ctest.c
| @@ -10,13 +10,27 @@ static qpdf_data qpdf = 0; | @@ -10,13 +10,27 @@ static qpdf_data qpdf = 0; | ||
| 10 | 10 | ||
| 11 | static FILE* safe_fopen(char const* filename, char const* mode) | 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 | if (f == NULL) | 27 | if (f == NULL) |
| 15 | { | 28 | { |
| 16 | fprintf(stderr, "%s: unable to open %s: %s\n", | 29 | fprintf(stderr, "%s: unable to open %s: %s\n", |
| 17 | - whoami, filename, strerror(errno)); /* XXXX */ | 30 | + whoami, filename, strerror(errno)); |
| 18 | exit(2); | 31 | exit(2); |
| 19 | } | 32 | } |
| 33 | +#endif | ||
| 20 | return f; | 34 | return f; |
| 21 | } | 35 | } |
| 22 | 36 |