Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(342)

Side by Side Diff: src/ast.h

Issue 7170014: Avoid OOM on regexps with nested quantifiers. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ast.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1745 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 #define MAKE_CASE(Name) \ 1756 #define MAKE_CASE(Name) \
1757 virtual void* Visit##Name(RegExp##Name*, void* data) = 0; 1757 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
1758 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) 1758 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
1759 #undef MAKE_CASE 1759 #undef MAKE_CASE
1760 }; 1760 };
1761 1761
1762 1762
1763 class RegExpTree: public ZoneObject { 1763 class RegExpTree: public ZoneObject {
1764 public: 1764 public:
1765 static const int kInfinity = kMaxInt; 1765 static const int kInfinity = kMaxInt;
1766 RegExpTree() : contains_expanded_quantifier_(false) { }
1766 virtual ~RegExpTree() { } 1767 virtual ~RegExpTree() { }
1767 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0; 1768 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1768 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1769 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1769 RegExpNode* on_success) = 0; 1770 RegExpNode* on_success) = 0;
1770 virtual bool IsTextElement() { return false; } 1771 virtual bool IsTextElement() { return false; }
1771 virtual bool IsAnchoredAtStart() { return false; } 1772 virtual bool IsAnchoredAtStart() { return false; }
1772 virtual bool IsAnchoredAtEnd() { return false; } 1773 virtual bool IsAnchoredAtEnd() { return false; }
1773 virtual int min_match() = 0; 1774 virtual int min_match() = 0;
1774 virtual int max_match() = 0; 1775 virtual int max_match() = 0;
1776 virtual bool ContainsExpandedQuantifier() {
1777 return contains_expanded_quantifier_;
1778 }
1779 void set_contains_expanded_quantifier(bool value) {
1780 contains_expanded_quantifier_ = value;
1781 }
1775 // Returns the interval of registers used for captures within this 1782 // Returns the interval of registers used for captures within this
1776 // expression. 1783 // expression.
1777 virtual Interval CaptureRegisters() { return Interval::Empty(); } 1784 virtual Interval CaptureRegisters() { return Interval::Empty(); }
1778 virtual void AppendToText(RegExpText* text); 1785 virtual void AppendToText(RegExpText* text);
1779 SmartPointer<const char> ToString(); 1786 SmartPointer<const char> ToString();
1780 #define MAKE_ASTYPE(Name) \ 1787 #define MAKE_ASTYPE(Name) \
1781 virtual RegExp##Name* As##Name(); \ 1788 virtual RegExp##Name* As##Name(); \
1782 virtual bool Is##Name(); 1789 virtual bool Is##Name();
1783 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE) 1790 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
1784 #undef MAKE_ASTYPE 1791 #undef MAKE_ASTYPE
1792
1793 protected:
1794 bool contains_expanded_quantifier_;
1785 }; 1795 };
1786 1796
1787 1797
1788 class RegExpDisjunction: public RegExpTree { 1798 class RegExpDisjunction: public RegExpTree {
1789 public: 1799 public:
1790 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives); 1800 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
1791 virtual void* Accept(RegExpVisitor* visitor, void* data); 1801 virtual void* Accept(RegExpVisitor* visitor, void* data);
1792 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1802 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1793 RegExpNode* on_success); 1803 RegExpNode* on_success);
1794 virtual RegExpDisjunction* AsDisjunction(); 1804 virtual RegExpDisjunction* AsDisjunction();
1795 virtual Interval CaptureRegisters(); 1805 virtual Interval CaptureRegisters();
1796 virtual bool IsDisjunction(); 1806 virtual bool IsDisjunction();
1797 virtual bool IsAnchoredAtStart(); 1807 virtual bool IsAnchoredAtStart();
1798 virtual bool IsAnchoredAtEnd(); 1808 virtual bool IsAnchoredAtEnd();
1799 virtual int min_match() { return min_match_; } 1809 virtual int min_match() { return min_match_; }
1800 virtual int max_match() { return max_match_; } 1810 virtual int max_match() { return max_match_; }
1811 virtual bool ContainsExpandedQuantifier();
1801 ZoneList<RegExpTree*>* alternatives() { return alternatives_; } 1812 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
1802 private: 1813 private:
1803 ZoneList<RegExpTree*>* alternatives_; 1814 ZoneList<RegExpTree*>* alternatives_;
1804 int min_match_; 1815 int min_match_;
1805 int max_match_; 1816 int max_match_;
1806 }; 1817 };
1807 1818
1808 1819
1809 class RegExpAlternative: public RegExpTree { 1820 class RegExpAlternative: public RegExpTree {
1810 public: 1821 public:
1811 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes); 1822 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
1812 virtual void* Accept(RegExpVisitor* visitor, void* data); 1823 virtual void* Accept(RegExpVisitor* visitor, void* data);
1813 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1824 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1814 RegExpNode* on_success); 1825 RegExpNode* on_success);
1815 virtual RegExpAlternative* AsAlternative(); 1826 virtual RegExpAlternative* AsAlternative();
1816 virtual Interval CaptureRegisters(); 1827 virtual Interval CaptureRegisters();
1817 virtual bool IsAlternative(); 1828 virtual bool IsAlternative();
1818 virtual bool IsAnchoredAtStart(); 1829 virtual bool IsAnchoredAtStart();
1819 virtual bool IsAnchoredAtEnd(); 1830 virtual bool IsAnchoredAtEnd();
1820 virtual int min_match() { return min_match_; } 1831 virtual int min_match() { return min_match_; }
1821 virtual int max_match() { return max_match_; } 1832 virtual int max_match() { return max_match_; }
1833 virtual bool ContainsExpandedQuantifier();
1822 ZoneList<RegExpTree*>* nodes() { return nodes_; } 1834 ZoneList<RegExpTree*>* nodes() { return nodes_; }
1823 private: 1835 private:
1824 ZoneList<RegExpTree*>* nodes_; 1836 ZoneList<RegExpTree*>* nodes_;
1825 int min_match_; 1837 int min_match_;
1826 int max_match_; 1838 int max_match_;
1827 }; 1839 };
1828 1840
1829 1841
1830 class RegExpAssertion: public RegExpTree { 1842 class RegExpAssertion: public RegExpTree {
1831 public: 1843 public:
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1961 1973
1962 1974
1963 class RegExpQuantifier: public RegExpTree { 1975 class RegExpQuantifier: public RegExpTree {
1964 public: 1976 public:
1965 enum Type { GREEDY, NON_GREEDY, POSSESSIVE }; 1977 enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
1966 RegExpQuantifier(int min, int max, Type type, RegExpTree* body) 1978 RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
1967 : body_(body), 1979 : body_(body),
1968 min_(min), 1980 min_(min),
1969 max_(max), 1981 max_(max),
1970 min_match_(min * body->min_match()), 1982 min_match_(min * body->min_match()),
1971 type_(type) { 1983 type_(type),
1984 contains_expanded_quantifier_(false) {
1972 if (max > 0 && body->max_match() > kInfinity / max) { 1985 if (max > 0 && body->max_match() > kInfinity / max) {
1973 max_match_ = kInfinity; 1986 max_match_ = kInfinity;
1974 } else { 1987 } else {
1975 max_match_ = max * body->max_match(); 1988 max_match_ = max * body->max_match();
1976 } 1989 }
1977 } 1990 }
1978 virtual void* Accept(RegExpVisitor* visitor, void* data); 1991 virtual void* Accept(RegExpVisitor* visitor, void* data);
1979 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 1992 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1980 RegExpNode* on_success); 1993 RegExpNode* on_success);
1981 static RegExpNode* ToNode(int min, 1994 static RegExpNode* ToNode(int min,
1982 int max, 1995 int max,
1983 bool is_greedy, 1996 bool is_greedy,
1984 RegExpTree* body, 1997 RegExpTree* body,
1985 RegExpCompiler* compiler, 1998 RegExpCompiler* compiler,
1986 RegExpNode* on_success, 1999 RegExpNode* on_success,
1987 bool not_at_start = false); 2000 bool not_at_start = false);
1988 virtual RegExpQuantifier* AsQuantifier(); 2001 virtual RegExpQuantifier* AsQuantifier();
1989 virtual Interval CaptureRegisters(); 2002 virtual Interval CaptureRegisters();
1990 virtual bool IsQuantifier(); 2003 virtual bool IsQuantifier();
1991 virtual int min_match() { return min_match_; } 2004 virtual int min_match() { return min_match_; }
1992 virtual int max_match() { return max_match_; } 2005 virtual int max_match() { return max_match_; }
2006 virtual bool ContainsExpandedQuantifier() {
2007 return contains_expanded_quantifier_ || body_->ContainsExpandedQuantifier();
2008 }
1993 int min() { return min_; } 2009 int min() { return min_; }
1994 int max() { return max_; } 2010 int max() { return max_; }
1995 bool is_possessive() { return type_ == POSSESSIVE; } 2011 bool is_possessive() { return type_ == POSSESSIVE; }
1996 bool is_non_greedy() { return type_ == NON_GREEDY; } 2012 bool is_non_greedy() { return type_ == NON_GREEDY; }
1997 bool is_greedy() { return type_ == GREEDY; } 2013 bool is_greedy() { return type_ == GREEDY; }
1998 RegExpTree* body() { return body_; } 2014 RegExpTree* body() { return body_; }
1999 2015
2000 private: 2016 private:
2001 RegExpTree* body_; 2017 RegExpTree* body_;
2002 int min_; 2018 int min_;
2003 int max_; 2019 int max_;
2004 int min_match_; 2020 int min_match_;
2005 int max_match_; 2021 int max_match_;
2006 Type type_; 2022 Type type_;
2023 bool contains_expanded_quantifier_;
2007 }; 2024 };
2008 2025
2009 2026
2010 class RegExpCapture: public RegExpTree { 2027 class RegExpCapture: public RegExpTree {
2011 public: 2028 public:
2012 explicit RegExpCapture(RegExpTree* body, int index) 2029 explicit RegExpCapture(RegExpTree* body, int index)
2013 : body_(body), index_(index) { } 2030 : body_(body), index_(index) { }
2014 virtual void* Accept(RegExpVisitor* visitor, void* data); 2031 virtual void* Accept(RegExpVisitor* visitor, void* data);
2015 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2032 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2016 RegExpNode* on_success); 2033 RegExpNode* on_success);
2017 static RegExpNode* ToNode(RegExpTree* body, 2034 static RegExpNode* ToNode(RegExpTree* body,
2018 int index, 2035 int index,
2019 RegExpCompiler* compiler, 2036 RegExpCompiler* compiler,
2020 RegExpNode* on_success); 2037 RegExpNode* on_success);
2021 virtual RegExpCapture* AsCapture(); 2038 virtual RegExpCapture* AsCapture();
2022 virtual bool IsAnchoredAtStart(); 2039 virtual bool IsAnchoredAtStart();
2023 virtual bool IsAnchoredAtEnd(); 2040 virtual bool IsAnchoredAtEnd();
2024 virtual Interval CaptureRegisters(); 2041 virtual Interval CaptureRegisters();
2025 virtual bool IsCapture(); 2042 virtual bool IsCapture();
2026 virtual int min_match() { return body_->min_match(); } 2043 virtual int min_match() { return body_->min_match(); }
2027 virtual int max_match() { return body_->max_match(); } 2044 virtual int max_match() { return body_->max_match(); }
2045 virtual bool ContainsExpandedQuantifier() {
2046 return contains_expanded_quantifier_ || body_->ContainsExpandedQuantifier();
2047 }
2028 RegExpTree* body() { return body_; } 2048 RegExpTree* body() { return body_; }
2029 int index() { return index_; } 2049 int index() { return index_; }
2030 static int StartRegister(int index) { return index * 2; } 2050 static int StartRegister(int index) { return index * 2; }
2031 static int EndRegister(int index) { return index * 2 + 1; } 2051 static int EndRegister(int index) { return index * 2 + 1; }
2032 2052
2033 private: 2053 private:
2034 RegExpTree* body_; 2054 RegExpTree* body_;
2035 int index_; 2055 int index_;
2036 }; 2056 };
2037 2057
(...skipping 11 matching lines...) Expand all
2049 2069
2050 virtual void* Accept(RegExpVisitor* visitor, void* data); 2070 virtual void* Accept(RegExpVisitor* visitor, void* data);
2051 virtual RegExpNode* ToNode(RegExpCompiler* compiler, 2071 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2052 RegExpNode* on_success); 2072 RegExpNode* on_success);
2053 virtual RegExpLookahead* AsLookahead(); 2073 virtual RegExpLookahead* AsLookahead();
2054 virtual Interval CaptureRegisters(); 2074 virtual Interval CaptureRegisters();
2055 virtual bool IsLookahead(); 2075 virtual bool IsLookahead();
2056 virtual bool IsAnchoredAtStart(); 2076 virtual bool IsAnchoredAtStart();
2057 virtual int min_match() { return 0; } 2077 virtual int min_match() { return 0; }
2058 virtual int max_match() { return 0; } 2078 virtual int max_match() { return 0; }
2079 virtual bool ContainsExpandedQuantifier() {
2080 return contains_expanded_quantifier_ || body_->ContainsExpandedQuantifier();
2081 }
2059 RegExpTree* body() { return body_; } 2082 RegExpTree* body() { return body_; }
2060 bool is_positive() { return is_positive_; } 2083 bool is_positive() { return is_positive_; }
2061 int capture_count() { return capture_count_; } 2084 int capture_count() { return capture_count_; }
2062 int capture_from() { return capture_from_; } 2085 int capture_from() { return capture_from_; }
2063 2086
2064 private: 2087 private:
2065 RegExpTree* body_; 2088 RegExpTree* body_;
2066 bool is_positive_; 2089 bool is_positive_;
2067 int capture_count_; 2090 int capture_count_;
2068 int capture_from_; 2091 int capture_from_;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 2167
2145 private: 2168 private:
2146 Isolate* isolate_; 2169 Isolate* isolate_;
2147 bool stack_overflow_; 2170 bool stack_overflow_;
2148 }; 2171 };
2149 2172
2150 2173
2151 } } // namespace v8::internal 2174 } } // namespace v8::internal
2152 2175
2153 #endif // V8_AST_H_ 2176 #endif // V8_AST_H_
OLDNEW
« no previous file with comments | « no previous file | src/ast.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698