MaxSem has uploaded a new change for review.
https://gerrit.wikimedia.org/r/269884
Change subject: Parse simplestyle text and description
......................................................................
Parse simplestyle text and description
Change-Id: Idb56d21c60263181385c71e2e067949a5202fb3d
---
M extension.json
A includes/SimpleStyleSanitizer.php
M includes/TagHandler.php
M tests/phpunit/KartographerTest.php
4 files changed, 126 insertions(+), 1 deletion(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Kartographer
refs/changes/84/269884/1
diff --git a/extension.json b/extension.json
index 37bbae6..166ba3f 100644
--- a/extension.json
+++ b/extension.json
@@ -15,6 +15,7 @@
"AutoloadClasses": {
"Kartographer\\DataModule": "includes/DataModule.php",
"Kartographer\\Hooks": "includes/Hooks.php",
+ "Kartographer\\SimpleStyleSanitizer":
"includes/SimpleStyleSanitizer.php",
"Kartographer\\TagHandler": "includes/TagHandler.php"
},
"ResourceModules": {
diff --git a/includes/SimpleStyleSanitizer.php
b/includes/SimpleStyleSanitizer.php
new file mode 100644
index 0000000..d381a81
--- /dev/null
+++ b/includes/SimpleStyleSanitizer.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Kartographer;
+
+use Parser;
+use PPFrame;
+
+/**
+ * Sanitizes text properties of GeoJSON/simplestyle by putting them through
parser
+ */
+class SimpleStyleSanitizer {
+ private static $parsedProps = array( 'title', 'description' );
+
+ private static $recursedProps = array( 'geometry', 'geometries',
'features' );
+
+ /** @var Parser */
+ private $parser;
+
+ /**
+ * @var PPFrame
+ */
+ private $frame;
+
+ /**
+ * Constructor
+ *
+ * @param Parser $parser Parser used for wikitext processing
+ * @param PPFrame $frame
+ */
+ public function __construct( Parser $parser, PPFrame $frame ) {
+ $this->parser = $parser;
+ $this->frame = $frame;
+ }
+
+ /**
+ * Performs recursive sanitizaton.
+ * Does not attempt to be smart, just recurses through everything that
can be dangerous even
+ * if not a valid GeoJSON.
+ *
+ * @param object|array $json
+ */
+ public function sanitize( &$json ) {
+ if ( is_array( $json ) ) {
+ foreach ( $json as &$element ) {
+ $this->sanitize( $element );
+ }
+ return;
+ } elseif ( !is_object( $json ) ) {
+ return;
+ }
+
+ if ( isset( $json->properties ) && is_object( $json->properties
) ) {
+ $this->sanitizeProperties( $json->properties );
+ }
+
+ foreach ( self::$recursedProps as $prop ) {
+ if ( isset( $json->$prop ) ) {
+ $this->sanitize( $json->$prop );
+ }
+ }
+ }
+
+ /**
+ * Sanitizes properties
+ * @param object $properties
+ */
+ private function sanitizeProperties( &$properties ) {
+ foreach ( self::$parsedProps as $prop ) {
+ if ( isset( $properties->$prop ) ) {
+ if ( !is_string( $properties->$prop ) ) {
+ unset( $properties->$prop ); // Dunno
what the hell it is, ditch
+ } else {
+ $properties->$prop =
Parser::stripOuterParagraph(
+
$this->parser->recursiveTagParseFully( $properties->$prop, $this->frame )
+ );
+ }
+ }
+ }
+ }
+}
diff --git a/includes/TagHandler.php b/includes/TagHandler.php
index 498f495..b300b23 100644
--- a/includes/TagHandler.php
+++ b/includes/TagHandler.php
@@ -41,6 +41,8 @@
if ( $value && !is_array( $value ) ) {
$value = array( $value );
}
+ $sanitizer = new SimpleStyleSanitizer( $parser,
$frame );
+ $sanitizer->sanitize( $value );
}
} else {
$status = Status::newGood();
diff --git a/tests/phpunit/KartographerTest.php
b/tests/phpunit/KartographerTest.php
index 6dab1fc..3286363 100644
--- a/tests/phpunit/KartographerTest.php
+++ b/tests/phpunit/KartographerTest.php
@@ -11,6 +11,14 @@
* @group Kartographer
*/
class KartographerTest extends MediaWikiTestCase {
+ public function setUp() {
+ $this->setMwGlobals( array(
+ 'wgScriptPath' => '/w',
+ 'wgScript' => '/w/index.php',
+ ) );
+ parent::setUp();
+ }
+
/**
* @dataProvider provideTagParse
*/
@@ -35,12 +43,46 @@
}
public function provideTagParse() {
+ $validJson = '{
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-122.3988, 37.8013]
+ },
+ "properties": {
+ "title": "Foo bar",
+ "marker-symbol": "museum",
+ "marker-size": "medium",
+ "marker-color": "0050d0"
+ }
+ }';
+ $wikitextJson = '{
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [-122.3988, 37.8013]
+ },
+ "properties": {
+ "title": "<script>alert(document.cookie);</script>",
+ "description": "[[Link to nowhere]]"
+ }
+ }';
+ $wikitextJsonParsed =
'{"_b3a06246589b01ce9e9c2ba3dc97e265f7ea0308":[
+
{"type":"Feature","geometry":{"type":"Point","coordinates":[-122.3988,37.8013]},
+
"properties":{"title":"<script>alert(document.cookie);<\/script>",
+ "description":"<a
href=\"\/w\/index.php?title=Link_to_nowhere&action=edit&redlink=1\"
class=\"new\" title=\"Link to nowhere (page does not exist)\">Link to
nowhere<\/a>"}}
+ ]}';
return array(
array( false, '<maps/>', 'Empty tag is meaningless' ),
array( false, '<maps></maps>', 'Empty tag is
meaningless 2' ),
array( 'null', '<maps width=700 height=400 zoom=13
longitude=-122.3988 latitude=37.8013 mode=interactive/>', 'Map without JSON' ),
array( 'null', '<maps width=700 height=400 zoom=13
longitude=-122.3988 latitude=37.8013 mode=interactive></maps>', 'Map without
JSON 2' ),
- array( 'null', '<maps width=700 height=400 zoom=13
longitude=-122.3988 latitude=37.8013 mode=interactive>[]</maps>', 'Map with
empty JSON' ),
+ array( false, '<maps width=700 height=400 zoom=13
longitude=-122.3988 latitude=37.8013 mode=interactive>123</maps>', 'Invalid
JSON' ),
+ array( false, '<maps width=700 height=400 zoom=13
longitude=-122.3988 latitude=37.8013 mode=interactive>fail</maps>', 'Invalid
JSON 2' ),
+ array( false, '<maps width=700 height=400 zoom=13
longitude=-122.3988 latitude=37.8013 mode=interactive>{{"":""}}</maps>',
'Invalid JSON 3' ),
+ array(
"{\"_bc2671e0e7a829e9d19c743d6701fa410dd04827\":[$validJson]}", "<maps
width=700 height=400 zoom=13 longitude=-122.3988 latitude=37.8013
mode=interactive>$validJson</maps>", 'Map with GeoJSON' ),
+ array(
"{\"_bc2671e0e7a829e9d19c743d6701fa410dd04827\":[$validJson]}", "<maps
width=700 height=400 zoom=13 longitude=-122.3988 latitude=37.8013
mode=interactive>[$validJson]</maps>", 'Map with GeoJSON array' ),
+ array( $wikitextJsonParsed, "<maps width=700 height=400
zoom=13 longitude=-122.3988 latitude=37.8013
mode=interactive>[$wikitextJson]</maps>", 'Map with parsable text and
description' ),
);
}
--
To view, visit https://gerrit.wikimedia.org/r/269884
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Idb56d21c60263181385c71e2e067949a5202fb3d
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Kartographer
Gerrit-Branch: master
Gerrit-Owner: MaxSem <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits