瀏覽代碼

LibRegex: Limit the number of nested capture groups allowed in BRE

Found by OSS-Fuzz: https://oss-fuzz.com/testcase?key=4869334212673536
Ali Mohammad Pur 3 年之前
父節點
當前提交
05c65f9b5d
共有 2 個文件被更改,包括 7 次插入0 次删除
  1. 6 0
      Userland/Libraries/LibRegex/RegexParser.cpp
  2. 1 0
      Userland/Libraries/LibRegex/RegexParser.h

+ 6 - 0
Userland/Libraries/LibRegex/RegexParser.cpp

@@ -12,6 +12,7 @@
 #include <AK/String.h>
 #include <AK/String.h>
 #include <AK/StringBuilder.h>
 #include <AK/StringBuilder.h>
 #include <AK/StringUtils.h>
 #include <AK/StringUtils.h>
+#include <AK/TemporaryChange.h>
 #include <AK/Utf16View.h>
 #include <AK/Utf16View.h>
 #include <LibUnicode/CharacterTypes.h>
 #include <LibUnicode/CharacterTypes.h>
 
 
@@ -460,6 +461,11 @@ bool PosixBasicParser::parse_nonduplicating_re(ByteCode& bytecode, size_t& match
 {
 {
     // nondupl_RE : one_char_or_coll_elem_RE | Back_open_paren RE_expression Back_close_paren | BACKREF
     // nondupl_RE : one_char_or_coll_elem_RE | Back_open_paren RE_expression Back_close_paren | BACKREF
     if (try_skip("\\(")) {
     if (try_skip("\\(")) {
+        TemporaryChange change { m_current_capture_group_depth, m_current_capture_group_depth + 1 };
+        // Max number of addressable capture groups is 10, let's just be lenient
+        // and accept 20; anything past that is probably a silly pattern anyway.
+        if (m_current_capture_group_depth > 20)
+            return set_error(Error::InvalidPattern);
         ByteCode capture_bytecode;
         ByteCode capture_bytecode;
         size_t capture_length_minimum = 0;
         size_t capture_length_minimum = 0;
         auto capture_group_index = ++m_parser_state.capture_groups_count;
         auto capture_group_index = ++m_parser_state.capture_groups_count;

+ 1 - 0
Userland/Libraries/LibRegex/RegexParser.h

@@ -166,6 +166,7 @@ private:
     constexpr static size_t number_of_addressable_capture_groups = 9;
     constexpr static size_t number_of_addressable_capture_groups = 9;
     size_t m_capture_group_minimum_lengths[number_of_addressable_capture_groups] { 0 };
     size_t m_capture_group_minimum_lengths[number_of_addressable_capture_groups] { 0 };
     bool m_capture_group_seen[number_of_addressable_capture_groups] { false };
     bool m_capture_group_seen[number_of_addressable_capture_groups] { false };
+    size_t m_current_capture_group_depth { 0 };
 };
 };
 
 
 class PosixExtendedParser final : public AbstractPosixParser {
 class PosixExtendedParser final : public AbstractPosixParser {