jenkins-bot has submitted this change and it was merged. (
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(-)
Approvals:
Subramanya Sastry: Looks good to me, approved
jenkins-bot: Verified
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: merged
Gerrit-Change-Id: Ica8ebc5ea910e6093e330e90c3e58f9ae167595a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/libs/RemexHtml
Gerrit-Branch: master
Gerrit-Owner: Tim Starling <[email protected]>
Gerrit-Reviewer: Subramanya Sastry <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits