From patchwork Mon May 4 12:34:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Giuliano Procida X-Patchwork-Id: 39203 From: gprocida@google.com (Giuliano Procida) Date: Mon, 4 May 2020 13:34:04 +0100 Subject: [PATCH v4 03/15] Escape names used in symbol whitelisting regex. In-Reply-To: <20200504123416.243214-1-gprocida@google.com> References: <20200424092132.150547-1-gprocida@google.com> <20200504123416.243214-1-gprocida@google.com> Message-ID: <20200504123416.243214-4-gprocida@google.com> There is the theoretical possibility that symbols may contain special regex characters like '.' and '$'. This patch ensures all such characters in symbol names are escaped before they are added to the whitelisting regex. * include/regex.h (escape): New string reference holder class. (operator<<): Declaration of std::ostream, regex::escape overload. * include/regex.cc (operator<<): New std::ostream, regex::escape overload that outputs regex-escaped strings. * src/abg-tools-utils.cc (gen_suppr_spec_from_kernel_abi_whitelists): Make sure any special regex characters in symbol names are escaped. Signed-off-by: Giuliano Procida Reviewed-by: Matthias Maennich --- include/abg-regex.h | 10 ++++++++++ src/abg-regex.cc | 28 ++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/include/abg-regex.h b/include/abg-regex.h index d39ada46..164083cc 100644 --- a/include/abg-regex.h +++ b/include/abg-regex.h @@ -58,6 +58,16 @@ struct regex_t_deleter } };//end struct regex_deleter +/// A class to hold a reference to a string to regex escape. +struct escape +{ + escape(const std::string& str) : ref(str) { } + const std::string& ref; +}; + +std::ostream& +operator<<(std::ostream& os, const escape& esc); + std::string generate_from_strings(const std::vector& strs); diff --git a/src/abg-regex.cc b/src/abg-regex.cc index 0451d111..a12ecc88 100644 --- a/src/abg-regex.cc +++ b/src/abg-regex.cc @@ -24,6 +24,7 @@ /// #include +#include #include "abg-regex.h" #include "abg-sptr-utils.h" @@ -57,6 +58,29 @@ sptr_utils::build_sptr() namespace regex { +/// Escape regex special charaters in input string. +/// +/// @param os the output stream being written to. +/// +/// @param esc the regex_escape object holding a reference to the string +/// needing to be escaped. +/// +/// @return the output stream. +std::ostream& +operator<<(std::ostream& os, const escape& esc) +{ + // ']' and '}' are only conditionally special, so could be removed. + static const std::string specials = "^.[]$()|*+?{}\\"; + const std::string str = esc.ref; + for (std::string::const_iterator i = str.begin(); i != str.end(); ++i) + { + if (specials.find(*i) != std::string::npos) + os << '\\'; + os << *i; + } + return os; +} + /// Generate a regex pattern equivalent to testing set membership. /// /// A string will match the resulting pattern regex, if and only if it @@ -73,9 +97,9 @@ generate_from_strings(const std::vector& strs) return "^_^"; std::ostringstream os; std::vector::const_iterator i = strs.begin(); - os << "^(" << *i++; + os << "^(" << escape(*i++); while (i != strs.end()) - os << "|" << *i++; + os << "|" << escape(*i++); os << ")$"; return os.str(); }