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