diff options
author | Zher Huei Lee <lee.zh.92@gmail.com> | 2016-10-24 22:13:26 +0100 |
---|---|---|
committer | Zher Huei Lee <lee.zh.92@gmail.com> | 2016-10-27 10:27:40 +0100 |
commit | c3b4686082bc92c70886ee848064009c8f628193 (patch) | |
tree | f467034c98a7a8c91de7d09e41274555ce60fd4e /modules | |
parent | 439d43932133d32dcabd482f11842072d52b41e1 (diff) |
Added global sub and bounds checking to RegEx
Diffstat (limited to 'modules')
-rw-r--r-- | modules/regex/regex.cpp | 57 | ||||
-rw-r--r-- | modules/regex/regex.h | 2 |
2 files changed, 46 insertions, 13 deletions
diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp index 8f26d764c4..388e6dfdec 100644 --- a/modules/regex/regex.cpp +++ b/modules/regex/regex.cpp @@ -1340,6 +1340,12 @@ Error RegEx::compile(const String& p_pattern) { Ref<RegExMatch> RegEx::search(const String& p_text, int p_start, int p_end) const { + ERR_FAIL_COND_V(!is_valid(), NULL); + ERR_FAIL_COND_V(p_start < 0, NULL); + ERR_FAIL_COND_V(p_start >= p_text.length(), NULL); + ERR_FAIL_COND_V(p_end > p_text.length(), NULL); + ERR_FAIL_COND_V(p_end != -1 && p_end < p_start, NULL); + Ref<RegExMatch> res = memnew(RegExMatch()); for (int i = 0; i < group_names.size(); ++i) { @@ -1350,7 +1356,7 @@ Ref<RegExMatch> RegEx::search(const String& p_text, int p_start, int p_end) cons res->string = p_text; - if (p_end < p_start || p_end > p_text.length()) + if (p_end == -1) p_end = p_text.length(); RegExSearch s(res, p_end, lookahead_depth); @@ -1369,18 +1375,45 @@ Ref<RegExMatch> RegEx::search(const String& p_text, int p_start, int p_end) cons return NULL; } -String RegEx::sub(const String& p_text, const String& p_template, int p_start, int p_end) const { +String RegEx::sub(const String& p_text, const String& p_replacement, bool p_all, int p_start, int p_end) const { - Ref<RegExMatch> m = search(p_text, p_start, p_end); - RegExMatch::Group& s = m->captures[0]; - if (s.start >= 0) { - String res = p_text.substr(0, s.start) + m->expand(p_template); - int end = s.start + s.length; - if (end < p_text.length()) - res += p_text.substr(end, p_text.length() - end); - return res; + ERR_FAIL_COND_V(!is_valid(), p_text); + ERR_FAIL_COND_V(p_start < 0, p_text); + ERR_FAIL_COND_V(p_start >= p_text.length(), p_text); + ERR_FAIL_COND_V(p_end > p_text.length(), p_text); + ERR_FAIL_COND_V(p_end != -1 && p_end < p_start, p_text); + + String text = p_text; + int start = p_start; + + if (p_end == -1) + p_end = p_text.length(); + + while (start < text.length() && (p_all || start == p_start)) { + + Ref<RegExMatch> m = search(text, start, p_end); + + RegExMatch::Group& s = m->captures[0]; + + if (s.start < 0) + break; + + String res = text.substr(0, s.start) + m->expand(p_replacement); + + start = res.length(); + + if (s.length == 0) + ++start; + + int sub_end = s.start + s.length; + if (sub_end < text.length()) + res += text.substr(sub_end, text.length() - sub_end); + + p_end += res.length() - text.length(); + + text = res; } - return p_text; + return text; } void RegEx::clear() { @@ -1456,7 +1489,7 @@ void RegEx::_bind_methods() { ObjectTypeDB::bind_method(_MD("clear"),&RegEx::clear); ObjectTypeDB::bind_method(_MD("compile","pattern"),&RegEx::compile); ObjectTypeDB::bind_method(_MD("search","text","start","end"),&RegEx::search, DEFVAL(0), DEFVAL(-1)); - ObjectTypeDB::bind_method(_MD("sub","text","template","start","end"),&RegEx::sub, DEFVAL(0), DEFVAL(-1)); + ObjectTypeDB::bind_method(_MD("sub","text","replacement","all","start","end"),&RegEx::sub, DEFVAL(false), DEFVAL(0), DEFVAL(-1)); ObjectTypeDB::bind_method(_MD("is_valid"),&RegEx::is_valid); ObjectTypeDB::bind_method(_MD("get_pattern"),&RegEx::get_pattern); ObjectTypeDB::bind_method(_MD("get_group_count"),&RegEx::get_group_count); diff --git a/modules/regex/regex.h b/modules/regex/regex.h index 283368c34f..8d31b84773 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -97,7 +97,7 @@ public: Error compile(const String& p_pattern); Ref<RegExMatch> search(const String& p_text, int p_start = 0, int p_end = -1) const; - String sub(const String& p_text, const String& p_template, int p_start = 0, int p_end = -1) const; + String sub(const String& p_text, const String& p_replacement, bool p_all = false, int p_start = 0, int p_end = -1) const; bool is_valid() const; String get_pattern() const; |