Change the behaviour on short last blocks to be a warning not an exception, as some people seem to have "real" valid files that trigger this. Fixed bug #28231

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@634318 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2008-03-06 15:54:06 +00:00
parent 6f0aafadac
commit 924975f0e9
6 changed files with 147 additions and 34 deletions

View File

@ -36,6 +36,7 @@
<!-- Don't forget to update status.xml too! --> <!-- Don't forget to update status.xml too! -->
<release version="3.1-beta1" date="2008-??-??"> <release version="3.1-beta1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">28231 - For apparently truncated files, which are somehow still valid, now issue a truncation warning but carry on, rather than giving an exception as before</action>
<action dev="POI-DEVELOPERS" type="fix">44504 - Added initial support for recognising external functions like YEARFRAC and ISEVEN (using NameXPtg), via LinkTable support</action> <action dev="POI-DEVELOPERS" type="fix">44504 - Added initial support for recognising external functions like YEARFRAC and ISEVEN (using NameXPtg), via LinkTable support</action>
<action dev="POI-DEVELOPERS" type="fix">44504 - Improvements to FormulaParser - operators, precedence, error literals, quotes in string literals, range checking on IntPtg, formulas with extra un-parsed stuff at the end, improved parse error handling</action> <action dev="POI-DEVELOPERS" type="fix">44504 - Improvements to FormulaParser - operators, precedence, error literals, quotes in string literals, range checking on IntPtg, formulas with extra un-parsed stuff at the end, improved parse error handling</action>
<action dev="POI-DEVELOPERS" type="fix">44504 - Fixed number conversion inconsistencies in many functions, and improved RefEval</action> <action dev="POI-DEVELOPERS" type="fix">44504 - Fixed number conversion inconsistencies in many functions, and improved RefEval</action>

View File

@ -33,6 +33,9 @@
<!-- Don't forget to update changes.xml too! --> <!-- Don't forget to update changes.xml too! -->
<changes> <changes>
<release version="3.1-beta1" date="2008-??-??"> <release version="3.1-beta1" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">44504 - Added initial support for recognising external functions like YEARFRAC and ISEVEN (using NameXPtg), via LinkTable support</action>
<action dev="POI-DEVELOPERS" type="fix">44504 - Improvements to FormulaParser - operators, precedence, error literals, quotes in string literals, range checking on IntPtg, formulas with extra un-parsed stuff at the end, improved parse error handling</action>
<action dev="POI-DEVELOPERS" type="fix">44504 - Fixed number conversion inconsistencies in many functions, and improved RefEval</action>
<action dev="POI-DEVELOPERS" type="fix">44504 - Added initial support for recognising external functions like YEARFRAC and ISEVEN (using NameXPtg), via LinkTable support</action> <action dev="POI-DEVELOPERS" type="fix">44504 - Added initial support for recognising external functions like YEARFRAC and ISEVEN (using NameXPtg), via LinkTable support</action>
<action dev="POI-DEVELOPERS" type="fix">44504 - Improvements to FormulaParser - operators, precedence, error literals, quotes in string literals, range checking on IntPtg, formulas with extra un-parsed stuff at the end, improved parse error handling</action> <action dev="POI-DEVELOPERS" type="fix">44504 - Improvements to FormulaParser - operators, precedence, error literals, quotes in string literals, range checking on IntPtg, formulas with extra un-parsed stuff at the end, improved parse error handling</action>
<action dev="POI-DEVELOPERS" type="fix">44504 - Fixed number conversion inconsistencies in many functions, and improved RefEval</action> <action dev="POI-DEVELOPERS" type="fix">44504 - Fixed number conversion inconsistencies in many functions, and improved RefEval</action>

View File

@ -21,6 +21,8 @@ package org.apache.poi.poifs.storage;
import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import java.io.*; import java.io.*;
@ -35,6 +37,7 @@ public class RawDataBlock
{ {
private byte[] _data; private byte[] _data;
private boolean _eof; private boolean _eof;
private static POILogger log = POILogFactory.getLogger(RawDataBlock.class);
/** /**
* Constructor RawDataBlock * Constructor RawDataBlock
@ -75,9 +78,12 @@ public class RawDataBlock
String type = " byte" + ((count == 1) ? ("") String type = " byte" + ((count == 1) ? ("")
: ("s")); : ("s"));
throw new IOException("Unable to read entire block; " + count log.log(POILogger.ERROR,
+ type + " read before EOF; expected " "Unable to read entire block; " + count
+ blockSize + " bytes"); + type + " read before EOF; expected "
+ blockSize + " bytes. Your document"
+ " has probably been truncated!"
);
} }
else { else {
_eof = false; _eof = false;

View File

@ -22,6 +22,9 @@ package org.apache.poi.poifs.storage;
import java.io.*; import java.io.*;
import java.util.Random; import java.util.Random;
import org.apache.poi.util.DummyPOILogger;
import org.apache.poi.util.POILogFactory;
import junit.framework.*; import junit.framework.*;
/** /**
@ -43,6 +46,13 @@ public class TestRawDataBlock
public TestRawDataBlock(String name) public TestRawDataBlock(String name)
{ {
super(name); super(name);
// We always want to use our own
// logger
System.setProperty(
"org.apache.poi.util.POILogger",
"org.apache.poi.util.DummyPOILogger"
);
} }
/** /**
@ -99,11 +109,19 @@ public class TestRawDataBlock
/** /**
* Test creating a short RawDataBlock * Test creating a short RawDataBlock
* Will trigger a warning, but no longer an IOException,
* as people seem to have "valid" truncated files
*/ */
public void testShortConstructor() throws Exception
public void testShortConstructor()
{ {
for (int k = 1; k < 512; k++) // Get the logger to be used
DummyPOILogger logger = (DummyPOILogger)POILogFactory.getLogger(
RawDataBlock.class
);
assertEquals(0, logger.logged.size());
// Test for various data sizes
for (int k = 1; k <= 512; k++)
{ {
byte[] data = new byte[ k ]; byte[] data = new byte[ k ];
@ -113,15 +131,32 @@ public class TestRawDataBlock
} }
RawDataBlock block = null; RawDataBlock block = null;
try logger.reset();
{ assertEquals(0, logger.logged.size());
block = new RawDataBlock(new ByteArrayInputStream(data));
fail("Should have thrown IOException creating short block");
}
catch (IOException ignored)
{
// as expected // Have it created
block = new RawDataBlock(new ByteArrayInputStream(data));
assertNotNull(block);
// Check for the warning is there for <512
if(k < 512) {
assertEquals(
"Warning on " + k + " byte short block",
1, logger.logged.size()
);
// Build the expected warning message, and check
String bts = k + " byte";
if(k > 1) {
bts += "s";
}
assertEquals(
"7 - Unable to read entire block; "+bts+" read before EOF; expected 512 bytes. Your document has probably been truncated!",
(String)(logger.logged.get(0))
);
} else {
assertEquals(0, logger.logged.size());
} }
} }
} }
@ -132,6 +167,13 @@ public class TestRawDataBlock
* incorrectly think that there's not enough data * incorrectly think that there's not enough data
*/ */
public void testSlowInputStream() throws Exception { public void testSlowInputStream() throws Exception {
// Get the logger to be used
DummyPOILogger logger = (DummyPOILogger)POILogFactory.getLogger(
RawDataBlock.class
);
assertEquals(0, logger.logged.size());
// Test for various ok data sizes
for (int k = 1; k < 512; k++) { for (int k = 1; k < 512; k++) {
byte[] data = new byte[ 512 ]; byte[] data = new byte[ 512 ];
for (int j = 0; j < data.length; j++) { for (int j = 0; j < data.length; j++) {
@ -153,14 +195,17 @@ public class TestRawDataBlock
data[j] = (byte) j; data[j] = (byte) j;
} }
// Shouldn't complain, as there is enough data logger.reset();
try { assertEquals(0, logger.logged.size());
RawDataBlock block =
new RawDataBlock(new SlowInputStream(data, k)); // Should complain, as there isn't enough data
fail(); RawDataBlock block =
} catch(IOException e) { new RawDataBlock(new SlowInputStream(data, k));
// as expected assertNotNull(block);
} assertEquals(
"Warning on " + k + " byte short block",
1, logger.logged.size()
);
} }
} }

View File

@ -21,6 +21,9 @@ package org.apache.poi.poifs.storage;
import java.io.*; import java.io.*;
import org.apache.poi.util.DummyPOILogger;
import org.apache.poi.util.POILogFactory;
import junit.framework.*; import junit.framework.*;
/** /**
@ -42,6 +45,13 @@ public class TestRawDataBlockList
public TestRawDataBlockList(String name) public TestRawDataBlockList(String name)
{ {
super(name); super(name);
// We always want to use our own
// logger
System.setProperty(
"org.apache.poi.util.POILogger",
"org.apache.poi.util.DummyPOILogger"
);
} }
/** /**
@ -78,8 +88,15 @@ public class TestRawDataBlockList
* Test creating a short RawDataBlockList * Test creating a short RawDataBlockList
*/ */
public void testShortConstructor() public void testShortConstructor() throws Exception
{ {
// Get the logger to be used
DummyPOILogger logger = (DummyPOILogger)POILogFactory.getLogger(
RawDataBlock.class
);
assertEquals(0, logger.logged.size());
// Test for various short sizes
for (int k = 2049; k < 2560; k++) for (int k = 2049; k < 2560; k++)
{ {
byte[] data = new byte[ k ]; byte[] data = new byte[ k ];
@ -88,16 +105,11 @@ public class TestRawDataBlockList
{ {
data[ j ] = ( byte ) j; data[ j ] = ( byte ) j;
} }
try
{
new RawDataBlockList(new ByteArrayInputStream(data));
fail("Should have thrown IOException creating short block");
}
catch (IOException ignored)
{
// as expected // Check we logged the error
} logger.reset();
new RawDataBlockList(new ByteArrayInputStream(data));
assertEquals(1, logger.logged.size());
} }
} }

View File

@ -0,0 +1,46 @@
/* ====================================================================
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.
==================================================================== */
package org.apache.poi.util;
import java.util.ArrayList;
import java.util.List;
/**
* POILogger which logs into an ArrayList, so that
* tests can see what got logged
*/
public class DummyPOILogger extends POILogger {
public List logged = new ArrayList();
public void reset() {
logged = new ArrayList();
}
public boolean check(int level) {
return true;
}
public void initialize(String cat) {}
public void log(int level, Object obj1) {
logged.add(new String(level + " - " + obj1));
}
public void log(int level, Object obj1, Throwable exception) {
logged.add(new String(level + " - " + obj1 + " - " + exception));
}
}