- fix NPE in XMLReader when no handler is found for the image - prevent SVGReader from closing the input stream if the image actually isn't SVG - reduce log level in SVGReader and XMLReader to avoid "false positive" (read error reported whereas the image format actually isn't recognized). This may hide regular I/O errors to the end-user, but I assume this will be rare enough compared to the annoyance of such messages when third-party plugins are used. Patch submitted by Max Berger (max.at.berger.name) git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@542447 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_94
@@ -87,6 +87,8 @@ public class ImageReaderFactory { | |||
return info; | |||
} | |||
} | |||
log.warn("No ImageReader found for " + uri); | |||
in.close(); | |||
} catch (IOException ex) { | |||
log.error("Error while recovering Image Informations (" | |||
+ uri + ")", ex); |
@@ -43,6 +43,7 @@ import org.apache.fop.image.XMLImage; | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.apps.FOUserAgent; | |||
import org.apache.fop.svg.SVGUserAgent; | |||
import org.apache.fop.util.UnclosableInputStream; | |||
/** | |||
* ImageReader object for SVG document image type. | |||
@@ -112,58 +113,7 @@ public class SVGReader implements ImageReader { | |||
// parse document and get the size attributes of the svg element | |||
try { | |||
int length = 5; | |||
fis.mark(length); | |||
byte[] b = new byte[length]; | |||
fis.read(b); | |||
String start = new String(b); | |||
fis.reset(); | |||
//TODO "true ||" here is a hack to improve SVG detection rate. Please improve. | |||
if (true || start.equals("<?xml")) { | |||
// we have xml, might be another doc | |||
// so stop batik from closing the stream | |||
final InputStream input = fis; | |||
fis = | |||
new InputStream() { | |||
public int read() throws IOException { | |||
return input.read(); | |||
} | |||
public int read(byte[] b) throws IOException { | |||
return input.read(b); | |||
} | |||
public int read(byte[] b, int off, int len) | |||
throws IOException { | |||
return input.read(b, off, len); | |||
} | |||
public long skip(long n) throws IOException { | |||
return input.skip(n); | |||
} | |||
public int available() throws IOException { | |||
return input.available(); | |||
} | |||
public void mark(int rl) { | |||
input.mark(rl); | |||
} | |||
public boolean markSupported() { | |||
return input.markSupported(); | |||
} | |||
public void reset() throws IOException { | |||
input.reset(); | |||
} | |||
public void close() throws IOException { | |||
//ignore | |||
} | |||
}; | |||
} | |||
fis = new UnclosableInputStream(fis); | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
@@ -175,7 +125,7 @@ public class SVGReader implements ImageReader { | |||
info.mimeType = getMimeType(); | |||
info.str = SVGDOMImplementation.SVG_NAMESPACE_URI; | |||
length = fis.available(); | |||
int length = fis.available(); | |||
fis.mark(length + 1); | |||
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory( | |||
XMLImage.getParserName()); | |||
@@ -217,7 +167,7 @@ public class SVGReader implements ImageReader { | |||
batik = false; | |||
log.warn("Batik not in class path", ncdfe); | |||
return null; | |||
} catch (Exception e) { | |||
} catch (IOException e) { | |||
// If the svg is invalid then it throws an IOException | |||
// so there is no way of knowing if it is an svg document | |||
@@ -31,6 +31,7 @@ import org.w3c.dom.Element; | |||
// FOP | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.util.UnclosableInputStream; | |||
import org.apache.fop.apps.FOUserAgent; | |||
// Commons-Logging | |||
@@ -63,8 +64,8 @@ public class XMLReader implements ImageReader { | |||
FOUserAgent ua) | |||
throws IOException { | |||
FopImage.ImageInfo info = loadImage(uri, fis, ua); | |||
info.originalURI = uri; | |||
if (info != null) { | |||
info.originalURI = uri; | |||
IOUtils.closeQuietly(fis); | |||
} | |||
return info; | |||
@@ -98,16 +99,17 @@ public class XMLReader implements ImageReader { | |||
/** | |||
* Creates an ImageInfo object from an XML image read from a stream. | |||
* | |||
* @param is The InputStream | |||
* @param input The InputStream | |||
* @param ua The user agent | |||
* @return An ImageInfo object describing the image | |||
*/ | |||
public FopImage.ImageInfo createDocument(InputStream is, FOUserAgent ua) { | |||
public FopImage.ImageInfo createDocument(final InputStream input, final FOUserAgent ua) { | |||
Document doc = null; | |||
FopImage.ImageInfo info = new FopImage.ImageInfo(); | |||
info.mimeType = getMimeType(); | |||
try { | |||
final InputStream is = new UnclosableInputStream(input); | |||
int length = is.available(); | |||
is.mark(length); | |||
@@ -128,14 +130,21 @@ public class XMLReader implements ImageReader { | |||
} | |||
} | |||
} catch (Exception e) { | |||
log.warn("Error while constructing image from XML", e); | |||
log.debug("Error while constructing image from XML", e); | |||
try { | |||
is.reset(); | |||
input.reset(); | |||
} catch (IOException ioe) { | |||
// throw the original exception, not this one | |||
} | |||
return null; | |||
} | |||
if (info != null) { | |||
try { | |||
input.close(); | |||
} catch (IOException io) { | |||
// ignore | |||
} | |||
} | |||
return info; | |||
} | |||
@@ -0,0 +1,46 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.util; | |||
import java.io.FilterInputStream; | |||
import java.io.InputStream; | |||
/** | |||
* Provides an InputStreamFilter which avoids closing the original stream. | |||
*/ | |||
public class UnclosableInputStream extends FilterInputStream { | |||
/** | |||
* Default constructor. | |||
* | |||
* @param in the Stream to filter. | |||
*/ | |||
public UnclosableInputStream(InputStream in) { | |||
super(in); | |||
} | |||
/** | |||
* Does <strong>not</strong> close the original stream. | |||
*/ | |||
public void close() { | |||
// ignore | |||
} | |||
} |