Tim Starling has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/338309 )
Change subject: Guard against runtime creation of undeclared properties ...................................................................... Guard against runtime creation of undeclared properties And fix the bugs which were thus detected. Also fix an error in TokenGeneratorHandler. Change-Id: Ica8ebc5ea910e6093e330e90c3e58f9ae167595a --- A src/PropGuard.php M src/Serializer/Serializer.php M src/Serializer/SerializerNode.php M src/Tokenizer/Attribute.php M src/Tokenizer/TokenGeneratorHandler.php M src/Tokenizer/Tokenizer.php M src/TreeBuilder/Element.php M src/TreeBuilder/InsertionMode.php M src/TreeBuilder/Marker.php M src/TreeBuilder/TreeBuilder.php M tests/phpunit/SerializerNodeDestructionTest.php 11 files changed, 81 insertions(+), 5 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/libs/RemexHtml refs/changes/09/338309/1 diff --git a/src/PropGuard.php b/src/PropGuard.php new file mode 100644 index 0000000..00c3c4d --- /dev/null +++ b/src/PropGuard.php @@ -0,0 +1,21 @@ +<?php + +namespace RemexHtml; + +/** + * This is a statically configurable mechanism for preventing the setting of + * undeclared properties on objects. The point of it is to detect programmer + * errors. + */ +class PropGuard { + public static $armed = true; + + public static function set( $obj, $name, $value ) { + if ( self::$armed ) { + throw new \Exception( "Property \"$name\" on object of class " . get_class( $obj ) . + " is undeclared" ); + } else { + $obj->$name = $value; + } + } +} diff --git a/src/Serializer/Serializer.php b/src/Serializer/Serializer.php index 65da72e..ad7ec8d 100644 --- a/src/Serializer/Serializer.php +++ b/src/Serializer/Serializer.php @@ -1,6 +1,7 @@ <?php namespace RemexHtml\Serializer; +use RemexHtml\PropGuard; use RemexHtml\TreeBuilder\TreeBuilder; use RemexHtml\TreeBuilder\TreeHandler; use RemexHtml\TreeBuilder\Element; @@ -52,6 +53,11 @@ private $isFragment; /** + * The result string + */ + private $result = ''; + + /** * Constructor * * @param Formatter $formatter @@ -63,6 +69,10 @@ $this->errorCallback = $errorCallback; } + public function __set( $name, $value ) { + PropGuard::set( $this, $name, $value ); + } + /** * Get the final string. This can only be called after endDocument() is received. */ diff --git a/src/Serializer/SerializerNode.php b/src/Serializer/SerializerNode.php index f19b20e..2944732 100644 --- a/src/Serializer/SerializerNode.php +++ b/src/Serializer/SerializerNode.php @@ -1,6 +1,7 @@ <?php namespace RemexHtml\Serializer; +use RemexHtml\PropGuard; class SerializerNode { public $id; @@ -24,4 +25,8 @@ $this->attrs = $attrs; $this->void = $void; } + + public function __set( $name, $value ) { + PropGuard::set( $this, $name, $value ); + } } diff --git a/src/Tokenizer/Attribute.php b/src/Tokenizer/Attribute.php index b53e3c0..293b075 100644 --- a/src/Tokenizer/Attribute.php +++ b/src/Tokenizer/Attribute.php @@ -1,6 +1,7 @@ <?php namespace RemexHtml\Tokenizer; +use RemexHtml\PropGuard; /** * A namespaced attribute, as returned by Attributes::getObjects() @@ -19,4 +20,8 @@ $this->localName = $localName; $this->value = $value; } + + public function __set( $name, $value ) { + PropGuard::set( $this, $name, $value ); + } } diff --git a/src/Tokenizer/TokenGeneratorHandler.php b/src/Tokenizer/TokenGeneratorHandler.php index 4d05b73..29f94f0 100644 --- a/src/Tokenizer/TokenGeneratorHandler.php +++ b/src/Tokenizer/TokenGeneratorHandler.php @@ -16,7 +16,7 @@ ]; } - public function endDocument() { + public function endDocument( $pos ) { $this->tokens[] = [ 'type' => 'endDocument' ]; } diff --git a/src/Tokenizer/Tokenizer.php b/src/Tokenizer/Tokenizer.php index f571aba..78b2383 100644 --- a/src/Tokenizer/Tokenizer.php +++ b/src/Tokenizer/Tokenizer.php @@ -2,6 +2,7 @@ namespace RemexHtml\Tokenizer; use RemexHtml\HTMLData; +use RemexHtml\PropGuard; /** * HTML 5 tokenizer @@ -67,6 +68,8 @@ protected $ignoreErrors; protected $ignoreCharRefs; protected $ignoreNulls; + protected $skipPreprocess; + protected $appropriateEndTag; protected $listener; protected $state; protected $preprocessed; @@ -110,6 +113,10 @@ $this->skipPreprocess = !empty( $options['skipPreprocess'] ); } + public function __set( $name, $value ) { + PropGuard::set( $this, $name, $value ); + } + public function setEnableCdataCallback( $cb ) { $this->enableCdataCallback = $cb; } diff --git a/src/TreeBuilder/Element.php b/src/TreeBuilder/Element.php index c571a12..56d0ff5 100644 --- a/src/TreeBuilder/Element.php +++ b/src/TreeBuilder/Element.php @@ -2,6 +2,7 @@ namespace RemexHtml\TreeBuilder; use RemexHtml\HTMLData; +use RemexHtml\PropGuard; use RemexHtml\Tokenizer\Attributes; /** @@ -54,6 +55,12 @@ * Internal to CachingStack. A link in the scope list. */ public $nextScope; + + /** + * Internal to CachingStack and SimpleStack. The current stack index, or + * null if the element is not in the stack. + */ + public $stackIndex; /** * Internal to ActiveFormattingElements. @@ -118,6 +125,10 @@ $this->attrs = $attrs; } + public function __set( $name, $value ) { + PropGuard::set( $this, $name, $value ); + } + /** * Is the element a MathML text integration point? * diff --git a/src/TreeBuilder/InsertionMode.php b/src/TreeBuilder/InsertionMode.php index 9b4e6b8..5d4cd08 100644 --- a/src/TreeBuilder/InsertionMode.php +++ b/src/TreeBuilder/InsertionMode.php @@ -1,6 +1,7 @@ <?php namespace RemexHtml\TreeBuilder; +use RemexHtml\PropGuard; use RemexHtml\Tokenizer\Attributes; use RemexHtml\Tokenizer\TokenHandler; @@ -15,6 +16,10 @@ $this->dispatcher = $dispatcher; } + public function __set( $name, $value ) { + PropGuard::set( $this, $name, $value ); + } + public function doctype( $name, $public, $system, $quirks, $sourceStart, $sourceLength ) { $this->builder->error( "unexpected doctype", $sourceStart ); } diff --git a/src/TreeBuilder/Marker.php b/src/TreeBuilder/Marker.php index 8bd8eb8..80029e5 100644 --- a/src/TreeBuilder/Marker.php +++ b/src/TreeBuilder/Marker.php @@ -1,6 +1,7 @@ <?php namespace RemexHtml\TreeBuilder; +use RemexHtml\PropGuard; /** * A pseudo-element used as a marker or bookmark in the list of active formatting elements @@ -8,10 +9,15 @@ class Marker implements FormattingElement { public $nextAFE; public $prevAFE; + public $nextNoah; public $type; public function __construct( $type ) { $this->type = $type; } + + public function __set( $name, $value ) { + PropGuard::set( $this, $name, $value ); + } } diff --git a/src/TreeBuilder/TreeBuilder.php b/src/TreeBuilder/TreeBuilder.php index 7a1f1d1..3523773 100644 --- a/src/TreeBuilder/TreeBuilder.php +++ b/src/TreeBuilder/TreeBuilder.php @@ -2,6 +2,7 @@ namespace RemexHtml\TreeBuilder; use RemexHtml\HTMLData; +use RemexHtml\PropGuard; use RemexHtml\Tokenizer\Attributes; use RemexHtml\Tokenizer\PlainAttributes; use RemexHtml\Tokenizer\Tokenizer; @@ -50,6 +51,7 @@ public $framesetOK = true; public $quirks = self::NO_QUIRKS; public $fosterParenting = false; + public $pendingTableCharacters = []; private static $fosterTriggers = [ 'table' => true, @@ -116,6 +118,10 @@ } } + public function __set( $name, $value ) { + PropGuard::set( $this, $name, $value ); + } + public function startDocument( Tokenizer $tokenizer, $namespace, $name ) { $tokenizer->setEnableCdataCallback( function () { diff --git a/tests/phpunit/SerializerNodeDestructionTest.php b/tests/phpunit/SerializerNodeDestructionTest.php index 077e0b4..73d6d8c 100644 --- a/tests/phpunit/SerializerNodeDestructionTest.php +++ b/tests/phpunit/SerializerNodeDestructionTest.php @@ -36,8 +36,8 @@ $sourceStart, $sourceLength ) { $this->wrap( __FUNCTION__, func_get_args() ); - if ( !isset( $element->userData->testDestruct ) ) { - $element->userData->testDestruct = new DestructNode( $this->count ); + if ( !$element->userData->snData ) { + $element->userData->snData = new DestructNode( $this->count ); } } @@ -71,8 +71,8 @@ $sourceStart ) { $this->wrap( __FUNCTION__, func_get_args() ); - if ( !isset( $newParent->userData->testDestruct ) ) { - $newParent->userData->testDestruct = new DestructNode( $this->count ); + if ( !$newParent->userData->snData ) { + $newParent->userData->snData = new DestructNode( $this->count ); } } } -- To view, visit https://gerrit.wikimedia.org/r/338309 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ica8ebc5ea910e6093e330e90c3e58f9ae167595a Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/libs/RemexHtml Gerrit-Branch: master Gerrit-Owner: Tim Starling <tstarl...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits