-
Bug
-
Resolution: Fixed
-
P4
-
8, 9
-
b143
-
x86
-
windows_7
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8259581 | openjdk8u292 | Elliott Baron | P4 | Resolved | Fixed | b01 |
JDK-8259367 | 8u291 | Maheshkumar Bollapragada | P4 | Resolved | Fixed | b01 |
JDK-8262638 | emb-8u291 | Vaibhav Choudhary | P4 | Resolved | Fixed | team |
FULL PRODUCT VERSION :
A DESCRIPTION OF THE PROBLEM :
(1) The specification of org.w3c.dom.Element.getElementsByTagName(String name) states:
>The special value "*" matches all tags.
In the class javax.imageio.metadata.IIOMetadataNode, which implements the above interface, "*" is not handled, so using it returns no elements. This is the offending code and fix:
private void getElementsByTagName(String name, List l) {
- if (nodeName.equals(name)) {
+ if (nodeName.equals(name) || "*".equals(name)) {
l.add(this);
}
Node child = getFirstChild();
while (child != null) {
((IIOMetadataNode)child).getElementsByTagName(name, l);
child = child.getNextSibling();
}
}
(2) The specification of org.w3c.dom.NodeList.item(int index) states:
>Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
In the class javax.imageio.metadata.IIONodeList, which implements the above interface, the range check has a trivial typo which means it throws an unexpected IndexOutOfBoundsException if index equals the number of nodes. This is offending code and fix:
public Node item(int index) {
- if (index < 0 || index > nodes.size()) {
+ if (index < 0 || index >= nodes.size()) {
return null;
}
return (Node)nodes.get(index);
}
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class ImageMetadataNodeBugs {
public static void main(String[] args) throws IOException {
// Generate some trivial image and save it to a temporary array
ByteArrayOutputStream tmp = new ByteArrayOutputStream();
ImageIO.write(new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB), "gif", tmp);
// Read it back in
ImageInputStream in = new MemoryCacheImageInputStream(
new ByteArrayInputStream(tmp.toByteArray()));
ImageReader reader = ImageIO.getImageReaders(in).next();
reader.setInput(in);
// Retrieve standard image metadata tree
IIOMetadata meta = reader.getImageMetadata(0);
if (meta == null || !meta.isStandardMetadataFormatSupported())
throw new Error("Test failure: Missing metadata");
Element root = (Element)meta.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
ArrayList<String> problems = new ArrayList<>();
// Test getElementsByTagName("*")
if (root.getElementsByTagName("*").getLength() == 0)
problems.add("getElementsByTagName(\"*\") doesn't return anything");
// Test IIONodeList.item()
try {
NodeList nodeList = root.getElementsByTagName(root.getFirstChild().getNodeName());
if (!(nodeList.item(-1) == null))
problems.add("nodeList.item(-1) should be null");
if (!(nodeList.item(0) != null))
problems.add("nodeList.item(0) should be non-null");
if (!(nodeList.item(nodeList.getLength() - 1) != null))
problems.add("nodeList.item(length - 1) should be non-null");
if (!(nodeList.item(nodeList.getLength()) == null))
problems.add("nodeList.item(length) should be null");
} catch (IndexOutOfBoundsException e) {
problems.add("nodeList.item throws unexpected IOOBE");
}
System.out.println("Result: " + (problems.isEmpty() ? "PASS" : "FAIL"));
for (String p : problems) System.out.println("- " + p);
}
}
---------- END SOURCE ----------
A DESCRIPTION OF THE PROBLEM :
(1) The specification of org.w3c.dom.Element.getElementsByTagName(String name) states:
>The special value "*" matches all tags.
In the class javax.imageio.metadata.IIOMetadataNode, which implements the above interface, "*" is not handled, so using it returns no elements. This is the offending code and fix:
private void getElementsByTagName(String name, List l) {
- if (nodeName.equals(name)) {
+ if (nodeName.equals(name) || "*".equals(name)) {
l.add(this);
}
Node child = getFirstChild();
while (child != null) {
((IIOMetadataNode)child).getElementsByTagName(name, l);
child = child.getNextSibling();
}
}
(2) The specification of org.w3c.dom.NodeList.item(int index) states:
>Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
In the class javax.imageio.metadata.IIONodeList, which implements the above interface, the range check has a trivial typo which means it throws an unexpected IndexOutOfBoundsException if index equals the number of nodes. This is offending code and fix:
public Node item(int index) {
- if (index < 0 || index > nodes.size()) {
+ if (index < 0 || index >= nodes.size()) {
return null;
}
return (Node)nodes.get(index);
}
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class ImageMetadataNodeBugs {
public static void main(String[] args) throws IOException {
// Generate some trivial image and save it to a temporary array
ByteArrayOutputStream tmp = new ByteArrayOutputStream();
ImageIO.write(new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB), "gif", tmp);
// Read it back in
ImageInputStream in = new MemoryCacheImageInputStream(
new ByteArrayInputStream(tmp.toByteArray()));
ImageReader reader = ImageIO.getImageReaders(in).next();
reader.setInput(in);
// Retrieve standard image metadata tree
IIOMetadata meta = reader.getImageMetadata(0);
if (meta == null || !meta.isStandardMetadataFormatSupported())
throw new Error("Test failure: Missing metadata");
Element root = (Element)meta.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
ArrayList<String> problems = new ArrayList<>();
// Test getElementsByTagName("*")
if (root.getElementsByTagName("*").getLength() == 0)
problems.add("getElementsByTagName(\"*\") doesn't return anything");
// Test IIONodeList.item()
try {
NodeList nodeList = root.getElementsByTagName(root.getFirstChild().getNodeName());
if (!(nodeList.item(-1) == null))
problems.add("nodeList.item(-1) should be null");
if (!(nodeList.item(0) != null))
problems.add("nodeList.item(0) should be non-null");
if (!(nodeList.item(nodeList.getLength() - 1) != null))
problems.add("nodeList.item(length - 1) should be non-null");
if (!(nodeList.item(nodeList.getLength()) == null))
problems.add("nodeList.item(length) should be null");
} catch (IndexOutOfBoundsException e) {
problems.add("nodeList.item throws unexpected IOOBE");
}
System.out.println("Result: " + (problems.isEmpty() ? "PASS" : "FAIL"));
for (String p : problems) System.out.println("- " + p);
}
}
---------- END SOURCE ----------
- backported by
-
JDK-8259367 IIOMetadataNode bugs in getElementsByTagName and NodeList.item methods
-
- Resolved
-
-
JDK-8259581 IIOMetadataNode bugs in getElementsByTagName and NodeList.item methods
-
- Resolved
-
-
JDK-8262638 IIOMetadataNode bugs in getElementsByTagName and NodeList.item methods
-
- Resolved
-