Browse Source

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
tags/fop-1_1rc1old
Peter Hancock 12 years ago
parent
commit
937d2cbd25

+ 1
- 0
build.xml View File

@@ -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"/>

+ 28
- 32
src/java/org/apache/fop/afp/util/AFPResourceUtil.java View 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();
}
}

}

+ 4
- 0
status.xml View File

@@ -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>

+ 100
- 0
test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java View File

@@ -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()));
}
}

+ 1
- 0
test/java/org/apache/fop/afp/AFPTestSuite.java View 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;
}

BIN
test/java/org/apache/fop/afp/expected_named_resource.afp View File


BIN
test/java/org/apache/fop/afp/expected_resource.afp View File


Loading…
Cancel
Save