Skip to content

Commit

Permalink
feat: restrict SVG title element to HTML elements
Browse files Browse the repository at this point in the history
This commit updates the content model of the SVG title element to allow
any text or HTML elements, but reject any non-HTML element.

- use NVDL to reject non-HTML namespaces
- the master XHTML schema is now the NVDL schema
- add an element class to include all HTML elements

Fix #1342
  • Loading branch information
rdeltour committed Nov 27, 2022
1 parent 3086258 commit 8631b7d
Show file tree
Hide file tree
Showing 26 changed files with 224 additions and 107 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/adobe/epubcheck/ops/OPSChecker.java
Expand Up @@ -56,7 +56,7 @@ public class OPSChecker extends PublicationResourceChecker
.putAll(Predicates.and(mimetype("application/xhtml+xml"), version(EPUBVersion.VERSION_2)),
XMLValidators.XHTML_20_NVDL, XMLValidators.XHTML_20_SCH, XMLValidators.IDUNIQUE_20_SCH)
.putAll(Predicates.and(mimetype("application/xhtml+xml"), version(EPUBVersion.VERSION_3)),
XMLValidators.XHTML_30_RNC, XMLValidators.XHTML_30_SCH, XMLValidators.SVG_INFORMATIVE_30_NVDL)
XMLValidators.XHTML_30_NVDL, XMLValidators.SVG_INFORMATIVE_30_NVDL)
.putAll(Predicates.and(mimetype("image/svg+xml"), version(EPUBVersion.VERSION_2)),
XMLValidators.SVG_20_NVDL, XMLValidators.IDUNIQUE_20_SCH)
.putAll(Predicates.and(mimetype("image/svg+xml"), version(EPUBVersion.VERSION_3)),
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/adobe/epubcheck/xml/XMLValidators.java
Expand Up @@ -45,6 +45,7 @@ public enum XMLValidators
XHTML_20_SCH("schema/20/sch/xhtml.sch"),
XHTML_30_SCH("schema/30/epub-xhtml-30.sch"),
XHTML_30_RNC("schema/30/epub-xhtml-30.rnc"),
XHTML_30_NVDL("schema/30/epub-xhtml-30.nvdl"),
XHTML_EDUPUB_STRUCTURE_SCH("schema/30/edupub/edu-structure.sch"),
XHTML_EDUPUB_SEMANTICS_SCH("schema/30/edupub/edu-semantics.sch"),
XHTML_DATANAV_SCH("schema/30/datanav/datanav-xhtml.sch"),
Expand Down
24 changes: 24 additions & 0 deletions src/main/resources/com/adobe/epubcheck/schema/30/epub-svg-30.nvdl
Expand Up @@ -5,6 +5,7 @@
<validate schema="epub-svg-30.rnc" schemaType="application/relax-ng-compact-syntax"
useMode="allowForeignNS">
<context path="foreignObject" useMode="attachAnyNS"/>
<context path="title" useMode="allowOnlyHTML"/>
</validate>
<validate schema="epub-svg-30.sch" useMode="attachAnyNS"/>
</namespace>
Expand Down Expand Up @@ -34,4 +35,27 @@
<attach/>
</anyNamespace>
</mode>
<mode name="allowOnlyHTML">
<namespace ns="http://www.w3.org/1999/xhtml">
<attach/>
</namespace>
<namespace ns="http://www.idpf.org/2007/ops" match="attributes">
<attach/>
</namespace>
<namespace ns="http://www.w3.org/1999/xlink" match="attributes">
<attach/>
</namespace>
<namespace ns="http://www.w3.org/XML/1998/namespace" match="attributes">
<attach/>
</namespace>
<namespace ns="" match="attributes">
<attach/>
</namespace>
<anyNamespace match="attributes">
<allow/>
</anyNamespace>
<anyNamespace>
<reject/>
</anyNamespace>
</mode>
</rules>
@@ -1,17 +1,17 @@
namespace svg = "http://www.w3.org/2000/svg"

include "./mod/epub-xhtml.rnc" {
include "./mod/epub-xhtml-inc.rnc" {
start = svg
}
include "./mod/epub-mathml3.rnc"
include "./mod/epub-svg-inc.rnc"

svg.title.content |= common.elem.phrasing
svg.title.content |= common.inner.anyhtml

svg.foreignObject.content |=
( body.elem
| common.inner.flow
| math
)

mtext.content |= common.elem.phrasing
mtext.content |= common.elem.phrasing
Expand Up @@ -17,14 +17,5 @@ SVG.Core.attrib &= aria.global?
SVG.Core.extra.attrib &= epub.type.attr?

## Do not check restricted elements, they are checked in normative schemas
SVG.foreignObject.content |= any.content
SVG.title.content |= any.content

## Anything

## Any attribute from any namespace, other than the special cases
any.attr = attribute * { text }*
## Any element from any namespace, other than the special cases
any.elem = element * { any.content & any.attr }
## Any content from any namespace
any.content = text & any.elem*
SVG.foreignObject.content |= common.inner.anything
SVG.title.content |= common.inner.anything
@@ -1,15 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0" startMode="html">
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"
xmlns:svg="http://www.w3.org/2000/svg" startMode="html">
<mode name="html">
<namespace ns="http://www.w3.org/1999/xhtml">
<validate schema="epub-xhtml-30.rnc" schemaType="application/relax-ng-compact-syntax"
useMode="attach"/>
useMode="attach">
<context path="title" useMode="allowOnlyHTML"/>
</validate>
<validate schema="epub-xhtml-30.sch" useMode="attach"/>
</namespace>
</mode>
<mode name="attach">
<namespace ns="http://www.w3.org/2000/svg">
<attach>
<context path="title" useMode="allowOnlyHTML"/>
</attach>
</namespace>
<anyNamespace>
<attach/>
</anyNamespace>
</mode>
<mode name="allowOnlyHTML">
<namespace ns="http://www.w3.org/1999/xhtml">
<attach/>
</namespace>
<namespace ns="http://www.idpf.org/2007/ops" match="attributes">
<attach/>
</namespace>
<namespace ns="http://www.w3.org/1999/xlink" match="attributes">
<attach/>
</namespace>
<namespace ns="http://www.w3.org/XML/1998/namespace" match="attributes">
<attach/>
</namespace>
<namespace ns="" match="attributes">
<attach/>
</namespace>
<anyNamespace match="attributes">
<allow/>
</anyNamespace>
<anyNamespace>
<reject/>
</anyNamespace>
</mode>
</rules>
@@ -1,6 +1,6 @@
namespace svg = "http://www.w3.org/2000/svg"

include "./mod/epub-xhtml.rnc"
include "./mod/epub-xhtml-inc.rnc"
include "./mod/epub-mathml3.rnc"
include "./mod/epub-svg-inc.rnc" {
svg.attr.id = attribute id { datatype.html5.token }?
Expand All @@ -11,7 +11,7 @@ common.elem.phrasing |= math

math.attributes &= aria.global?

svg.title.content |= common.elem.phrasing
svg.title.content |= common.inner.anyhtml

svg.foreignObject.content |=
( common.inner.flow
Expand Down
Expand Up @@ -152,11 +152,6 @@
<param name="descendant" value="h:label"/>
</pattern>

<pattern id="descendant-svgtitle-svg" is-a="disallowed-descendants">
<param name="ancestor" value="svg:title"/>
<param name="descendant" value="svg:*"/>
</pattern>

<pattern id="bdo-dir" is-a="required-attr">
<param name="elem" value="h:bdo"/>
<param name="attr" value="dir"/>
Expand Down
Expand Up @@ -27,7 +27,7 @@ svg.foreignObject.content = notAllowed
### SVG title element restrictions
svg.title =
element title { any.attr & svg.title.content }
svg.title.content = text
svg.title.content = text

## Anything

Expand Down
@@ -0,0 +1,18 @@

# #####################################################################
## RELAX NG Schema for EPUB HTML 5: For inclusion in master schema #
# #####################################################################

## Include the main XHTML schema

include "./epub-xhtml.rnc"

## HTML fragments

# Note: the default HMTL schema does not define such a category, so we
# do our best to include what makes sense here

common.inner.anyhtml =
html.elem
| body.elem
| common.inner.flow
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<html xmlns:epub="http://www.idpf.org/2007/ops" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head epub:type="document">
<meta charset="utf-8"/>
<title>Minimal EPUB</title>
</head>
Expand Down
Expand Up @@ -101,6 +101,8 @@ Feature: EPUB 3 — Content Documents — SVG

### 6.2.3 Restrictions on SVG

#### `foreignObject` element

@spec @xref:sec-svg-restrictions
Scenario: Verify that `foreignObject` conforming to the rules is allowed
When checking document 'foreignObject-valid.svg'
Expand Down Expand Up @@ -132,32 +134,35 @@ Feature: EPUB 3 — Content Documents — SVG
And the message contains 'element "body" not allowed here'
And no other errors or warnings are reported

@spec @xref:sec-svg-restrictions
Scenario: Report HTML validation errors within `foreignObject` content
When checking document 'foreignObject-html-invalid-error.svg'
Then error RSC-005 is reported
And the message contains 'attribute "href" not allowed here'
And no other errors or warnings are reported

@spec @xref:sec-svg-restrictions
Scenario: Verify `title` can contain text
When checking document 'title-text-valid.svg'
Then no errors or warnings are reported
#### `title` element

@spec @xref:sec-svg-restrictions
Scenario: Verify `title` can contain HTML phrasing content
When checking document 'title-phrasing-content-valid.svg'
Scenario: Verify `title` valid content model
When checking document 'title-content-valid.svg'
Then no errors or warnings are reported

@spec @xref:sec-svg-restrictions
Scenario: Report `title` with non-phrasing content
When checking document 'title-not-phrasing-content-error.svg'
Scenario: Report `title` with non-HTML elements
When checking document 'title-content-not-html-error.svg'
Then error RSC-005 is reported
And the message contains 'elements from namespace "https://example.org" are not allowed'
Then error RSC-005 is reported
And the message contains 'element "h1" not allowed here'
And the message contains 'elements from namespace "http://www.w3.org/2000/svg" are not allowed'
And no other errors or warnings are reported

@spec @xref:sec-svg-restrictions
Scenario: Report HTML validation errors within `title` content
When checking document 'title-html-invalid-error.svg'
When checking document 'title-content-invalid-html-error.svg'
Then error RSC-005 is reported
And the message contains 'attribute "href" not allowed here'
Then error RSC-005 is reported
And the message contains 'element "body" not allowed here'
And no other errors or warnings are reported

Expand Up @@ -985,22 +985,20 @@ Feature: EPUB 3 — Content Documents — XHTML
And the message contains 'element "title" not allowed here'
And no other errors or warnings are reported

Scenario: Verify `title` can contain text
When checking document 'svg-title-text-valid.xhtml'
Scenario: Verify `title` valid content model
When checking document 'svg-title-content-valid.xhtml'
Then no errors or warnings are reported

Scenario: Verify `title` can contain HTML phrasing content
When checking document 'svg-title-phrasing-content-valid.xhtml'
Then no errors or warnings are reported

Scenario: Report `title` with non-phrasing content
When checking document 'svg-title-not-phrasing-content-error.xhtml'
Scenario: Report `title` with non-HTML elements
When checking document 'svg-title-content-not-html-error.xhtml'
Then error RSC-005 is reported
And the message contains 'elements from namespace "https://example.org" are not allowed'
Then error RSC-005 is reported
And the message contains 'element "h1" not allowed here'
And the message contains 'elements from namespace "http://www.w3.org/2000/svg" are not allowed'
And no other errors or warnings are reported

Scenario: Report HTML validation errors within `title` content
When checking document 'svg-title-html-invalid-error.xhtml'
When checking document 'svg-title-content-invalid-html-error.xhtml'
Then error RSC-005 is reported
And the message contains 'attribute "href" not allowed here'
And no other errors or warnings are reported
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta charset="utf-8" />
<title>Test</title>
</head>
<body>
<h1>Test</h1>
<svg width="12cm" height="4cm" viewBox="0 0 1200 400" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Test</title>
<desc>Non-HTML content</desc>
<g>
<title><not:html xmlns:not="https://example.org">not HTML</not:html></title>
</g>
<g>
<title><body xmlns="http://www.w3.org/1999/xhtml">
<svg xmlns="http://www.w3.org/2000/svg">
<title>Inner SVG</title>
<desc>Disallowed</desc>
</svg>
</body></title>
</g>
</svg>
</body>
</html>
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta charset="utf-8" />
<title>Test</title>
</head>
<body>
<h1>Test</h1>
<svg width="12cm" height="4cm" viewBox="0 0 1200 400" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>title</title>
<desc>Example</desc>
<g>
<title>Plain text</title>
</g>
<g>
<title><span xmlns="http://www.w3.org/1999/xhtml">html phrasing content</span></title>
</g>
<g>
<title><h1 xmlns="http://www.w3.org/1999/xhtml">html flow content</h1></title>
</g>
<g>
<title><body xmlns="http://www.w3.org/1999/xhtml">html non-categorized elements</body></title>
</g>
<g>
<title>some <span xmlns="http://www.w3.org/1999/xhtml">mixed</span> content</title>
</g>
<g>
<title><html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head><title>full html document</title></head><body></body></html>
</title>
</g>
</svg>
</body>
</html>

This file was deleted.

This file was deleted.

0 comments on commit 8631b7d

Please sign in to comment.