Skip to content

Commit

Permalink
IBX-8891: Fixed XML link validation to allow using tel: in links (#…
Browse files Browse the repository at this point in the history
…245)

* IBX-8891: XML link validator in rich-text does not allow to use "tel: "

* [PHPStan] Aligned baseline after PHPStan update
  • Loading branch information
vidarl authored Sep 26, 2024
1 parent dbe816f commit acb0fa0
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 29 deletions.
90 changes: 86 additions & 4 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,36 @@ parameters:
count: 1
path: src/lib/eZ/FieldType/RichText/RichTextStorage.php

-
message: "#^Offset 1 does not exist on array\\{0\\?\\: string, 1\\?\\: ''\\|'ezremote\\://', 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/FieldType/RichText/RichTextStorage.php

-
message: "#^Offset 1 does not exist on array\\{0\\?\\: string, 1\\?\\: string, 2\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/FieldType/RichText/RichTextStorage.php

-
message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\: 'ezremote\\://', 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/FieldType/RichText/RichTextStorage.php

-
message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\?\\: ''\\|'ezremote\\://', 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 2
path: src/lib/eZ/FieldType/RichText/RichTextStorage.php

-
message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\?\\: string, 2\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/FieldType/RichText/RichTextStorage.php

-
message: "#^Offset 3 does not exist on array\\{0\\?\\: string, 1\\?\\: ''\\|'ezremote\\://', 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/FieldType/RichText/RichTextStorage.php

-
message: "#^Parameter \\#1 \\$source of method DOMDocument\\:\\:loadXML\\(\\) expects string, array\\|bool\\|float\\|int\\|string\\|null given\\.$#"
count: 2
Expand Down Expand Up @@ -770,6 +800,21 @@ parameters:
count: 4
path: src/lib/eZ/RichText/Converter/Link.php

-
message: "#^Offset 1 does not exist on array\\{0\\?\\: string, 1\\?\\: string, 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/RichText/Converter/Link.php

-
message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\?\\: string, 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/RichText/Converter/Link.php

-
message: "#^Offset 3 does not exist on array\\{0\\?\\: string, 1\\?\\: string, 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/RichText/Converter/Link.php

-
message: "#^Parameter \\#1 \\$locationId of method eZ\\\\Publish\\\\API\\\\Repository\\\\LocationService\\:\\:loadLocation\\(\\) expects int, int\\|null given\\.$#"
count: 1
Expand Down Expand Up @@ -915,6 +960,21 @@ parameters:
count: 1
path: src/lib/eZ/RichText/Converter/Render/Embed.php

-
message: "#^Offset 1 does not exist on array\\{0\\?\\: string, 1\\?\\: 'ezcontent'\\|'ezlocation', 2\\?\\: numeric\\-string\\}\\.$#"
count: 1
path: src/lib/eZ/RichText/Converter/Render/Embed.php

-
message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\: 'ezcontent', 2\\?\\: numeric\\-string\\}\\.$#"
count: 1
path: src/lib/eZ/RichText/Converter/Render/Embed.php

-
message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\: 'ezlocation', 2\\?\\: numeric\\-string\\}\\.$#"
count: 1
path: src/lib/eZ/RichText/Converter/Render/Embed.php

-
message: "#^PHPDoc tag @var has invalid value \\(\\$embed \\\\DOMElement\\)\\: Unexpected token \"\\$embed\", expected type at offset 9$#"
count: 1
Expand Down Expand Up @@ -1105,6 +1165,16 @@ parameters:
count: 1
path: src/lib/eZ/RichText/RelationProcessor.php

-
message: "#^Offset 1 does not exist on array\\{0\\?\\: string, 1\\?\\: non\\-empty\\-string, 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/RichText/RelationProcessor.php

-
message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\?\\: non\\-empty\\-string, 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/RichText/RelationProcessor.php

-
message: "#^Method EzSystems\\\\EzPlatformRichText\\\\eZ\\\\RichText\\\\RendererInterface\\:\\:renderContentEmbed\\(\\) has parameter \\$parameters with no value type specified in iterable type array\\.$#"
count: 1
Expand Down Expand Up @@ -1150,6 +1220,16 @@ parameters:
count: 1
path: src/lib/eZ/RichText/Validator/InternalLinkValidator.php

-
message: "#^Offset 1 does not exist on array\\{0\\?\\: string, 1\\?\\: non\\-empty\\-string, 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/RichText/Validator/InternalLinkValidator.php

-
message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\?\\: non\\-empty\\-string, 2\\?\\: string, 3\\?\\: string\\}\\.$#"
count: 1
path: src/lib/eZ/RichText/Validator/InternalLinkValidator.php

-
message: "#^Parameter \\#1 \\$locationId of method eZ\\\\Publish\\\\SPI\\\\Persistence\\\\Content\\\\Location\\\\Handler\\:\\:load\\(\\) expects int, string given\\.$#"
count: 1
Expand Down Expand Up @@ -1629,10 +1709,7 @@ parameters:
message: "#^Cannot access property \\$id on eZ\\\\Publish\\\\API\\\\Repository\\\\Values\\\\Content\\\\Field\\|null\\.$#"
count: 1
path: tests/integration/eZ/API/RichTextFieldTypeIntegrationTest.php
-
message: "#^Cannot call method fetchOne\\(\\) on Doctrine\\\\DBAL\\\\ForwardCompatibility\\\\Result\\|int\\|string\\.$#"
count: 1
path: tests/integration/eZ/API/RichTextFieldTypeIntegrationTest.php

-
message: "#^Cannot access property \\$value on eZ\\\\Publish\\\\API\\\\Repository\\\\Values\\\\Content\\\\Field\\|null\\.$#"
count: 1
Expand All @@ -1648,6 +1725,11 @@ parameters:
count: 1
path: tests/integration/eZ/API/RichTextFieldTypeIntegrationTest.php

-
message: "#^Cannot call method fetchOne\\(\\) on Doctrine\\\\DBAL\\\\ForwardCompatibility\\\\Result\\|int\\|string\\.$#"
count: 1
path: tests/integration/eZ/API/RichTextFieldTypeIntegrationTest.php

-
message: "#^Method EzSystems\\\\IntegrationTests\\\\EzPlatformRichText\\\\eZ\\\\API\\\\RichTextFieldTypeIntegrationTest\\:\\:__construct\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
Expand Down
15 changes: 4 additions & 11 deletions src/lib/eZ/RichText/Resources/schemas/docbook/docbook.iso.sch
Original file line number Diff line number Diff line change
Expand Up @@ -253,20 +253,13 @@
<s:let name="lowerCase" value="'abcdefghijklmnopqrstuvwxyz'"/>
<s:rule context="db:link">
<!-- Using translate() because we don't have XPath 2, so we can't use lower-case(). -->
<s:assert test="starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'http://') or
starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'https://') or
<s:assert test="starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'http') or
starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'mailto:') or
starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezcontent://') or
starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezlocation://') or
starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezremote://') or
starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezurl://') or
starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'tel:') or
starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ez') or
starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), '/') or
starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), '#')"
mode="schematron-get-full-path-2">links must start with one of: http://, https://, mailto:, ezcontent://, ezlocation://, ezremote://, ezurl://, /, #</s:assert>
<s:assert test="not(contains(@*[name()='xlink:href'], '&lt;') or
contains(@*[name()='xlink:href'], '&gt;') or
contains(@*[name()='xlink:href'], '&quot;'))"
mode="schematron-get-full-path-2">using characters [&lt; &gt; &quot;] in links is not allowed</s:assert>
mode="schematron-get-full-path-2">links must start with one of: http://, https://, mailto:, tel:, ezcontent://, ezlocation://, ezremote://, ezurl://, /, #</s:assert>
</s:rule>
</s:pattern>
</s:schema>
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,4 @@
<axsl:template match="db:link" priority="1000" mode="M3"><svrl:fired-rule xmlns:svrl="http://purl.oclc.org/dsdl/svrl" context="db:link"/>

<!--ASSERT -->
<axsl:choose><axsl:when test="starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'http://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'https://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'mailto:') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezcontent://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezlocation://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezremote://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezurl://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), '/') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), '#')"/><axsl:otherwise><svrl:failed-assert xmlns:svrl="http://purl.oclc.org/dsdl/svrl" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:schold="http://www.ascc.net/xml/schematron" test="starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'http://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'https://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'mailto:') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezcontent://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezlocation://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezremote://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ezurl://') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), '/') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), '#')"><axsl:attribute name="location"><axsl:apply-templates select="." mode="schematron-get-full-path-2"/></axsl:attribute><svrl:text>links must start with one of: http://, https://, mailto:, ezcontent://, ezlocation://, ezremote://, ezurl://, /, #</svrl:text></svrl:failed-assert></axsl:otherwise></axsl:choose>

<!--ASSERT -->
<axsl:choose><axsl:when test="not(contains(@*[name()='xlink:href'], '&lt;') or contains(@*[name()='xlink:href'], '&gt;') or contains(@*[name()='xlink:href'], '&quot;'))"/><axsl:otherwise><svrl:failed-assert xmlns:svrl="http://purl.oclc.org/dsdl/svrl" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:schold="http://www.ascc.net/xml/schematron" test="not(contains(@*[name()='xlink:href'], '&lt;') or contains(@*[name()='xlink:href'], '&gt;') or contains(@*[name()='xlink:href'], '&quot;'))"><axsl:attribute name="location"><axsl:apply-templates select="." mode="schematron-get-full-path-2"/></axsl:attribute><svrl:text>using characters [&lt; &gt; "] in links is not allowed</svrl:text></svrl:failed-assert></axsl:otherwise></axsl:choose><axsl:apply-templates select="*|comment()|processing-instruction()" mode="M3"/></axsl:template><axsl:template match="text()" priority="-1" mode="M3"/><axsl:template match="@*|node()" priority="-2" mode="M3"><axsl:apply-templates select="*|comment()|processing-instruction()" mode="M3"/></axsl:template></axsl:stylesheet>
<axsl:choose><axsl:when test="starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'http') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'mailto:') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'tel:') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ez') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), '/') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), '#')"/><axsl:otherwise><svrl:failed-assert xmlns:svrl="http://purl.oclc.org/dsdl/svrl" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:schold="http://www.ascc.net/xml/schematron" test="starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'http') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'mailto:') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'tel:') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), 'ez') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), '/') or starts-with(translate(@*[name()='xlink:href'], $upperCase, $lowerCase), '#')"><axsl:attribute name="location"><axsl:apply-templates select="." mode="schematron-get-full-path-2"/></axsl:attribute><svrl:text>links must start with one of: http://, https://, mailto:, tel:, ezcontent://, ezlocation://, ezremote://, ezurl://, /, #</svrl:text></svrl:failed-assert></axsl:otherwise></axsl:choose><axsl:apply-templates select="*|comment()|processing-instruction()" mode="M3"/></axsl:template><axsl:template match="text()" priority="-1" mode="M3"/><axsl:template match="@*|node()" priority="-2" mode="M3"><axsl:apply-templates select="*|comment()|processing-instruction()" mode="M3"/></axsl:template></axsl:stylesheet>
13 changes: 3 additions & 10 deletions tests/lib/eZ/FieldType/RichTextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public function providerForTestValidate()
[
new ValidationError(
"Validation of XML content failed:\n" .
'/section/para/link: links must start with one of: http://, https://, mailto:, ezcontent://, ezlocation://, ezremote://, ezurl://, /, #',
'/section/para/link: links must start with one of: http://, https://, mailto:, tel:, ezcontent://, ezlocation://, ezremote://, ezurl://, /, #',
null,
[],
'xml'
Expand All @@ -239,7 +239,7 @@ public function providerForTestValidate()
[
new ValidationError(
"Validation of XML content failed:\n" .
'/section/para/link: links must start with one of: http://, https://, mailto:, ezcontent://, ezlocation://, ezremote://, ezurl://, /, #',
'/section/para/link: links must start with one of: http://, https://, mailto:, tel:, ezcontent://, ezlocation://, ezremote://, ezurl://, /, #',
null,
[],
'xml'
Expand All @@ -252,13 +252,6 @@ public function providerForTestValidate()
<para><link xlink:href="https://example.com/foo&lt;bar">link</link></para>
</section>',
[
new ValidationError(
"Validation of XML content failed:\n" .
'/section/para/link: using characters [< > "] in links is not allowed',
null,
[],
'xml'
),
],
],
[
Expand All @@ -269,7 +262,7 @@ public function providerForTestValidate()
[
new ValidationError(
"Validation of XML content failed:\n" .
'/section/para/link: links must start with one of: http://, https://, mailto:, ezcontent://, ezlocation://, ezremote://, ezurl://, /, #',
'/section/para/link: links must start with one of: http://, https://, mailto:, tel:, ezcontent://, ezlocation://, ezremote://, ezurl://, /, #',
null,
[],
'xml'
Expand Down

0 comments on commit acb0fa0

Please sign in to comment.