From 8eeb906f93e67c43122fe3de4548b3d05bc8962c Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Mon, 22 Sep 2014 12:49:28 -0400 Subject: [PATCH] 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 --- includes/parser/Parser.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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 ) ); } -- 2.20.1