Skip to content

Commit 003234a

Browse files
committed
feat: check stylesheets declared in SVG
This enables checking of CSS declared in SVG inline `style` element, as well as stylesheets declared in `<?xml-stylesheet?>` processing instructions. Fix #1450
1 parent 9f75a1d commit 003234a

File tree

54 files changed

+556
-30
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+556
-30
lines changed

src/main/java/com/adobe/epubcheck/css/CSSHandler.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ else if (uriOrString.getType() == CssConstruct.Type.STRING)
159159
}
160160
if (uri != null)
161161
{
162-
resolveAndRegister(uri, line, col, atRule.toCssString(), Reference.Type.GENERIC);
162+
resolveAndRegister(uri, line, col, atRule.toCssString(), Reference.Type.STYLESHEET);
163163
}
164164
}
165165
}
@@ -390,7 +390,10 @@ private void resolveAndRegister(String uriString, int line, int col, String cssC
390390
if (url != null && context.referenceRegistry.isPresent())
391391
{
392392
context.referenceRegistry.get().registerReference(url, type, getCorrectedEPUBLocation(line, col, cssContext));
393-
if (context.isRemote(url))
393+
// register that a remote resource was found
394+
// no need to register a remote stylesheet, as these are disallowed
395+
// and will be reported elsewhere
396+
if (type != Reference.Type.STYLESHEET && context.isRemote(url))
394397
{
395398
detectedProperties.add(ITEM_PROPERTIES.REMOTE_RESOURCES);
396399
}

src/main/java/com/adobe/epubcheck/ops/OPSHandler.java

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525
import java.util.Locale;
2626
import java.util.Stack;
2727

28+
import org.w3c.epubcheck.constants.MIMEType;
2829
import org.w3c.epubcheck.core.references.Reference;
30+
import org.w3c.epubcheck.core.references.Reference.Type;
31+
import org.xml.sax.SAXException;
2932

3033
import com.adobe.epubcheck.api.EPUBLocation;
3134
import com.adobe.epubcheck.css.CSSChecker;
@@ -40,6 +43,8 @@
4043
import com.adobe.epubcheck.xml.model.XMLElement;
4144

4245
import io.mola.galimatias.URL;
46+
import net.sf.saxon.trans.XPathException;
47+
import net.sf.saxon.tree.util.ProcInstParser;
4348

4449
public class OPSHandler extends XMLHandler
4550
{
@@ -190,6 +195,10 @@ public void startElement()
190195
Reference.Type resourceType = Reference.Type.GENERIC;
191196
if (ns != null)
192197
{
198+
if (name.equals("style"))
199+
{
200+
textNode = new StringBuilder();
201+
}
193202
if (ns.equals("http://www.w3.org/2000/svg"))
194203
{
195204
if (name.equals("lineargradient") || name.equals("radialgradient")
@@ -246,10 +255,6 @@ else if (name.equals("link"))
246255
{
247256
checkLink();
248257
}
249-
else if (name.equals("style"))
250-
{
251-
textNode = new StringBuilder();
252-
}
253258
else if (name.equals("iframe"))
254259
{
255260
checkIFrame();
@@ -341,20 +346,21 @@ public void endElement()
341346

342347
EPUBLocation currentLocation = elementLocationStack.pop();
343348

344-
if (EpubConstants.HtmlNamespaceUri.equals(ns))
349+
if ("style".equals(name))
345350
{
346-
347-
if ("style".equals(name))
351+
String style = textNode.toString();
352+
if (style.length() > 0)
348353
{
349-
String style = textNode.toString();
350-
if (style.length() > 0)
351-
{
352-
this.hasCSS = true;
353-
new CSSChecker(context, style, currentLocation.getLine(), false).check();
354-
}
355-
textNode = null;
354+
this.hasCSS = true;
355+
new CSSChecker(context, style, currentLocation.getLine(), false).check();
356356
}
357-
else if ("table".equals(name))
357+
textNode = null;
358+
}
359+
360+
if (EpubConstants.HtmlNamespaceUri.equals(ns))
361+
{
362+
363+
if ("table".equals(name))
358364
{
359365
if (tableDepth > 0)
360366
{
@@ -392,4 +398,39 @@ public void characters(char[] chars, int start, int length)
392398
}
393399
}
394400

401+
@Override
402+
public void processingInstruction(String target, String data)
403+
throws SAXException
404+
{
405+
super.processingInstruction(target, data);
406+
407+
// for SVG documents, parse 'xml-stylesheet' processing instructions
408+
if (MIMEType.SVG.is(context.mimeType) && "xml-stylesheet".equals(target))
409+
{
410+
checkXMLStylesheetPI(data);
411+
}
412+
}
413+
414+
protected void checkXMLStylesheetPI(String data)
415+
{
416+
assert data != null;
417+
try
418+
{
419+
String type = ProcInstParser.getPseudoAttribute(data, "type");
420+
if (type == null || MIMEType.CSS.is(type))
421+
{
422+
String href = ProcInstParser.getPseudoAttribute(data, "href");
423+
URL url = checkURL(href);
424+
if (url != null)
425+
{
426+
hasCSS = true;
427+
registerReference(url, Type.STYLESHEET);
428+
}
429+
}
430+
} catch (XPathException e1)
431+
{
432+
// ignore invalid declaration, must have been reported earlier
433+
}
434+
}
435+
395436
}
Lines changed: 10 additions & 0 deletions
Loading

src/test/resources/epub3/03-resources/files/file-url-in-xhtml-content-error.xhtml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
<head>
44
<meta charset="utf-8"/>
55
<title>Minimal EPUB</title>
6+
<style>
7+
@import url(file:example);
8+
</style>
69
</head>
710
<body>
811
<h1>Loomings</h1>
Lines changed: 9 additions & 0 deletions
Loading
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
3+
<head>
4+
<meta charset="utf-8"/>
5+
<title>Minimal Nav</title>
6+
</head>
7+
<body>
8+
<nav epub:type="toc">
9+
<ol>
10+
<li><a href="content_001.svg">content 001</a></li>
11+
</ol>
12+
</nav>
13+
</body>
14+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="en" unique-identifier="q">
3+
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
4+
<dc:title id="title">Minimal EPUB 3.0</dc:title>
5+
<dc:language>en</dc:language>
6+
<dc:identifier id="q">NOID</dc:identifier>
7+
<meta property="dcterms:modified">2017-06-14T00:00:01Z</meta>
8+
</metadata>
9+
<manifest>
10+
<item id="content_001" href="content_001.svg" media-type="image/svg+xml"/>
11+
<item id="nav" href="nav.xhtml" media-type="application/xhtml+xml" properties="nav"/>
12+
</manifest>
13+
<spine>
14+
<itemref idref="content_001" />
15+
</spine>
16+
</package>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
3+
<rootfiles>
4+
<rootfile full-path="EPUB/package.opf" media-type="application/oebps-package+xml"/>
5+
</rootfiles>
6+
</container>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
application/epub+zip
Lines changed: 7 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)