From d7fc7bcf9f306e093a955caee5edd6cf3c2e1232 Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Sun, 5 May 2019 17:41:33 +0300 Subject: [PATCH] commitlog: descriptor: skip leading path from filename std::regex_match of the leading path may run out of stack with long paths in debug build. Using rfind instead to lookup the last '/' in in pathname and skip it if found. Fixes #4464 Signed-off-by: Benny Halevy Message-Id: <20190505144133.4333-1-bhalevy@scylladb.com> (cherry picked from commit d9136f96f3909112cf3aa374dcb473a80f7a9140) --- db/commitlog/commitlog.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/db/commitlog/commitlog.cc b/db/commitlog/commitlog.cc index 737631c3be..8c0d49a8d4 100644 --- a/db/commitlog/commitlog.cc +++ b/db/commitlog/commitlog.cc @@ -148,9 +148,18 @@ db::commitlog::descriptor::descriptor(const sstring& filename, const std::string : descriptor([&filename, &fname_prefix]() { std::smatch m; // match both legacy and new version of commitlogs Ex: CommitLog-12345.log and CommitLog-4-12345.log. - std::regex rx("(?:.*/)?(?:Recycled-)?" + fname_prefix + "((\\d+)(" + SEPARATOR + "\\d+)?)" + FILENAME_EXTENSION); + std::regex rx("(?:Recycled-)?" + fname_prefix + "((\\d+)(" + SEPARATOR + "\\d+)?)" + FILENAME_EXTENSION); std::string sfilename = filename; - if (!std::regex_match(sfilename, m, rx)) { + auto cbegin = sfilename.cbegin(); + // skip the leading path + // Note: we're using rfind rather than the regex above + // since it may run out of stack in debug builds. + // See https://github.com/scylladb/scylla/issues/4464 + auto pos = std::string(filename).rfind('/'); + if (pos != std::string::npos) { + cbegin += pos + 1; + } + if (!std::regex_match(cbegin, sfilename.cend(), m, rx)) { throw std::domain_error("Cannot parse the version of the file: " + filename); } if (m[3].length() == 0) {