You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by kl...@apache.org on 2008/02/08 12:55:45 UTC

svn commit: r619848 - in /poi/trunk/src: java/org/apache/poi/hpsf/ testcases/org/apache/poi/hpsf/basic/ testcases/org/apache/poi/hpsf/data/

Author: klute
Date: Fri Feb  8 03:55:43 2008
New Revision: 619848

URL: http://svn.apache.org/viewvc?rev=619848&view=rev
Log:
- Fixed bug 44375 - HPSF now copes with a broken dictionary in Document Summary Information stream. RuntimeExceptions that occured when trying to read bogus data are now caught. Dictionary entries up to but not including the bogus one are preserved, the rest is ignored.

Added:
    poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestReadAllFiles.java
    poi/trunk/src/testcases/org/apache/poi/hpsf/data/TestBug44375.xls
      - copied, changed from r619765, poi/trunk/src/testcases/org/apache/poi/hpsf/data/Bug44375.xls
Removed:
    poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestBugs.java
    poi/trunk/src/testcases/org/apache/poi/hpsf/data/Bug44375.xls
Modified:
    poi/trunk/src/java/org/apache/poi/hpsf/Property.java
    poi/trunk/src/java/org/apache/poi/hpsf/Section.java
    poi/trunk/src/java/org/apache/poi/hpsf/VariantSupport.java
    poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestBasic.java

Modified: poi/trunk/src/java/org/apache/poi/hpsf/Property.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hpsf/Property.java?rev=619848&r1=619847&r2=619848&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hpsf/Property.java (original)
+++ poi/trunk/src/java/org/apache/poi/hpsf/Property.java Fri Feb  8 03:55:43 2008
@@ -23,6 +23,8 @@
 
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
 
 /**
  * <p>A property in a {@link Section} of a {@link PropertySet}.</p>
@@ -113,7 +115,8 @@
      * 
      * @param id the property's ID.
      * @param type the property's type, see {@link Variant}.
-     * @param value the property's value. Only certain types are allowed, see {@link Variant}. 
+     * @param value the property's value. Only certain types are allowed, see
+     *        {@link Variant}.
      */
     public Property(final long id, final long type, final Object value)
     {
@@ -210,68 +213,80 @@
         o += LittleEndian.INT_SIZE;
 
         final Map m = new HashMap((int) nrEntries, (float) 1.0);
-        for (int i = 0; i < nrEntries; i++)
+
+        try
         {
-            /* The key. */
-            final Long id = new Long(LittleEndian.getUInt(src, o));
-            o += LittleEndian.INT_SIZE;
-
-            /* The value (a string). The length is the either the
-             * number of (two-byte) characters if the character set is Unicode
-             * or the number of bytes if the character set is not Unicode.
-             * The length includes terminating 0x00 bytes which we have to strip
-             * off to create a Java string. */
-            long sLength = LittleEndian.getUInt(src, o);
-            o += LittleEndian.INT_SIZE;
-
-            /* Read the string. */
-            final StringBuffer b = new StringBuffer();
-            switch (codepage)
+            for (int i = 0; i < nrEntries; i++)
             {
-                case -1:
-                {
-                    /* Without a codepage the length is equal to the number of
-                     * bytes. */
-                    b.append(new String(src, o, (int) sLength));
-                    break;
-                }
-                case Constants.CP_UNICODE:
+                /* The key. */
+                final Long id = new Long(LittleEndian.getUInt(src, o));
+                o += LittleEndian.INT_SIZE;
+
+                /* The value (a string). The length is the either the
+                 * number of (two-byte) characters if the character set is Unicode
+                 * or the number of bytes if the character set is not Unicode.
+                 * The length includes terminating 0x00 bytes which we have to strip
+                 * off to create a Java string. */
+                long sLength = LittleEndian.getUInt(src, o);
+                o += LittleEndian.INT_SIZE;
+
+                /* Read the string. */
+                final StringBuffer b = new StringBuffer();
+                switch (codepage)
                 {
-                    /* The length is the number of characters, i.e. the number
-                     * of bytes is twice the number of the characters. */
-                    final int nrBytes = (int) (sLength * 2);
-                    final byte[] h = new byte[nrBytes];
-                    for (int i2 = 0; i2 < nrBytes; i2 += 2)
+                    case -1:
+                    {
+                        /* Without a codepage the length is equal to the number of
+                         * bytes. */
+                        b.append(new String(src, o, (int) sLength));
+                        break;
+                    }
+                    case Constants.CP_UNICODE:
+                    {
+                        /* The length is the number of characters, i.e. the number
+                         * of bytes is twice the number of the characters. */
+                        final int nrBytes = (int) (sLength * 2);
+                        final byte[] h = new byte[nrBytes];
+                        for (int i2 = 0; i2 < nrBytes; i2 += 2)
+                        {
+                            h[i2] = src[o + i2 + 1];
+                            h[i2 + 1] = src[o + i2];
+                        }
+                        b.append(new String(h, 0, nrBytes,
+                                VariantSupport.codepageToEncoding(codepage)));
+                        break;
+                    }
+                    default:
                     {
-                        h[i2] = src[o + i2 + 1];
-                        h[i2 + 1] = src[o + i2];
+                        /* For encodings other than Unicode the length is the number
+                         * of bytes. */
+                        b.append(new String(src, o, (int) sLength,
+                                 VariantSupport.codepageToEncoding(codepage)));
+                        break;
                     }
-                    b.append(new String(h, 0, nrBytes,
-                            VariantSupport.codepageToEncoding(codepage)));
-                    break;
                 }
-                default:
+
+                /* Strip 0x00 characters from the end of the string: */
+                while (b.length() > 0 && b.charAt(b.length() - 1) == 0x00)
+                    b.setLength(b.length() - 1);
+                if (codepage == Constants.CP_UNICODE)
                 {
-                    /* For encodings other than Unicode the length is the number
-                     * of bytes. */
-                    b.append(new String(src, o, (int) sLength,
-                             VariantSupport.codepageToEncoding(codepage)));
-                    break;
+                    if (sLength % 2 == 1)
+                        sLength++;
+                    o += (sLength + sLength);
                 }
+                else
+                    o += sLength;
+                m.put(id, b.toString());
             }
-
-            /* Strip 0x00 characters from the end of the string: */
-            while (b.length() > 0 && b.charAt(b.length() - 1) == 0x00)
-                b.setLength(b.length() - 1);
-            if (codepage == Constants.CP_UNICODE)
-            {
-                if (sLength % 2 == 1)
-                    sLength++;
-                o += (sLength + sLength);
-            }
-            else
-                o += sLength;
-            m.put(id, b.toString());
+        }
+        catch (RuntimeException ex)
+        {
+            final POILogger l = POILogFactory.getLogger(getClass());
+            l.log(POILogger.WARN,
+                    "The property set's dictionary contains bogus data. "
+                    + "All dictionary entries starting with the one with ID "
+                    + id + " will be ignored.", ex);
         }
         return m;
     }
@@ -320,11 +335,10 @@
 
 
     /**
-     * <p>Compares two properties.</p>
-     * 
-     * <p>Please beware that a property with ID == 0 is a special case: It does not have a type, and its value is the section's
-     * dictionary. Another special case are strings: Two properties may have
-     * the different types Variant.VT_LPSTR and Variant.VT_LPWSTR;</p>
+     * <p>Compares two properties.</p> <p>Please beware that a property with
+     * ID == 0 is a special case: It does not have a type, and its value is the
+     * section's dictionary. Another special case are strings: Two properties
+     * may have the different types Variant.VT_LPSTR and Variant.VT_LPWSTR;</p>
      * 
      * @see Object#equals(java.lang.Object)
      */

Modified: poi/trunk/src/java/org/apache/poi/hpsf/Section.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hpsf/Section.java?rev=619848&r1=619847&r2=619848&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hpsf/Section.java (original)
+++ poi/trunk/src/java/org/apache/poi/hpsf/Section.java Fri Feb  8 03:55:43 2008
@@ -210,7 +210,7 @@
         
         /* Pass 1: Read the property list. */
         int pass1Offset = o1;
-        List propertyList = new ArrayList(propertyCount);
+        final List propertyList = new ArrayList(propertyCount);
         PropertyListEntry ple;
         for (int i = 0; i < properties.length; i++)
         {

Modified: poi/trunk/src/java/org/apache/poi/hpsf/VariantSupport.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hpsf/VariantSupport.java?rev=619848&r1=619847&r2=619848&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hpsf/VariantSupport.java (original)
+++ poi/trunk/src/java/org/apache/poi/hpsf/VariantSupport.java Fri Feb  8 03:55:43 2008
@@ -109,25 +109,51 @@
     }
 
 
+    /**
+     * <p>HPSF is able to read these {@link Variant} types.</p>
+     */
+    final static public int[] SUPPORTED_TYPES = { Variant.VT_EMPTY,
+            Variant.VT_I2, Variant.VT_I4, Variant.VT_I8, Variant.VT_R8,
+            Variant.VT_FILETIME, Variant.VT_LPSTR, Variant.VT_LPWSTR,
+            Variant.VT_CF, Variant.VT_BOOL };
+
+
+
+    /**
+     * <p>Checks whether HPSF supports the specified variant type. Unsupported
+     * types should be implemented included in the {@link #SUPPORTED_TYPES}
+     * array.</p>
+     * 
+     * @see Variant
+     * @param variantType the variant type to check
+     * @return <code>true</code> if HPFS supports this type, else
+     *         <code>false</code>
+     */
+    public boolean isSupportedType(final int variantType)
+    {
+        for (int i = 0; i < SUPPORTED_TYPES.length; i++)
+            if (variantType == SUPPORTED_TYPES[i])
+                return true;
+        return false;
+    }
+
+
 
     /**
      * <p>Reads a variant type from a byte array.</p>
-     *
+     * 
      * @param src The byte array
-     * @param offset The offset in the byte array where the variant
-     * starts
-     * @param length The length of the variant including the variant
-     * type field
+     * @param offset The offset in the byte array where the variant starts
+     * @param length The length of the variant including the variant type field
      * @param type The variant type to read
-     * @param codepage The codepage to use to write non-wide strings
-     * @return A Java object that corresponds best to the variant
-     * field. For example, a VT_I4 is returned as a {@link Long}, a
-     * VT_LPSTR as a {@link String}.
+     * @param codepage The codepage to use for non-wide strings
+     * @return A Java object that corresponds best to the variant field. For
+     *         example, a VT_I4 is returned as a {@link Long}, a VT_LPSTR as a
+     *         {@link String}.
      * @exception ReadingNotSupportedException if a property is to be written
-     * who's variant type HPSF does not yet support
+     *            who's variant type HPSF does not yet support
      * @exception UnsupportedEncodingException if the specified codepage is not
-     * supported.
-     *
+     *            supported.
      * @see Variant
      */
     public static Object read(final byte[] src, final int offset,

Modified: poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestBasic.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestBasic.java?rev=619848&r1=619847&r2=619848&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestBasic.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestBasic.java Fri Feb  8 03:55:43 2008
@@ -20,7 +20,6 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.io.FileFilter;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -223,46 +222,6 @@
         Assert.assertEquals(17, s.getPropertyCount());
         Assert.assertEquals("Titel", s.getProperty(2));
         Assert.assertEquals(1748, s.getSize());
-    }
-
-
-
-    /**
-     * <p>This test methods reads all property set streams from all POI
-     * filesystems in the "data" directory.</p>
-     */
-    public void testReadAllFiles()
-    {
-        final File dataDir =
-            new File(System.getProperty("HPSF.testdata.path"));
-        final File[] fileList = dataDir.listFiles(new FileFilter()
-            {
-                public boolean accept(final File f)
-                {
-                    return f.isFile();
-                }
-            });
-        try
-        {
-            for (int i = 0; i < fileList.length; i++)
-            {
-                File f = fileList[i];
-                /* Read the POI filesystem's property set streams: */
-                final POIFile[] psf1 = Util.readPropertySets(f);
-
-                for (int j = 0; j < psf1.length; j++)
-                {
-                    final InputStream in =
-                        new ByteArrayInputStream(psf1[j].getBytes());
-                    PropertySetFactory.create(in);
-                }
-            }
-        }
-        catch (Throwable t)
-        {
-            final String s = org.apache.poi.hpsf.Util.toString(t);
-            fail(s);
-        }
     }
 
 

Added: poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestReadAllFiles.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestReadAllFiles.java?rev=619848&view=auto
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestReadAllFiles.java (added)
+++ poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestReadAllFiles.java Fri Feb  8 03:55:43 2008
@@ -0,0 +1,110 @@
+/* ====================================================================
+   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.hpsf.basic;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.hpsf.PropertySetFactory;
+
+
+
+/**
+ * <p>Tests some HPSF functionality by reading all property sets from all files
+ * in the "data" directory. If you want to ensure HPSF can deal with a certain
+ * OLE2 file, just add it to the "data" directory and run this test case.</p>
+ * 
+ * @author Rainer Klute (klute@rainer-klute.de)
+ * @since 2008-02-08
+ * @version $Id: TestBasic.java 489730 2006-12-22 19:18:16Z bayard $
+ */
+public class TestReadAllFiles extends TestCase
+{
+
+    /**
+     * <p>Test case constructor.</p>
+     * 
+     * @param name The test case's name.
+     */
+    public TestReadAllFiles(final String name)
+    {
+        super(name);
+    }
+
+
+
+    /**
+     * <p>This test methods reads all property set streams from all POI
+     * filesystems in the "data" directory.</p>
+     */
+    public void testReadAllFiles()
+    {
+        final File dataDir =
+            new File(System.getProperty("HPSF.testdata.path"));
+        final File[] fileList = dataDir.listFiles(new FileFilter()
+            {
+                public boolean accept(final File f)
+                {
+                    return f.isFile();
+                }
+            });
+        try
+        {
+            for (int i = 0; i < fileList.length; i++)
+            {
+                final File f = fileList[i];
+                /* Read the POI filesystem's property set streams: */
+                final POIFile[] psf1 = Util.readPropertySets(f);
+
+                for (int j = 0; j < psf1.length; j++)
+                {
+                    final InputStream in =
+                        new ByteArrayInputStream(psf1[j].getBytes());
+                    PropertySetFactory.create(in);
+                }
+            }
+        }
+        catch (Throwable t)
+        {
+            final String s = org.apache.poi.hpsf.Util.toString(t);
+            fail(s);
+        }
+    }
+
+
+
+    /**
+     * <p>Runs the test cases stand-alone.</p>
+     * 
+     * @param args Command-line arguments (ignored)
+     * 
+     * @exception Throwable if any sort of exception or error occurs
+     */
+    public static void main(final String[] args) throws Throwable
+    {
+        System.setProperty("HPSF.testdata.path",
+                           "./src/testcases/org/apache/poi/hpsf/data");
+        junit.textui.TestRunner.run(TestReadAllFiles.class);
+    }
+
+}

Copied: poi/trunk/src/testcases/org/apache/poi/hpsf/data/TestBug44375.xls (from r619765, poi/trunk/src/testcases/org/apache/poi/hpsf/data/Bug44375.xls)
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hpsf/data/TestBug44375.xls?p2=poi/trunk/src/testcases/org/apache/poi/hpsf/data/TestBug44375.xls&p1=poi/trunk/src/testcases/org/apache/poi/hpsf/data/Bug44375.xls&r1=619765&r2=619848&rev=619848&view=diff
==============================================================================
Binary files - no diff available.



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org