From: Brad Jorsch Date: Mon, 22 Sep 2014 16:49:28 +0000 (-0400) Subject: Break accidental references in Parser::__clone X-Git-Tag: 1.31.0-rc.0~13885^2 X-Git-Url: http://git.cyclocoop.org/url?a=commitdiff_plain;h=8eeb906f93e67c43122fe3de4548b3d05bc8962c;p=lhc%2Fweb%2Fwiklou.git Break accidental references in Parser::__clone If you have a reference *to* an object field (anywhere in the call stack) when you clone the object, the field will be cloned as a reference rather than as a value. So we have to break those unexpected references in the cloned object manually, which is easy enough by making a non-reference copy and then rebinding the cloned object's reference to this copy. Bug: 56226 Change-Id: I9c600e9c0845b4fde0366126ce3809d74e2240b4 --- diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 84bb224300..8bd96b531f 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -258,6 +258,21 @@ class Parser { */ public function __clone() { $this->mInParse = false; + + // Bug 56226: When you create a reference "to" an object field, that + // makes the object field itself be a reference too (until the other + // reference goes out of scope). When cloning, any field that's a + // reference is copied as a reference in the new object. Both of these + // are defined PHP5 behaviors, as inconvenient as it is for us when old + // hooks from PHP4 days are passing fields by reference. + foreach ( array( 'mStripState', 'mVarCache' ) as $k ) { + // Make a non-reference copy of the field, then rebind the field to + // reference the new copy. + $tmp = $this->$k; + $this->$k =& $tmp; + unset( $tmp ); + } + wfRunHooks( 'ParserCloned', array( $this ) ); }