diff --git a/app/app_utils.cpp b/app/app_utils.cpp index d36694b2d1..05d6a87d2c 100644 --- a/app/app_utils.cpp +++ b/app/app_utils.cpp @@ -4,6 +4,13 @@ #include #include #include +#include "error.hpp" +#include "futils.hpp" + +#if __has_include() +#include // for getrlimit() +#define HAS_GETRLIMIT +#endif namespace Util { bool strtol(const char* nptr, int64_t& n) { @@ -24,4 +31,31 @@ bool strtol(const char* nptr, int64_t& n) { return true; } +void increase_stack_limit() { + using namespace Exiv2; +#ifdef HAS_GETRLIMIT + { + struct rlimit rl {}; + + if (getrlimit(RLIMIT_STACK, &rl) < 0) { +#ifndef SUPPRESS_WARNINGS + EXV_WARNING << "getrlimit(RLIMIT_STACK) failed: " << strError() << "\n"; +#endif + return; + } + if (rl.rlim_cur < rl.rlim_max) { + // Increase it to the max allowed. + rl.rlim_cur = rl.rlim_max; + if (setrlimit(RLIMIT_STACK, &rl) < 0) { +#ifndef SUPPRESS_WARNINGS + EXV_WARNING << "setrlimit(RLIMIT_STACK) failed: " << strError() << "\n"; +#endif + return; + } + } + return; + } +#endif +} + } // namespace Util diff --git a/app/app_utils.hpp b/app/app_utils.hpp index 2731f52de9..73cce64a54 100644 --- a/app/app_utils.hpp +++ b/app/app_utils.hpp @@ -12,6 +12,13 @@ namespace Util { n is not modified if the conversion is unsuccessful. See strtol(2). */ bool strtol(const char* nptr, int64_t& n); + +/*! + @brief This raises the default stack size limit so that deeply nested + files won't cause a crash. On Linux, the default stack size is + often only 8192KB, which is very easy to hit. + */ +void increase_stack_limit(); } // namespace Util #endif // APP_UTILS_HPP_ diff --git a/app/exiv2.cpp b/app/exiv2.cpp index d37bf69cfb..354fe923a3 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -119,6 +119,7 @@ std::string parseEscapes(const std::string& input); // Main int main(int argc, char* const argv[]) { setlocale(LC_CTYPE, ".utf8"); + Util::increase_stack_limit(); Exiv2::XmpParser::initialize(); ::atexit(Exiv2::XmpParser::terminate);