aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Hancock <phancock@apache.org>2011-08-22 15:14:54 +0000
committerPeter Hancock <phancock@apache.org>2011-08-22 15:14:54 +0000
commit937d2cbd25b967195ee81c74a43fa3ae4fd2d703 (patch)
tree917c75d16fc7bc6d84448d6bf23b9c95ac349abf
parentc3e956474f171eec631678fb5797e5469675b009 (diff)
downloadxmlgraphics-fop-937d2cbd25b967195ee81c74a43fa3ae4fd2d703.tar.gz
xmlgraphics-fop-937d2cbd25b967195ee81c74a43fa3ae4fd2d703.zip
Fixed a bug in AFP where an ArrayOutofBoundsException is throwqn when embedding a Page Segment.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1160298 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--build.xml1
-rw-r--r--src/java/org/apache/fop/afp/util/AFPResourceUtil.java60
-rw-r--r--status.xml4
-rw-r--r--test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java100
-rw-r--r--test/java/org/apache/fop/afp/AFPTestSuite.java1
-rw-r--r--test/java/org/apache/fop/afp/expected_named_resource.afpbin0 -> 21494 bytes
-rw-r--r--test/java/org/apache/fop/afp/expected_resource.afpbin0 -> 21511 bytes
7 files changed, 134 insertions, 32 deletions
diff --git a/build.xml b/build.xml
index 1dd2ca689..c1828a144 100644
--- a/build.xml
+++ b/build.xml
@@ -738,6 +738,7 @@ list of possible build targets.
<include name="META-INF/**"/>
<include name="**/*.xml"/>
<include name="**/*.fo"/>
+ <include name="**/*.afp"/>
</fileset>
<fileset dir="${build.dir}/test-gensrc">
<include name="**/*.xml"/>
diff --git a/src/java/org/apache/fop/afp/util/AFPResourceUtil.java b/src/java/org/apache/fop/afp/util/AFPResourceUtil.java
index 979376b3e..538f2b880 100644
--- a/src/java/org/apache/fop/afp/util/AFPResourceUtil.java
+++ b/src/java/org/apache/fop/afp/util/AFPResourceUtil.java
@@ -92,10 +92,13 @@ public final class AFPResourceUtil {
throws UnsupportedEncodingException {
//The first 8 bytes of the field data represent the resource name
byte[] nameBytes = new byte[8];
- System.arraycopy(field.getData(), 0, nameBytes, 0, 8);
- String asciiName;
- asciiName = new String(nameBytes, AFPConstants.EBCIDIC_ENCODING);
- return asciiName;
+
+ byte[] fieldData = field.getData();
+ if (fieldData.length < 8) {
+ throw new IllegalArgumentException("Field data does not contain a resource name");
+ }
+ System.arraycopy(fieldData, 0, nameBytes, 0, 8);
+ return new String(nameBytes, AFPConstants.EBCIDIC_ENCODING);
}
/**
@@ -128,12 +131,13 @@ public final class AFPResourceUtil {
public static void copyNamedResource(String name,
final InputStream in, final OutputStream out) throws IOException {
final MODCAParser parser = new MODCAParser(in);
- Collection resourceNames = new java.util.HashSet();
+ Collection<String> resourceNames = new java.util.HashSet<String>();
//Find matching "Begin" field
final UnparsedStructuredField fieldBegin;
while (true) {
- UnparsedStructuredField field = parser.readNextStructuredField();
+ final UnparsedStructuredField field = parser.readNextStructuredField();
+
if (field == null) {
throw new IOException("Requested resource '" + name
+ "' not found. Encountered resource names: " + resourceNames);
@@ -142,8 +146,10 @@ public final class AFPResourceUtil {
if (field.getSfTypeCode() != TYPE_CODE_BEGIN) { //0xA8=Begin
continue; //Not a "Begin" field
}
- String resourceName = getResourceName(field);
+ final String resourceName = getResourceName(field);
+
resourceNames.add(resourceName);
+
if (resourceName.equals(name)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Start of requested structured field found:\n"
@@ -170,45 +176,35 @@ public final class AFPResourceUtil {
if (wrapInResource) {
ResourceObject resourceObject = new ResourceObject(name) {
protected void writeContent(OutputStream os) throws IOException {
- copyStructuredFields(name, fieldBegin, parser, out);
+ copyNamedStructuredFields(name, fieldBegin, parser, out);
}
};
resourceObject.setType(ResourceObject.TYPE_PAGE_SEGMENT);
resourceObject.writeToStream(out);
} else {
- copyStructuredFields(name, fieldBegin, parser, out);
+ copyNamedStructuredFields(name, fieldBegin, parser, out);
}
}
- private static void copyStructuredFields(String name, UnparsedStructuredField fieldBegin,
- MODCAParser parser, OutputStream out) throws IOException {
- boolean inRequestedResource;
+ private static void copyNamedStructuredFields(final String name,
+ UnparsedStructuredField fieldBegin, MODCAParser parser,
+ OutputStream out) throws IOException {
- //The "Begin" field first
- out.write(MODCAParser.CARRIAGE_CONTROL_CHAR);
- fieldBegin.writeTo(out);
- UnparsedStructuredField field;
+ UnparsedStructuredField field = fieldBegin;
- //Then the rest of the fields until the corresponding "End" field
- inRequestedResource = true;
- do {
- field = parser.readNextStructuredField();
+ while (true) {
if (field == null) {
- break; //Unexpected EOF
- }
-
- if (field.getSfTypeCode() == TYPE_CODE_END) {
- String resourceName = getResourceName(field);
- if (resourceName.equals(name)) {
- inRequestedResource = false; //Signal end of loop
- }
+ throw new IOException("Ending structured field not found for resource " + name);
}
out.write(MODCAParser.CARRIAGE_CONTROL_CHAR);
field.writeTo(out);
- } while (inRequestedResource);
- if (inRequestedResource) {
- throw new IOException("Ending structured field not found for resource " + name);
+
+ if (field.getSfTypeCode() == TYPE_CODE_END
+ && fieldBegin.getSfCategoryCode() == field.getSfCategoryCode()
+ && name.equals(getResourceName(field))) {
+ break;
+ }
+ field = parser.readNextStructuredField();
}
}
-
}
diff --git a/status.xml b/status.xml
index 2295a4f60..340030f22 100644
--- a/status.xml
+++ b/status.xml
@@ -60,6 +60,10 @@
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
+ <action context="Renderers" dev="PH" type="fix">
+ Fixed a bug in AFP where an ArrayOutofBoundsException is throwqn when embedding a Page
+ Segment.
+ </action>
<action context="Renderers" dev="VH" type="add">
Added support for 128bit encryption in PDF output. Based on work by Michael Rubin.
</action>
diff --git a/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java b/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java
new file mode 100644
index 000000000..da3e023a4
--- /dev/null
+++ b/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java
@@ -0,0 +1,100 @@
+/*
+ * 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.afp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.fop.afp.util.AFPResourceUtil;
+
+/**
+ * Tests the {@link AFPResourceUtil} class.
+ */
+public class AFPResourceUtilTestCase extends TestCase {
+
+ private static final String RESOURCE_FILENAME = "expected_resource.afp";
+
+ private static final String NAMED_RESOURCE_FILENAME = "expected_named_resource.afp";
+
+ private static final String PSEG = "XFEATHER";
+
+ /**
+ * Tests copyResourceFile()
+ * @throws Exception -
+ */
+ public void testCopyResourceFile() throws Exception {
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ InputStream in = null;
+
+ try {
+ in = getClass().getResourceAsStream(RESOURCE_FILENAME);
+ AFPResourceUtil.copyResourceFile(in, baos);
+ } finally {
+ in.close();
+ }
+
+ byte[] expectedBytes = null;
+
+ try {
+ in = getClass().getResourceAsStream(RESOURCE_FILENAME);
+ expectedBytes = IOUtils.toByteArray(in);
+ } finally {
+ in.close();
+ }
+
+ assertTrue(Arrays.equals(expectedBytes, baos.toByteArray()));
+
+ }
+
+ /**
+ * Tests copyNamedResource()
+ * @throws Exception -
+ */
+ public void testCopyNamedResource() throws Exception {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ InputStream in = null;
+
+ try {
+ in = getClass().getResourceAsStream(RESOURCE_FILENAME);
+ AFPResourceUtil.copyNamedResource(PSEG, in, baos);
+ } finally {
+ in.close();
+ }
+
+ byte[] expectedBytes = null;
+
+ try {
+ in = getClass().getResourceAsStream(NAMED_RESOURCE_FILENAME);
+ expectedBytes = IOUtils.toByteArray(in);
+ } finally {
+ in.close();
+ }
+
+ assertTrue(Arrays.equals(expectedBytes, baos.toByteArray()));
+ }
+}
diff --git a/test/java/org/apache/fop/afp/AFPTestSuite.java b/test/java/org/apache/fop/afp/AFPTestSuite.java
index c32eab6ea..cb57a92ed 100644
--- a/test/java/org/apache/fop/afp/AFPTestSuite.java
+++ b/test/java/org/apache/fop/afp/AFPTestSuite.java
@@ -38,6 +38,7 @@ public class AFPTestSuite {
TestSuite suite = new TestSuite("Test suite for FOP's AFP classes");
//$JUnit-BEGIN$
suite.addTest(new TestSuite(IncludeObjectTestCase.class));
+ suite.addTest(new TestSuite(AFPResourceUtilTestCase.class));
//$JUnit-END$
return suite;
}
diff --git a/test/java/org/apache/fop/afp/expected_named_resource.afp b/test/java/org/apache/fop/afp/expected_named_resource.afp
new file mode 100644
index 000000000..9fe45c388
--- /dev/null
+++ b/test/java/org/apache/fop/afp/expected_named_resource.afp
Binary files differ
diff --git a/test/java/org/apache/fop/afp/expected_resource.afp b/test/java/org/apache/fop/afp/expected_resource.afp
new file mode 100644
index 000000000..a98ac0e5e
--- /dev/null
+++ b/test/java/org/apache/fop/afp/expected_resource.afp
Binary files differ