Skip to content

Commit

Permalink
feat: check stylesheets declared in SVG
Browse files Browse the repository at this point in the history
This enables checking of CSS declared in SVG inline `style`
element, as well as stylesheets declared in  `<?xml-stylesheet?>`
processing instructions.

Fix #1450
  • Loading branch information
rdeltour committed Dec 13, 2022
1 parent 9f75a1d commit 003234a
Show file tree
Hide file tree
Showing 54 changed files with 556 additions and 30 deletions.
7 changes: 5 additions & 2 deletions src/main/java/com/adobe/epubcheck/css/CSSHandler.java
Expand Up @@ -159,7 +159,7 @@ else if (uriOrString.getType() == CssConstruct.Type.STRING)
}
if (uri != null)
{
resolveAndRegister(uri, line, col, atRule.toCssString(), Reference.Type.GENERIC);
resolveAndRegister(uri, line, col, atRule.toCssString(), Reference.Type.STYLESHEET);
}
}
}
Expand Down Expand Up @@ -390,7 +390,10 @@ private void resolveAndRegister(String uriString, int line, int col, String cssC
if (url != null && context.referenceRegistry.isPresent())
{
context.referenceRegistry.get().registerReference(url, type, getCorrectedEPUBLocation(line, col, cssContext));
if (context.isRemote(url))
// register that a remote resource was found
// no need to register a remote stylesheet, as these are disallowed
// and will be reported elsewhere
if (type != Reference.Type.STYLESHEET && context.isRemote(url))
{
detectedProperties.add(ITEM_PROPERTIES.REMOTE_RESOURCES);
}
Expand Down
71 changes: 56 additions & 15 deletions src/main/java/com/adobe/epubcheck/ops/OPSHandler.java
Expand Up @@ -25,7 +25,10 @@
import java.util.Locale;
import java.util.Stack;

import org.w3c.epubcheck.constants.MIMEType;
import org.w3c.epubcheck.core.references.Reference;
import org.w3c.epubcheck.core.references.Reference.Type;
import org.xml.sax.SAXException;

import com.adobe.epubcheck.api.EPUBLocation;
import com.adobe.epubcheck.css.CSSChecker;
Expand All @@ -40,6 +43,8 @@
import com.adobe.epubcheck.xml.model.XMLElement;

import io.mola.galimatias.URL;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.tree.util.ProcInstParser;

public class OPSHandler extends XMLHandler
{
Expand Down Expand Up @@ -190,6 +195,10 @@ public void startElement()
Reference.Type resourceType = Reference.Type.GENERIC;
if (ns != null)
{
if (name.equals("style"))
{
textNode = new StringBuilder();
}
if (ns.equals("http://www.w3.org/2000/svg"))
{
if (name.equals("lineargradient") || name.equals("radialgradient")
Expand Down Expand Up @@ -246,10 +255,6 @@ else if (name.equals("link"))
{
checkLink();
}
else if (name.equals("style"))
{
textNode = new StringBuilder();
}
else if (name.equals("iframe"))
{
checkIFrame();
Expand Down Expand Up @@ -341,20 +346,21 @@ public void endElement()

EPUBLocation currentLocation = elementLocationStack.pop();

if (EpubConstants.HtmlNamespaceUri.equals(ns))
if ("style".equals(name))
{

if ("style".equals(name))
String style = textNode.toString();
if (style.length() > 0)
{
String style = textNode.toString();
if (style.length() > 0)
{
this.hasCSS = true;
new CSSChecker(context, style, currentLocation.getLine(), false).check();
}
textNode = null;
this.hasCSS = true;
new CSSChecker(context, style, currentLocation.getLine(), false).check();
}
else if ("table".equals(name))
textNode = null;
}

if (EpubConstants.HtmlNamespaceUri.equals(ns))
{

if ("table".equals(name))
{
if (tableDepth > 0)
{
Expand Down Expand Up @@ -392,4 +398,39 @@ public void characters(char[] chars, int start, int length)
}
}

@Override
public void processingInstruction(String target, String data)
throws SAXException
{
super.processingInstruction(target, data);

// for SVG documents, parse 'xml-stylesheet' processing instructions
if (MIMEType.SVG.is(context.mimeType) && "xml-stylesheet".equals(target))
{
checkXMLStylesheetPI(data);
}
}

protected void checkXMLStylesheetPI(String data)
{
assert data != null;
try
{
String type = ProcInstParser.getPseudoAttribute(data, "type");
if (type == null || MIMEType.CSS.is(type))
{
String href = ProcInstParser.getPseudoAttribute(data, "href");
URL url = checkURL(href);
if (url != null)
{
hasCSS = true;
registerReference(url, Type.STYLESHEET);
}
}
} catch (XPathException e1)
{
// ignore invalid declaration, must have been reported earlier
}
}

}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -3,6 +3,9 @@
<head>
<meta charset="utf-8"/>
<title>Minimal EPUB</title>
<style>
@import url(file:example);
</style>
</head>
<body>
<h1>Loomings</h1>
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,14 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
<head>
<meta charset="utf-8"/>
<title>Minimal Nav</title>
</head>
<body>
<nav epub:type="toc">
<ol>
<li><a href="content_001.svg">content 001</a></li>
</ol>
</nav>
</body>
</html>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="en" unique-identifier="q">
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title id="title">Minimal EPUB 3.0</dc:title>
<dc:language>en</dc:language>
<dc:identifier id="q">NOID</dc:identifier>
<meta property="dcterms:modified">2017-06-14T00:00:01Z</meta>
</metadata>
<manifest>
<item id="content_001" href="content_001.svg" media-type="image/svg+xml"/>
<item id="nav" href="nav.xhtml" media-type="application/xhtml+xml" properties="nav"/>
</manifest>
<spine>
<itemref idref="content_001" />
</spine>
</package>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="EPUB/package.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
@@ -0,0 +1 @@
application/epub+zip
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
<head>
<meta charset="utf-8"/>
<title>Minimal Nav</title>
</head>
<body>
<nav epub:type="toc">
<ol>
<li><a href="content_001.svg">content 001</a></li>
</ol>
</nav>
</body>
</html>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="en" unique-identifier="q">
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title id="title">Minimal EPUB 3.0</dc:title>
<dc:language>en</dc:language>
<dc:identifier id="q">NOID</dc:identifier>
<meta property="dcterms:modified">2017-06-14T00:00:01Z</meta>
</metadata>
<manifest>
<item id="content_001" href="content_001.svg" media-type="image/svg+xml"/>
<item id="nav" href="nav.xhtml" media-type="application/xhtml+xml" properties="nav"/>
</manifest>
<spine>
<itemref idref="content_001" />
</spine>
</package>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="EPUB/package.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
@@ -0,0 +1 @@
application/epub+zip
22 changes: 20 additions & 2 deletions src/test/resources/epub3/03-resources/resources.feature
Expand Up @@ -472,6 +472,18 @@
Then error RSC-006 is reported
And no other errors or warnings are reported

@spec @xref:sec-resource-locations
Scenario: Report a remote stylesheet declared in SVG XML processing instruction
When checking EPUB 'resources-remote-stylesheet-svg-xmlpi-error'
Then error RSC-006 is reported
And no other errors or warnings are reported

@spec @xref:sec-resource-locations
Scenario: Report a remote stylesheet declared in SVG inline style import
When checking EPUB 'resources-remote-stylesheet-svg-import-error'
Then error RSC-006 is reported
And no other errors or warnings are reported

@spec @xref:sec-resource-locations
Scenario: Warn about a remote resource with a non `https` URL
When checking EPUB 'resources-remote-not-https-warning'
Expand Down Expand Up @@ -544,9 +556,15 @@
And no other errors or warnings are reported

@spec @xref:sec-file-urls
Scenario: Report a file URL used in a content document
Scenario: Report a file URL used in an XHTML content document
When checking document 'file-url-in-xhtml-content-error.xhtml'
Then error RSC-030 is reported
Then error RSC-030 is reported 2 times
And no other errors or warnings are reported

@spec @xref:sec-file-urls
Scenario: Report a file URL used in an SVG content document
When checking document 'file-url-in-svg-content-error.svg'
Then error RSC-030 is reported 2 times
And no other errors or warnings are reported

@spec @xref:sec-file-urls
Expand Down
Binary file not shown.
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<smil xmlns="http://www.w3.org/ns/SMIL" xmlns:epub="http://www.idpf.org/2007/ops" version="3.0">
<body>
<par id="par1">
<text src="content_001.svg#c01"/>
<audio src="content_001.mp3"/>
</par>
</body>
</smil>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
<head>
<meta charset="utf-8"/>
<title>Minimal Nav</title>
</head>
<body>
<nav epub:type="toc">
<ol>
<li><a href="content_001.svg">content 001</a></li>
</ol>
</nav>
</body>
</html>
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="en" unique-identifier="q">
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title id="title">Minimal EPUB 3.0</dc:title>
<dc:language>en</dc:language>
<dc:identifier id="q">NOID</dc:identifier>
<meta property="dcterms:modified">2017-06-14T00:00:01Z</meta>
<meta property="media:duration">2.5s</meta>
<meta property="media:duration" refines="#mo_001">2.5s</meta>
<meta property="media:active-class">-epub-media-overlay-active</meta>
<meta property="media:playback-active-class">-epub-media-overlay-playing</meta>
</metadata>
<manifest>
<item id="content_001" href="content_001.svg" media-type="image/svg+xml" media-overlay="mo_001"/>
<item id="mo_001" href="content_001.smil" media-type="application/smil+xml"/>
<item id="audio_001" href="content_001.mp3" media-type="audio/mpeg"/>
<item id="nav" href="nav.xhtml" media-type="application/xhtml+xml" properties="nav"/>
</manifest>
<spine>
<itemref idref="content_001" />
</spine>
</package>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
<rootfiles>
<rootfile full-path="EPUB/package.opf" media-type="application/oebps-package+xml"/>
</rootfiles>
</container>
@@ -0,0 +1 @@
application/epub+zip
Binary file not shown.
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<smil xmlns="http://www.w3.org/ns/SMIL" xmlns:epub="http://www.idpf.org/2007/ops" version="3.0">
<body>
<par id="par1">
<text src="content_001.svg#c01"/>
<audio src="content_001.mp3"/>
</par>
</body>
</smil>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 003234a

Please sign in to comment.