]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Fixed a bug in AFP where an ArrayOutofBoundsException is throwqn when embedding a...
authorPeter Hancock <phancock@apache.org>
Mon, 22 Aug 2011 15:14:54 +0000 (15:14 +0000)
committerPeter Hancock <phancock@apache.org>
Mon, 22 Aug 2011 15:14:54 +0000 (15:14 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1160298 13f79535-47bb-0310-9956-ffa450edef68

build.xml
src/java/org/apache/fop/afp/util/AFPResourceUtil.java
status.xml
test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java [new file with mode: 0644]
test/java/org/apache/fop/afp/AFPTestSuite.java
test/java/org/apache/fop/afp/expected_named_resource.afp [new file with mode: 0644]
test/java/org/apache/fop/afp/expected_resource.afp [new file with mode: 0644]

index 1dd2ca689a9c647fc49f9ee22eb842ccca7e9a0b..c1828a144e5686405c36cf7bd1c4bb1473926233 100644 (file)
--- 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"/>
index 979376b3e4c0fa6e12affabe34911cc1d630ebeb..538f2b88085eef47327c30a53562a30e1be6e97b 100644 (file)
@@ -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();
         }
     }
-
 }
index 2295a4f60ddbf8f24ecf8495cb9d1f15cbfeff93..340030f2236e5289d89ae1913daa0f799e7a4978 100644 (file)
       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 (file)
index 0000000..da3e023
--- /dev/null
@@ -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()));
+    }
+}
index c32eab6ea33a0b7bcb94074c0071705e4d3451eb..cb57a92edfe7241844e243c72c87bd8e4ef73b72 100644 (file)
@@ -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 (file)
index 0000000..9fe45c3
Binary files /dev/null and b/test/java/org/apache/fop/afp/expected_named_resource.afp 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 (file)
index 0000000..a98ac0e
Binary files /dev/null and b/test/java/org/apache/fop/afp/expected_resource.afp differ