From 21a6e405c7e09f6b4d4dbbf5c8728e80710eddb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3js?= Date: Wed, 4 Oct 2017 13:16:43 +0200 Subject: [PATCH] Fix EZP-27562: Allow square brackets and percent character in RichText link (#2090) --- .../Resources/schemas/docbook/docbook.iso.sch | 6 ++- .../Resources/schemas/docbook/docbook.iso.sch.xsl | 4 +- .../RichText/Resources/schemas/docbook/docbook.rng | 2 +- .../iso_schematron_skeleton_for_xslt1.xsl | 6 ++- eZ/Publish/Core/FieldType/RichText/Validator.php | 3 ++ .../FieldType/RichText/XSLTProcessorFunctions.php | 30 ++++++++++++ .../Tests/RichText/XSLTProcessorFunctionsTest.php | 46 ++++++++++++++++++ eZ/Publish/Core/FieldType/Tests/RichTextTest.php | 54 +++++++++++++++++++++- 8 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 eZ/Publish/Core/FieldType/RichText/XSLTProcessorFunctions.php create mode 100644 eZ/Publish/Core/FieldType/Tests/RichText/XSLTProcessorFunctionsTest.php diff --git a/eZ/Publish/Core/FieldType/RichText/Resources/schemas/docbook/docbook.iso.sch b/eZ/Publish/Core/FieldType/RichText/Resources/schemas/docbook/docbook.iso.sch index 4129880d39..9838425259 100644 --- a/eZ/Publish/Core/FieldType/RichText/Resources/schemas/docbook/docbook.iso.sch +++ b/eZ/Publish/Core/FieldType/RichText/Resources/schemas/docbook/docbook.iso.sch @@ -1,6 +1,8 @@ + xmlns:db="http://docbook.org/ns/docbook" + xmlns:php="http://php.net/xsl" + > @@ -79,4 +79,4 @@ -using scripts in links is not allowed +The value must be a valid URL diff --git a/eZ/Publish/Core/FieldType/RichText/Resources/schemas/docbook/docbook.rng b/eZ/Publish/Core/FieldType/RichText/Resources/schemas/docbook/docbook.rng index 019c84b847..2f34b8b1a8 100644 --- a/eZ/Publish/Core/FieldType/RichText/Resources/schemas/docbook/docbook.rng +++ b/eZ/Publish/Core/FieldType/RichText/Resources/schemas/docbook/docbook.rng @@ -203,7 +203,7 @@ Identifies a link target with a URI - + diff --git a/eZ/Publish/Core/FieldType/RichText/Resources/stylesheets/schematron/iso_schematron_skeleton_for_xslt1.xsl b/eZ/Publish/Core/FieldType/RichText/Resources/stylesheets/schematron/iso_schematron_skeleton_for_xslt1.xsl index d0114996b1..001b3be00f 100644 --- a/eZ/Publish/Core/FieldType/RichText/Resources/stylesheets/schematron/iso_schematron_skeleton_for_xslt1.xsl +++ b/eZ/Publish/Core/FieldType/RichText/Resources/stylesheets/schematron/iso_schematron_skeleton_for_xslt1.xsl @@ -393,13 +393,14 @@ xmlns:iso="http://purl.oclc.org/dsdl/schematron" xmlns:exsl="http://exslt.org/common" xmlns:msxsl="urn:schemas-microsoft-com:xslt" - extension-element-prefixes="exsl msxsl" + xmlns:php="http://php.net/xsl" + extension-element-prefixes="exsl msxsl" > - + @@ -569,6 +570,7 @@ + php Implementers: please note that overriding process-prolog or process-root is the preferred method for meta-stylesheets to use where possible. diff --git a/eZ/Publish/Core/FieldType/RichText/Validator.php b/eZ/Publish/Core/FieldType/RichText/Validator.php index c10c778455..d598462a34 100644 --- a/eZ/Publish/Core/FieldType/RichText/Validator.php +++ b/eZ/Publish/Core/FieldType/RichText/Validator.php @@ -119,6 +119,9 @@ protected function schematronValidate(DOMDocument $document, $filename) { $stylesheet = $this->loadFile($filename); $xsltProcessor = new XSLTProcessor(); + $xsltProcessor->registerPHPFunctions([ + 'eZ\Publish\Core\FieldType\RichText\XSLTProcessorFunctions::isValidUrl', + ]); $xsltProcessor->importStyleSheet($stylesheet); $result = $xsltProcessor->transformToDoc($document); diff --git a/eZ/Publish/Core/FieldType/RichText/XSLTProcessorFunctions.php b/eZ/Publish/Core/FieldType/RichText/XSLTProcessorFunctions.php new file mode 100644 index 0000000000..a20b84340a --- /dev/null +++ b/eZ/Publish/Core/FieldType/RichText/XSLTProcessorFunctions.php @@ -0,0 +1,30 @@ +assertEquals($expected, XSLTProcessorFunctions::isValidUrl($url)); + } + + public function providerForIsValidUrl() + { + return [ + ['http://example.url', true], + ['https://example.url', true], + ['http://192.168.56.101/segment#/fragment%20url', true], + ['http://example.url/segment', true], + ['http://user:password@example.url:8001/', true], + ['http://example.url?with[square]=brackets', true], + ['http://example.url?with=value%20with%20spaces', true], + ['http://example.url#fragment', true], + ['http://example.url.with.#fragment', true], + ['ftp://example.com/pub/file.txt', true], + ['ftp://user:password@example.com/pub/file.txt', true], + ['ftps://example.com/pub/file.txt', true], + ['ftps://user:password@example.com/pub/file.txt', true], + ['#fragment', true], + ['ezlocation://72', true], + ['ezlocation://72#fragment', true], + ['ezcontent://70', true], + ['ezcontent://72#fragment', true], + ["javascript:alert('BOOM!')", false], + ["vbscript:alert('BOOM!')", false], + ['Simple text', false], + ['script>', false], + ["", false], + ]; + } +} diff --git a/eZ/Publish/Core/FieldType/Tests/RichTextTest.php b/eZ/Publish/Core/FieldType/Tests/RichTextTest.php index c3eb709551..e5ec7bf966 100644 --- a/eZ/Publish/Core/FieldType/Tests/RichTextTest.php +++ b/eZ/Publish/Core/FieldType/Tests/RichTextTest.php @@ -208,7 +208,7 @@ public function providerForTestValidate() array( new ValidationError( "Validation of XML content failed:\n" . - '/section/para/link: using scripts in links is not allowed' + '/section/para/link: The value must be a valid URL' ), ), ), @@ -220,7 +220,7 @@ public function providerForTestValidate() array( new ValidationError( "Validation of XML content failed:\n" . - '/section/para/link: using scripts in links is not allowed' + '/section/para/link: The value must be a valid URL' ), ), ), @@ -231,6 +231,56 @@ public function providerForTestValidate() ', array(), ), + array( + ' +
+ link +
', + array(), + ), + array( + ' +
+ link +
', + array(), + ), + array( + ' +
+ injected > +
', + array( + new ValidationError( + "Validation of XML content failed:\n" . + '/section/para/link: The value must be a valid URL' + ), + ), + ), + array( + ' +
+ injected < +
', + array( + new ValidationError( + "Validation of XML content failed:\n" . + '/section/para/link: The value must be a valid URL' + ), + ), + ), + array( + ' +
+ injected " +
', + array( + new ValidationError( + "Validation of XML content failed:\n" . + '/section/para/link: The value must be a valid URL' + ), + ), + ), ); }