From: Peter Hancock Date: Mon, 22 Aug 2011 15:14:54 +0000 (+0000) Subject: Fixed a bug in AFP where an ArrayOutofBoundsException is throwqn when embedding a... X-Git-Tag: fop-1_1rc1old~185 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=937d2cbd25b967195ee81c74a43fa3ae4fd2d703;p=xmlgraphics-fop.git 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 --- 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. + 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 resourceNames = new java.util.HashSet(); //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. --> + + Fixed a bug in AFP where an ArrayOutofBoundsException is throwqn when embedding a Page + Segment. + Added support for 128bit encryption in PDF output. Based on work by Michael Rubin. 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 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 index 000000000..a98ac0e5e Binary files /dev/null and b/test/java/org/apache/fop/afp/expected_resource.afp differ