[v4,03/15] Escape names used in symbol whitelisting regex.
Commit Message
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 <gprocida@google.com>
---
include/abg-regex.h | 10 ++++++++++
src/abg-regex.cc | 28 ++++++++++++++++++++++++++--
2 files changed, 36 insertions(+), 2 deletions(-)
Comments
On Mon, May 04, 2020 at 01:34:04PM +0100, Giuliano Procida wrote:
>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 <gprocida@google.com>
>---
> 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<std::string>& 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 <sstream>
>+#include <ostream>
Sort.
>
> #include "abg-regex.h"
> #include "abg-sptr-utils.h"
>@@ -57,6 +58,29 @@ sptr_utils::build_sptr<regex_t>()
> 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 = "^.[]$()|*+?{}\\";
Could sort the characters e.g. "[](){}^$.*+?|\\"
>+ const std::string str = esc.ref;
const std::string&
Besides the above
Reviewed-by: Matthias Maennich <maennich@google.com>
Cheers,
Matthias
>+ 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<std::string>& strs)
> return "^_^";
> std::ostringstream os;
> std::vector<std::string>::const_iterator i = strs.begin();
>- os << "^(" << *i++;
>+ os << "^(" << escape(*i++);
> while (i != strs.end())
>- os << "|" << *i++;
>+ os << "|" << escape(*i++);
> os << ")$";
> return os.str();
> }
>--
>2.26.2.526.g744177e7f7-goog
>
@@ -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<std::string>& strs);
@@ -24,6 +24,7 @@
///
#include <sstream>
+#include <ostream>
#include "abg-regex.h"
#include "abg-sptr-utils.h"
@@ -57,6 +58,29 @@ sptr_utils::build_sptr<regex_t>()
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<std::string>& strs)
return "^_^";
std::ostringstream os;
std::vector<std::string>::const_iterator i = strs.begin();
- os << "^(" << *i++;
+ os << "^(" << escape(*i++);
while (i != strs.end())
- os << "|" << *i++;
+ os << "|" << escape(*i++);
os << ")$";
return os.str();
}