Changeset 20051 in webkit
- Timestamp:
- Mar 7, 2007 7:47:34 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r20041 r20051 1 2007-03-07 Alexey Proskuryakov <ap@webkit.org> 2 3 Reviewed by Darin. 4 5 http://bugs.webkit.org/show_bug.cgi?id=13004 6 Repeatedly calling XPathExpression.evaluate() causes crashes or memory leaks 7 8 * fast/xpath/evaluate-twice-expected.txt: Added. 9 * fast/xpath/evaluate-twice.html: Added. 10 1 11 2007-03-07 Mitz Pettel <mitz@webkit.org> 2 12 -
trunk/WebCore/ChangeLog
r20048 r20051 1 2007-03-07 Alexey Proskuryakov <ap@webkit.org> 2 3 Reviewed by Darin. 4 5 http://bugs.webkit.org/show_bug.cgi?id=13004 6 Repeatedly calling XPathExpression.evaluate() causes crashes or memory leaks 7 8 Removed XPath::Expression::optimize() and related methods, since they were buggy and almost useless. 9 Merged doEvaluate() into evaluate(), since this was all evaluate() was doing after the above changes. 10 11 Test: fast/xpath/evaluate-twice.html 12 13 * xml/XPathExpression.cpp: 14 (WebCore::XPathExpression::evaluate): 15 * xml/XPathExpressionNode.cpp: 16 (WebCore::XPath::Expression::Expression): 17 (WebCore::XPath::Expression::~Expression): 18 * xml/XPathExpressionNode.h: 19 * xml/XPathFunctions.cpp: 20 (WebCore::XPath::FunLast::evaluate): 21 (WebCore::XPath::FunPosition::evaluate): 22 (WebCore::XPath::FunId::evaluate): 23 (WebCore::XPath::FunLocalName::evaluate): 24 (WebCore::XPath::FunNamespaceURI::evaluate): 25 (WebCore::XPath::FunName::evaluate): 26 (WebCore::XPath::FunCount::evaluate): 27 (WebCore::XPath::FunString::evaluate): 28 (WebCore::XPath::FunConcat::evaluate): 29 (WebCore::XPath::FunStartsWith::evaluate): 30 (WebCore::XPath::FunContains::evaluate): 31 (WebCore::XPath::FunSubstringBefore::evaluate): 32 (WebCore::XPath::FunSubstringAfter::evaluate): 33 (WebCore::XPath::FunSubstring::evaluate): 34 (WebCore::XPath::FunStringLength::evaluate): 35 (WebCore::XPath::FunNormalizeSpace::evaluate): 36 (WebCore::XPath::FunTranslate::evaluate): 37 (WebCore::XPath::FunBoolean::evaluate): 38 (WebCore::XPath::FunNot::evaluate): 39 (WebCore::XPath::FunTrue::evaluate): 40 (WebCore::XPath::FunLang::evaluate): 41 (WebCore::XPath::FunFalse::evaluate): 42 (WebCore::XPath::FunNumber::evaluate): 43 (WebCore::XPath::FunSum::evaluate): 44 (WebCore::XPath::FunFloor::evaluate): 45 (WebCore::XPath::FunCeiling::evaluate): 46 (WebCore::XPath::FunRound::evaluate): 47 * xml/XPathPath.cpp: 48 (WebCore::XPath::Filter::evaluate): 49 (WebCore::XPath::LocationPath::evaluate): 50 (WebCore::XPath::Path::evaluate): 51 * xml/XPathPath.h: 52 * xml/XPathPredicate.cpp: 53 (WebCore::XPath::Number::evaluate): 54 (WebCore::XPath::StringExpression::evaluate): 55 (WebCore::XPath::Negative::evaluate): 56 (WebCore::XPath::NumericOp::evaluate): 57 (WebCore::XPath::EqTestOp::evaluate): 58 (WebCore::XPath::LogicalOp::evaluate): 59 (WebCore::XPath::Union::evaluate): 60 * xml/XPathPredicate.h: 61 * xml/XPathStep.cpp: 62 * xml/XPathStep.h: 63 * xml/XPathVariableReference.cpp: 64 (WebCore::XPath::VariableReference::evaluate): 65 * xml/XPathVariableReference.h: 66 1 67 2007-03-07 Sam Weinig <sam@webkit.org> 2 68 -
trunk/WebCore/xml/XPathExpression.cpp
r19968 r20051 75 75 Expression::evaluationContext().size = 1; 76 76 Expression::evaluationContext().position = 1; 77 m_topExpression->optimize();78 77 RefPtr<XPathResult> result = new XPathResult(eventTarget, m_topExpression->evaluate()); 79 78 -
trunk/WebCore/xml/XPathExpressionNode.cpp
r19855 r20051 43 43 44 44 Expression::Expression() 45 : m_constantValue(0)46 45 { 47 46 } … … 50 49 { 51 50 deleteAllValues(m_subExpressions); 52 delete m_constantValue;53 }54 55 Value Expression::evaluate() const56 {57 if (m_constantValue)58 return *m_constantValue;59 return doEvaluate();60 51 } 61 52 … … 63 54 { 64 55 m_subExpressions.append(expr); 65 }66 67 void Expression::optimize()68 {69 bool allSubExpressionsConstant = true;70 71 for (unsigned i = 0; i < m_subExpressions.size(); i++) {72 if (m_subExpressions[i]->isConstant())73 m_subExpressions[i]->optimize();74 else75 allSubExpressionsConstant = false;76 }77 78 if (allSubExpressionsConstant) {79 ASSERT (!m_constantValue);80 m_constantValue = new Value(doEvaluate());81 deleteAllValues(m_subExpressions);82 m_subExpressions.clear();83 }84 56 } 85 57 … … 101 73 } 102 74 103 bool Expression::isConstant() const104 {105 for (unsigned i = 0; i < m_subExpressions.size(); i++)106 if (!m_subExpressions[i]->isConstant())107 return false;108 return true;109 }110 111 75 } 112 76 } -
trunk/WebCore/xml/XPathExpressionNode.h
r19855 r20051 64 64 virtual ~Expression(); 65 65 66 virtual Value evaluate() const ;66 virtual Value evaluate() const = 0; 67 67 68 68 void addSubExpression(Expression*); 69 void optimize();70 virtual bool isConstant() const;71 69 72 70 protected: … … 76 74 77 75 private: 78 virtual Value doEvaluate() const = 0;79 80 76 Vector<Expression*> m_subExpressions; 81 Value* m_constantValue;82 77 }; 83 78 -
trunk/WebCore/xml/XPathFunctions.cpp
r19968 r20051 72 72 73 73 class FunLast : public Function { 74 virtual bool isConstant() const; 75 virtual Value doEvaluate() const; 74 virtual Value evaluate() const; 76 75 }; 77 76 78 77 class FunPosition : public Function { 79 virtual bool isConstant() const; 80 virtual Value doEvaluate() const; 78 virtual Value evaluate() const; 81 79 }; 82 80 83 81 class FunCount : public Function { 84 virtual bool isConstant() const; 85 virtual Value doEvaluate() const; 82 virtual Value evaluate() const; 86 83 }; 87 84 88 85 class FunId : public Function { 89 virtual bool isConstant() const; 90 virtual Value doEvaluate() const; 86 virtual Value evaluate() const; 91 87 }; 92 88 93 89 class FunLocalName : public Function { 94 virtual bool isConstant() const; 95 virtual Value doEvaluate() const; 90 virtual Value evaluate() const; 96 91 }; 97 92 98 93 class FunNamespaceURI : public Function { 99 virtual bool isConstant() const; 100 virtual Value doEvaluate() const; 94 virtual Value evaluate() const; 101 95 }; 102 96 103 97 class FunName : public Function { 104 virtual bool isConstant() const; 105 virtual Value doEvaluate() const; 98 virtual Value evaluate() const; 106 99 }; 107 100 108 101 class FunString : public Function { 109 virtual Value doEvaluate() const;102 virtual Value evaluate() const; 110 103 }; 111 104 112 105 class FunConcat : public Function { 113 virtual Value doEvaluate() const;106 virtual Value evaluate() const; 114 107 }; 115 108 116 109 class FunStartsWith : public Function { 117 virtual Value doEvaluate() const;110 virtual Value evaluate() const; 118 111 }; 119 112 120 113 class FunContains : public Function { 121 virtual Value doEvaluate() const;114 virtual Value evaluate() const; 122 115 }; 123 116 124 117 class FunSubstringBefore : public Function { 125 virtual Value doEvaluate() const;118 virtual Value evaluate() const; 126 119 }; 127 120 128 121 class FunSubstringAfter : public Function { 129 virtual Value doEvaluate() const;122 virtual Value evaluate() const; 130 123 }; 131 124 132 125 class FunSubstring : public Function { 133 virtual Value doEvaluate() const;126 virtual Value evaluate() const; 134 127 }; 135 128 136 129 class FunStringLength : public Function { 137 virtual Value doEvaluate() const;130 virtual Value evaluate() const; 138 131 }; 139 132 140 133 class FunNormalizeSpace : public Function { 141 virtual Value doEvaluate() const;134 virtual Value evaluate() const; 142 135 }; 143 136 144 137 class FunTranslate : public Function { 145 virtual Value doEvaluate() const;138 virtual Value evaluate() const; 146 139 }; 147 140 148 141 class FunBoolean : public Function { 149 virtual Value doEvaluate() const;142 virtual Value evaluate() const; 150 143 }; 151 144 152 145 class FunNot : public Function { 153 virtual Value doEvaluate() const;146 virtual Value evaluate() const; 154 147 }; 155 148 156 149 class FunTrue : public Function { 157 virtual bool isConstant() const; 158 virtual Value doEvaluate() const; 150 virtual Value evaluate() const; 159 151 }; 160 152 161 153 class FunFalse : public Function { 162 virtual bool isConstant() const; 163 virtual Value doEvaluate() const; 154 virtual Value evaluate() const; 164 155 }; 165 156 166 157 class FunLang : public Function { 167 virtual bool isConstant() const; 168 virtual Value doEvaluate() const; 158 virtual Value evaluate() const; 169 159 }; 170 160 171 161 class FunNumber : public Function { 172 virtual Value doEvaluate() const;162 virtual Value evaluate() const; 173 163 }; 174 164 175 165 class FunSum : public Function { 176 virtual Value doEvaluate() const;166 virtual Value evaluate() const; 177 167 }; 178 168 179 169 class FunFloor : public Function { 180 virtual Value doEvaluate() const;170 virtual Value evaluate() const; 181 171 }; 182 172 183 173 class FunCeiling : public Function { 184 virtual Value doEvaluate() const;174 virtual Value evaluate() const; 185 175 }; 186 176 187 177 class FunRound : public Function { 188 virtual Value doEvaluate() const;178 virtual Value evaluate() const; 189 179 public: 190 180 static double round(double); … … 286 276 } 287 277 288 Value FunLast:: doEvaluate() const278 Value FunLast::evaluate() const 289 279 { 290 280 return Expression::evaluationContext().size; 291 281 } 292 282 293 bool FunLast::isConstant() const 294 { 295 return false; 296 } 297 298 Value FunPosition::doEvaluate() const 283 Value FunPosition::evaluate() const 299 284 { 300 285 return Expression::evaluationContext().position; 301 286 } 302 287 303 bool FunPosition::isConstant() const 304 { 305 return false; 306 } 307 308 bool FunId::isConstant() const 309 { 310 return false; 311 } 312 313 Value FunId::doEvaluate() const 288 Value FunId::evaluate() const 314 289 { 315 290 // FIXME: this algorithm does not produce an ordered node-set, as it should. … … 359 334 } 360 335 361 bool FunLocalName::isConstant() const 362 { 363 return false; 364 } 365 366 Value FunLocalName::doEvaluate() const 336 Value FunLocalName::evaluate() const 367 337 { 368 338 Node* node = 0; … … 381 351 } 382 352 383 bool FunNamespaceURI::isConstant() const 384 { 385 return false; 386 } 387 388 Value FunNamespaceURI::doEvaluate() const 353 Value FunNamespaceURI::evaluate() const 389 354 { 390 355 Node* node = 0; … … 403 368 } 404 369 405 bool FunName::isConstant() const 406 { 407 return false; 408 } 409 410 Value FunName::doEvaluate() const 370 Value FunName::evaluate() const 411 371 { 412 372 Node* node = 0; … … 426 386 } 427 387 428 Value FunCount:: doEvaluate() const388 Value FunCount::evaluate() const 429 389 { 430 390 Value a = arg(0)->evaluate(); … … 436 396 } 437 397 438 bool FunCount::isConstant() const 439 { 440 return false; 441 } 442 443 Value FunString::doEvaluate() const 398 Value FunString::evaluate() const 444 399 { 445 400 if (!argCount()) … … 448 403 } 449 404 450 Value FunConcat:: doEvaluate() const405 Value FunConcat::evaluate() const 451 406 { 452 407 String str = ""; … … 458 413 } 459 414 460 Value FunStartsWith:: doEvaluate() const415 Value FunStartsWith::evaluate() const 461 416 { 462 417 String s1 = arg(0)->evaluate().toString(); … … 469 424 } 470 425 471 Value FunContains:: doEvaluate() const426 Value FunContains::evaluate() const 472 427 { 473 428 String s1 = arg(0)->evaluate().toString(); … … 480 435 } 481 436 482 Value FunSubstringBefore:: doEvaluate() const437 Value FunSubstringBefore::evaluate() const 483 438 { 484 439 String s1 = arg(0)->evaluate().toString(); … … 496 451 } 497 452 498 Value FunSubstringAfter:: doEvaluate() const453 Value FunSubstringAfter::evaluate() const 499 454 { 500 455 String s1 = arg(0)->evaluate().toString(); … … 511 466 } 512 467 513 Value FunSubstring:: doEvaluate() const468 Value FunSubstring::evaluate() const 514 469 { 515 470 String s = arg(0)->evaluate().toString(); … … 537 492 } 538 493 539 Value FunStringLength:: doEvaluate() const494 Value FunStringLength::evaluate() const 540 495 { 541 496 if (!argCount()) … … 544 499 } 545 500 546 Value FunNormalizeSpace:: doEvaluate() const501 Value FunNormalizeSpace::evaluate() const 547 502 { 548 503 if (!argCount()) { … … 555 510 } 556 511 557 Value FunTranslate:: doEvaluate() const512 Value FunTranslate::evaluate() const 558 513 { 559 514 String s1 = arg(0)->evaluate().toString(); … … 578 533 } 579 534 580 Value FunBoolean:: doEvaluate() const535 Value FunBoolean::evaluate() const 581 536 { 582 537 return arg(0)->evaluate().toBoolean(); 583 538 } 584 539 585 Value FunNot:: doEvaluate() const540 Value FunNot::evaluate() const 586 541 { 587 542 return !arg(0)->evaluate().toBoolean(); 588 543 } 589 544 590 Value FunTrue:: doEvaluate() const545 Value FunTrue::evaluate() const 591 546 { 592 547 return true; 593 548 } 594 549 595 bool FunTrue::isConstant() const 596 { 597 return true; 598 } 599 600 Value FunLang::doEvaluate() const 550 Value FunLang::evaluate() const 601 551 { 602 552 String lang = arg(0)->evaluate().toString(); … … 631 581 } 632 582 633 bool FunLang::isConstant() const583 Value FunFalse::evaluate() const 634 584 { 635 585 return false; 636 586 } 637 587 638 Value FunFalse::doEvaluate() const 639 { 640 return false; 641 } 642 643 bool FunFalse::isConstant() const 644 { 645 return true; 646 } 647 648 Value FunNumber::doEvaluate() const 588 Value FunNumber::evaluate() const 649 589 { 650 590 if (!argCount()) … … 653 593 } 654 594 655 Value FunSum:: doEvaluate() const595 Value FunSum::evaluate() const 656 596 { 657 597 Value a = arg(0)->evaluate(); … … 668 608 } 669 609 670 Value FunFloor:: doEvaluate() const610 Value FunFloor::evaluate() const 671 611 { 672 612 return floor(arg(0)->evaluate().toNumber()); 673 613 } 674 614 675 Value FunCeiling:: doEvaluate() const615 Value FunCeiling::evaluate() const 676 616 { 677 617 return ceil(arg(0)->evaluate().toNumber()); … … 689 629 } 690 630 691 Value FunRound:: doEvaluate() const631 Value FunRound::evaluate() const 692 632 { 693 633 return round(arg(0)->evaluate().toNumber()); -
trunk/WebCore/xml/XPathPath.cpp
r19855 r20051 49 49 } 50 50 51 Value Filter:: doEvaluate() const51 Value Filter::evaluate() const 52 52 { 53 53 Value v = m_expr->evaluate(); … … 87 87 } 88 88 89 void LocationPath::optimize() 90 { 91 for (unsigned i = 0; i < m_steps.size(); i++) 92 m_steps[i]->optimize(); 93 } 94 95 Value LocationPath::doEvaluate() const 89 Value LocationPath::evaluate() const 96 90 { 97 91 /* For absolute location paths, the context node is ignored - the … … 145 139 } 146 140 147 Value Path:: doEvaluate() const141 Value Path::evaluate() const 148 142 { 149 143 return m_path->evaluate(m_filter->evaluate().toNodeVector()); -
trunk/WebCore/xml/XPathPath.h
r19855 r20051 47 47 virtual ~Filter(); 48 48 49 virtual Value evaluate() const; 50 49 51 private: 50 virtual Value doEvaluate() const;51 52 52 Expression* m_expr; 53 53 Vector<Predicate*> m_predicates; … … 59 59 virtual ~LocationPath(); 60 60 61 using Expression::evaluate;61 virtual Value evaluate() const; 62 62 Value evaluate(const NodeVector& startNodes) const; 63 63 64 void optimize();65 66 64 private: 67 virtual Value doEvaluate() const;68 69 65 Vector<Step*> m_steps; 70 66 bool m_absolute; … … 79 75 virtual ~Path(); 80 76 77 virtual Value evaluate() const; 78 81 79 private: 82 virtual Value doEvaluate() const;83 84 80 Filter* m_filter; 85 81 LocationPath* m_path; -
trunk/WebCore/xml/XPathPredicate.cpp
r20008 r20051 48 48 } 49 49 50 bool Number::isConstant() const 51 { 52 return true; 53 } 54 55 Value Number::doEvaluate() const 50 Value Number::evaluate() const 56 51 { 57 52 return m_value; … … 63 58 } 64 59 65 bool StringExpression::isConstant() const 66 { 67 return true; 68 } 69 70 Value StringExpression::doEvaluate() const 60 Value StringExpression::evaluate() const 71 61 { 72 62 return m_value; 73 63 } 74 64 75 Value Negative:: doEvaluate() const65 Value Negative::evaluate() const 76 66 { 77 67 Value p(subExpr(0)->evaluate()); … … 86 76 } 87 77 88 Value NumericOp:: doEvaluate() const78 Value NumericOp::evaluate() const 89 79 { 90 80 Value lhs(subExpr(0)->evaluate()); … … 205 195 } 206 196 207 Value EqTestOp:: doEvaluate() const197 Value EqTestOp::evaluate() const 208 198 { 209 199 Value lhs(subExpr(0)->evaluate()); … … 228 218 } 229 219 230 bool LogicalOp::isConstant() const 231 { 232 return subExpr(0)->isConstant() && 233 subExpr(0)->evaluate().toBoolean() == shortCircuitOn(); 234 } 235 236 Value LogicalOp::doEvaluate() const 220 Value LogicalOp::evaluate() const 237 221 { 238 222 Value lhs(subExpr(0)->evaluate()); … … 247 231 } 248 232 249 Value Union:: doEvaluate() const233 Value Union::evaluate() const 250 234 { 251 235 // FIXME: This algorithm doesn't return nodes in document order, as it should. … … 295 279 } 296 280 297 void Predicate::optimize()298 {299 m_expr->optimize();300 }301 302 281 } 303 282 } -
trunk/WebCore/xml/XPathPredicate.h
r19963 r20051 39 39 public: 40 40 Number(double); 41 bool isConstant() const;42 41 private: 43 virtual Value doEvaluate() const;42 virtual Value evaluate() const; 44 43 double m_value; 45 44 }; … … 48 47 public: 49 48 StringExpression(const String&); 50 bool isConstant() const;51 49 private: 52 virtual Value doEvaluate() const;50 virtual Value evaluate() const; 53 51 String m_value; 54 52 }; … … 56 54 class Negative : public Expression { 57 55 private: 58 virtual Value doEvaluate() const;56 virtual Value evaluate() const; 59 57 }; 60 58 … … 66 64 NumericOp(Opcode, Expression* lhs, Expression* rhs); 67 65 private: 68 virtual Value doEvaluate() const;66 virtual Value evaluate() const; 69 67 Opcode m_opcode; 70 68 }; … … 74 72 enum Opcode { OP_EQ, OP_NE, OP_GT, OP_LT, OP_GE, OP_LE }; 75 73 EqTestOp(Opcode, Expression* lhs, Expression* rhs); 74 virtual Value evaluate() const; 76 75 private: 77 virtual Value doEvaluate() const;78 76 bool compare(const Value&, const Value&) const; 79 77 Opcode m_opcode; … … 84 82 enum Opcode { OP_And, OP_Or }; 85 83 LogicalOp(Opcode, Expression* lhs, Expression* rhs); 86 virtual bool isConstant() const;87 84 private: 88 85 bool shortCircuitOn() const; 89 virtual Value doEvaluate() const;86 virtual Value evaluate() const; 90 87 Opcode m_opcode; 91 88 }; … … 93 90 class Union : public Expression { 94 91 private: 95 virtual Value doEvaluate() const;92 virtual Value evaluate() const; 96 93 }; 97 94 … … 101 98 ~Predicate(); 102 99 bool evaluate() const; 103 void optimize();104 100 private: 105 101 Expression* m_expr; -
trunk/WebCore/xml/XPathStep.cpp
r20008 r20051 265 265 } 266 266 267 void Step::optimize()268 {269 for (unsigned i = 0; i < m_predicates.size(); i++)270 m_predicates[i]->optimize();271 }272 273 267 Node::NodeType Step::primaryNodeType(Axis axis) const 274 268 { -
trunk/WebCore/xml/XPathStep.h
r19855 r20051 56 56 NodeVector evaluate(Node* context) const; 57 57 58 void optimize();59 60 58 private: 61 59 NodeVector nodesInAxis(Node* context) const; -
trunk/WebCore/xml/XPathVariableReference.cpp
r19855 r20051 41 41 } 42 42 43 bool VariableReference::isConstant() const 44 { 45 return false; 46 } 47 48 Value VariableReference::doEvaluate() const 43 Value VariableReference::evaluate() const 49 44 { 50 45 HashMap<String, String>& bindings = evaluationContext().variableBindings; -
trunk/WebCore/xml/XPathVariableReference.h
r19855 r20051 38 38 public: 39 39 VariableReference(const String& name); 40 virtual bool isConstant() const;41 40 private: 42 virtual Value doEvaluate() const;41 virtual Value evaluate() const; 43 42 String m_name; 44 43 };
Note: See TracChangeset
for help on using the changeset viewer.