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

<include name="META-INF/**"/> <include name="META-INF/**"/>
<include name="**/*.xml"/> <include name="**/*.xml"/>
<include name="**/*.fo"/> <include name="**/*.fo"/>
<include name="**/*.afp"/>
</fileset> </fileset>
<fileset dir="${build.dir}/test-gensrc"> <fileset dir="${build.dir}/test-gensrc">
<include name="**/*.xml"/> <include name="**/*.xml"/>

+ 28
- 32
src/java/org/apache/fop/afp/util/AFPResourceUtil.java View File

throws UnsupportedEncodingException { throws UnsupportedEncodingException {
//The first 8 bytes of the field data represent the resource name //The first 8 bytes of the field data represent the resource name
byte[] nameBytes = new byte[8]; 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);
} }


/** /**
public static void copyNamedResource(String name, public static void copyNamedResource(String name,
final InputStream in, final OutputStream out) throws IOException { final InputStream in, final OutputStream out) throws IOException {
final MODCAParser parser = new MODCAParser(in); final MODCAParser parser = new MODCAParser(in);
Collection resourceNames = new java.util.HashSet();
Collection<String> resourceNames = new java.util.HashSet<String>();


//Find matching "Begin" field //Find matching "Begin" field
final UnparsedStructuredField fieldBegin; final UnparsedStructuredField fieldBegin;
while (true) { while (true) {
UnparsedStructuredField field = parser.readNextStructuredField();
final UnparsedStructuredField field = parser.readNextStructuredField();

if (field == null) { if (field == null) {
throw new IOException("Requested resource '" + name throw new IOException("Requested resource '" + name
+ "' not found. Encountered resource names: " + resourceNames); + "' not found. Encountered resource names: " + resourceNames);
if (field.getSfTypeCode() != TYPE_CODE_BEGIN) { //0xA8=Begin if (field.getSfTypeCode() != TYPE_CODE_BEGIN) { //0xA8=Begin
continue; //Not a "Begin" field continue; //Not a "Begin" field
} }
String resourceName = getResourceName(field);
final String resourceName = getResourceName(field);

resourceNames.add(resourceName); resourceNames.add(resourceName);

if (resourceName.equals(name)) { if (resourceName.equals(name)) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Start of requested structured field found:\n" LOG.debug("Start of requested structured field found:\n"
if (wrapInResource) { if (wrapInResource) {
ResourceObject resourceObject = new ResourceObject(name) { ResourceObject resourceObject = new ResourceObject(name) {
protected void writeContent(OutputStream os) throws IOException { protected void writeContent(OutputStream os) throws IOException {
copyStructuredFields(name, fieldBegin, parser, out);
copyNamedStructuredFields(name, fieldBegin, parser, out);
} }
}; };
resourceObject.setType(ResourceObject.TYPE_PAGE_SEGMENT); resourceObject.setType(ResourceObject.TYPE_PAGE_SEGMENT);
resourceObject.writeToStream(out); resourceObject.writeToStream(out);
} else { } 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) { 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); out.write(MODCAParser.CARRIAGE_CONTROL_CHAR);
field.writeTo(out); 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

documents. Example: the fix of marks layering will be such a case when it's done. documents. Example: the fix of marks layering will be such a case when it's done.
--> -->
<release version="FOP Trunk" date="TBD"> <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"> <action context="Renderers" dev="VH" type="add">
Added support for 128bit encryption in PDF output. Based on work by Michael Rubin. Added support for 128bit encryption in PDF output. Based on work by Michael Rubin.
</action> </action>

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

/*
* 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

TestSuite suite = new TestSuite("Test suite for FOP's AFP classes"); TestSuite suite = new TestSuite("Test suite for FOP's AFP classes");
//$JUnit-BEGIN$ //$JUnit-BEGIN$
suite.addTest(new TestSuite(IncludeObjectTestCase.class)); suite.addTest(new TestSuite(IncludeObjectTestCase.class));
suite.addTest(new TestSuite(AFPResourceUtilTestCase.class));
//$JUnit-END$ //$JUnit-END$
return suite; 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