Commit af91b5b5841aaa34ebf2d2062041c874425f474f
1 parent
ac0060ac
Add QUtil::file_can_be_opened
Showing
5 changed files
with
29 additions
and
18 deletions
ChangeLog
include/qpdf/QUtil.hh
| @@ -111,6 +111,10 @@ namespace QUtil | @@ -111,6 +111,10 @@ namespace QUtil | ||
| 111 | QPDF_DLL | 111 | QPDF_DLL |
| 112 | FILE* fopen_wrapper(std::string const&, FILE*); | 112 | FILE* fopen_wrapper(std::string const&, FILE*); |
| 113 | 113 | ||
| 114 | + // Attempt to open the file read only and then close again | ||
| 115 | + QPDF_DLL | ||
| 116 | + bool file_can_be_opened(char const* filename); | ||
| 117 | + | ||
| 114 | // Wrap around off_t versions of fseek and ftell if available | 118 | // Wrap around off_t versions of fseek and ftell if available |
| 115 | QPDF_DLL | 119 | QPDF_DLL |
| 116 | int seek(FILE* stream, qpdf_offset_t offset, int whence); | 120 | int seek(FILE* stream, qpdf_offset_t offset, int whence); |
libqpdf/QUtil.cc
| @@ -515,6 +515,21 @@ QUtil::fopen_wrapper(std::string const& description, FILE* f) | @@ -515,6 +515,21 @@ QUtil::fopen_wrapper(std::string const& description, FILE* f) | ||
| 515 | return f; | 515 | return f; |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | +bool | ||
| 519 | +QUtil::file_can_be_opened(char const* filename) | ||
| 520 | +{ | ||
| 521 | + try | ||
| 522 | + { | ||
| 523 | + fclose(safe_fopen(filename, "rb")); | ||
| 524 | + return true; | ||
| 525 | + } | ||
| 526 | + catch (std::runtime_error&) | ||
| 527 | + { | ||
| 528 | + // can't open the file | ||
| 529 | + } | ||
| 530 | + return false; | ||
| 531 | +} | ||
| 532 | + | ||
| 518 | int | 533 | int |
| 519 | QUtil::seek(FILE* stream, qpdf_offset_t offset, int whence) | 534 | QUtil::seek(FILE* stream, qpdf_offset_t offset, int whence) |
| 520 | { | 535 | { |
libtests/qutil.cc
| @@ -203,6 +203,9 @@ void fopen_wrapper_test() | @@ -203,6 +203,9 @@ void fopen_wrapper_test() | ||
| 203 | std::cout << "exception: " << s.what() << std::endl; | 203 | std::cout << "exception: " << s.what() << std::endl; |
| 204 | assert(s.getErrno() != 0); | 204 | assert(s.getErrno() != 0); |
| 205 | } | 205 | } |
| 206 | + | ||
| 207 | + assert(QUtil::file_can_be_opened("qutil.out")); | ||
| 208 | + assert(! QUtil::file_can_be_opened("/does/not/exist")); | ||
| 206 | } | 209 | } |
| 207 | 210 | ||
| 208 | void getenv_test() | 211 | void getenv_test() |
qpdf/qpdf.cc
| @@ -740,21 +740,6 @@ static void parse_object_id(std::string const& objspec, | @@ -740,21 +740,6 @@ static void parse_object_id(std::string const& objspec, | ||
| 740 | } | 740 | } |
| 741 | } | 741 | } |
| 742 | 742 | ||
| 743 | -static bool file_exists(char const* filename) | ||
| 744 | -{ | ||
| 745 | - try | ||
| 746 | - { | ||
| 747 | - fclose(QUtil::safe_fopen(filename, "rb")); | ||
| 748 | - return true; | ||
| 749 | - } | ||
| 750 | - catch (std::runtime_error&) | ||
| 751 | - { | ||
| 752 | - // can't open the file | ||
| 753 | - } | ||
| 754 | - return false; | ||
| 755 | -} | ||
| 756 | - | ||
| 757 | - | ||
| 758 | // This is not a general-purpose argument parser. It is tightly | 743 | // This is not a general-purpose argument parser. It is tightly |
| 759 | // crafted to work with qpdf. qpdf's command-line syntax is very | 744 | // crafted to work with qpdf. qpdf's command-line syntax is very |
| 760 | // complex because of its long history, and it doesn't really follow | 745 | // complex because of its long history, and it doesn't really follow |
| @@ -2976,7 +2961,7 @@ ArgParser::handleArgFileArguments() | @@ -2976,7 +2961,7 @@ ArgParser::handleArgFileArguments() | ||
| 2976 | argfile = 1 + argv[i]; | 2961 | argfile = 1 + argv[i]; |
| 2977 | if (strcmp(argfile, "-") != 0) | 2962 | if (strcmp(argfile, "-") != 0) |
| 2978 | { | 2963 | { |
| 2979 | - if (! file_exists(argfile)) | 2964 | + if (! QUtil::file_can_be_opened(argfile)) |
| 2980 | { | 2965 | { |
| 2981 | // The file's not there; treating as regular option | 2966 | // The file's not there; treating as regular option |
| 2982 | argfile = nullptr; | 2967 | argfile = nullptr; |
| @@ -3276,7 +3261,7 @@ ArgParser::parsePagesOptions() | @@ -3276,7 +3261,7 @@ ArgParser::parsePagesOptions() | ||
| 3276 | char const* file = argv[cur_arg++]; | 3261 | char const* file = argv[cur_arg++]; |
| 3277 | char const* password = 0; | 3262 | char const* password = 0; |
| 3278 | char const* range = argv[cur_arg++]; | 3263 | char const* range = argv[cur_arg++]; |
| 3279 | - if (! file_exists(file)) | 3264 | + if (! QUtil::file_can_be_opened(file)) |
| 3280 | { | 3265 | { |
| 3281 | check_unclosed(file, 0); | 3266 | check_unclosed(file, 0); |
| 3282 | } | 3267 | } |
| @@ -3315,7 +3300,7 @@ ArgParser::parsePagesOptions() | @@ -3315,7 +3300,7 @@ ArgParser::parsePagesOptions() | ||
| 3315 | // "." means the input file. | 3300 | // "." means the input file. |
| 3316 | QTC::TC("qpdf", "qpdf pages range omitted with ."); | 3301 | QTC::TC("qpdf", "qpdf pages range omitted with ."); |
| 3317 | } | 3302 | } |
| 3318 | - else if (file_exists(range)) | 3303 | + else if (QUtil::file_can_be_opened(range)) |
| 3319 | { | 3304 | { |
| 3320 | QTC::TC("qpdf", "qpdf pages range omitted in middle"); | 3305 | QTC::TC("qpdf", "qpdf pages range omitted in middle"); |
| 3321 | // Yup, it's a file. | 3306 | // Yup, it's a file. |