]> source.dussan.org Git - poi.git/commitdiff
Findbugs fixes
authorDominik Stadler <centic@apache.org>
Sat, 12 Mar 2016 11:37:12 +0000 (11:37 +0000)
committerDominik Stadler <centic@apache.org>
Sat, 12 Mar 2016 11:37:12 +0000 (11:37 +0000)
OldExcelExtractor could leak file handles in case of exceptions
Free file handles in POIFSDump, add unit-test for POIFSDump
Add a Findbugs exclude and adjust findbugs-ant slightly

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1734689 13f79535-47bb-0310-9956-ffa450edef68

build.xml
src/java/org/apache/poi/hssf/extractor/OldExcelExtractor.java
src/java/org/apache/poi/hssf/record/StyleRecord.java
src/java/org/apache/poi/poifs/dev/POIFSDump.java
src/java/org/apache/poi/ss/formula/functions/DStarRunner.java
src/ooxml/java/org/apache/poi/xdgf/usermodel/section/CharacterSection.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java
src/resources/devtools/findbugs-filters.xml
src/testcases/org/apache/poi/hssf/extractor/TestOldExcelExtractor.java
src/testcases/org/apache/poi/poifs/dev/TestPOIFSDump.java [new file with mode: 0644]

index 3c87c1c0ea86f416fe06a581269a2f608651c76a..f0b43443a847045c5112e92f021614325f31ef78 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -1803,15 +1803,15 @@ under the License.
             src="http://prdownloads.sourceforge.net/findbugs/findbugs-noUpdateChecks-2.0.3.zip?download"
             dest="${main.lib}/findbugs-noUpdateChecks-2.0.3.zip"/>
 
+        <property name="findbugs.home" value="build/findbugs" />
         <unzip src="${main.lib}/findbugs-noUpdateChecks-2.0.3.zip"
-               dest="build/findbugs/lib">
+               dest="${findbugs.home}/lib">
             <patternset>
                 <include name="findbugs-2.0.3/lib/**"/>
             </patternset>
             <mapper type="flatten"/>
         </unzip>
 
-        <property name="findbugs.home" value="build/findbugs" />
         <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
             <classpath>
                 <fileset dir="${findbugs.home}/lib">
index f84a7fd821763e2e194210cefffa712a910573fa..1e1d833de5096238a96a9f8e0279554d922cceba 100644 (file)
@@ -44,6 +44,7 @@ import org.apache.poi.poifs.filesystem.DocumentNode;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.NotOLE2FileException;
 import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.util.IOUtils;
 
 /**
  * A text extractor for old Excel files, which are too old for
@@ -74,9 +75,27 @@ public class OldExcelExtractor implements Closeable {
         try {
             open(new NPOIFSFileSystem(f));
         } catch (OldExcelFormatException oe) {
-            open(new FileInputStream(f));
+            FileInputStream biffStream = new FileInputStream(f);
+            try {
+                open(biffStream);
+            } catch (RuntimeException e2) {
+                // ensure that the stream is properly closed here if an Exception
+                // is thrown while opening
+                biffStream.close();
+
+                throw e2;
+            }
         } catch (NotOLE2FileException e) {
-            open(new FileInputStream(f));
+            FileInputStream biffStream = new FileInputStream(f);
+            try {
+                open(biffStream);
+            } catch (RuntimeException e2) {
+                // ensure that the stream is properly closed here if an Exception
+                // is thrown while opening
+                biffStream.close();
+
+                throw e2;
+            }
         }
     }
 
@@ -255,10 +274,7 @@ public class OldExcelExtractor implements Closeable {
     @Override
     public void close() {
         if (input != null) {
-            try {
-                input.close();
-            } catch (IOException e) {}
-            input = null;
+            IOUtils.closeQuietly(input);
         }
     }
     
index 77e677485d57c26b935ee8a0a0a9b9e764621686..ee45909025fa8feaff931852f7e22d05c68f2ea3 100644 (file)
@@ -51,7 +51,7 @@ public final class StyleRecord extends StandardRecord {
         * creates a new style record, initially set to 'built-in'
         */
        public StyleRecord() {
-               field_1_xf_index = isBuiltinFlag.set(field_1_xf_index);
+               field_1_xf_index = isBuiltinFlag.set(0);
        }
 
        public StyleRecord(RecordInputStream in) {
@@ -140,7 +140,7 @@ public final class StyleRecord extends StandardRecord {
 
        @Override
        public String toString() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
 
                sb.append("[STYLE]\n");
                sb.append("    .xf_index_raw =").append(HexDump.shortToHex(field_1_xf_index)).append("\n");
index be57446c4885ecf4854f63194ba61e1a0cec7708..0dfd4a290ff1449f6f1284eed128ac523c448efd 100644 (file)
@@ -116,14 +116,17 @@ public class POIFSDump {
     public static void dump(NPOIFSFileSystem fs, int startBlock, String name, File parent) throws IOException {
         File file = new File(parent, name);
         FileOutputStream out = new FileOutputStream(file);
-        NPOIFSStream stream = new NPOIFSStream(fs, startBlock);
-        
-        byte[] b = new byte[fs.getBigBlockSize()];
-        for (ByteBuffer bb : stream) {
-            int len = bb.remaining();
-            bb.get(b);
-            out.write(b, 0, len);
+        try {
+            NPOIFSStream stream = new NPOIFSStream(fs, startBlock);
+
+            byte[] b = new byte[fs.getBigBlockSize()];
+            for (ByteBuffer bb : stream) {
+                int len = bb.remaining();
+                bb.get(b);
+                out.write(b, 0, len);
+            }
+        } finally {
+            out.close();
         }
-        out.close();
     }
 }
index 2fa27c84ae17dff1a4b316a088c47a088550e4cb..519d7d91bb507958939f2a20609523b39bb45229 100644 (file)
@@ -84,6 +84,8 @@ public final class DStarRunner implements Function3Arg {
         switch(algoType) {
             case DGET: algorithm = new DGet(); break;
             case DMIN: algorithm = new DMin(); break;
+            default:
+                throw new IllegalStateException("Unexpected algorithm type " + algoType + " encountered.");
         }
 
         // Iterate over all DB entries.
index 0d8fef05578b524a26a22ff42ee213a61bfce94a..7c1aa3f0c50cd4c59f4eb120704e99b5bb67fbce 100644 (file)
@@ -45,13 +45,11 @@ public class CharacterSection extends XDGFSection {
             _characterCells.put(cell.getN(), new XDGFCell(cell));
         }
 
-        if (row != null) {
-            _fontSize = XDGFCell.maybeGetDouble(_characterCells, "Size");
+        _fontSize = XDGFCell.maybeGetDouble(_characterCells, "Size");
 
-            String tmpColor = XDGFCell.maybeGetString(_characterCells, "Color");
-            if (tmpColor != null)
-                _fontColor = Color.decode(tmpColor);
-        }
+        String tmpColor = XDGFCell.maybeGetString(_characterCells, "Color");
+        if (tmpColor != null)
+            _fontColor = Color.decode(tmpColor);
     }
 
     public Double getFontSize() {
index 298bcc7817d2843e65552c2382a91ba696c1f5d5..0939edb962b594ed256add6fd1e975ec5cd05798 100644 (file)
@@ -587,11 +587,26 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
 \r
     @Override\r
     public void setSpaceBefore(Double spaceBefore){\r
-        if (spaceBefore == null && !_p.isSetPPr()) return;\r
+        if (spaceBefore == null && !_p.isSetPPr()) {\r
+            return;\r
+        }\r
+\r
+        // unset the space before on null input\r
+        if (spaceBefore == null) {\r
+            if(_p.getPPr().isSetSpcBef()) {\r
+                _p.getPPr().unsetSpcBef();\r
+            }\r
+            return;\r
+        }\r
+\r
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();\r
         CTTextSpacing spc = CTTextSpacing.Factory.newInstance();\r
-        if(spaceBefore >= 0) spc.addNewSpcPct().setVal((int)(spaceBefore*1000));\r
-        else spc.addNewSpcPts().setVal((int)(-spaceBefore*100));\r
+\r
+        if(spaceBefore >= 0) {\r
+            spc.addNewSpcPct().setVal((int)(spaceBefore*1000));\r
+        } else {\r
+            spc.addNewSpcPts().setVal((int)(-spaceBefore*100));\r
+        }\r
         pr.setSpcBef(spc);\r
     }\r
 \r
@@ -616,10 +631,26 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
 \r
     @Override\r
     public void setSpaceAfter(Double spaceAfter){\r
+        if (spaceAfter == null && !_p.isSetPPr()) {\r
+            return;\r
+        }\r
+\r
+        // unset the space before on null input\r
+        if (spaceAfter == null) {\r
+            if(_p.getPPr().isSetSpcAft()) {\r
+                _p.getPPr().unsetSpcAft();\r
+            }\r
+            return;\r
+        }\r
+\r
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();\r
         CTTextSpacing spc = CTTextSpacing.Factory.newInstance();\r
-        if(spaceAfter >= 0) spc.addNewSpcPct().setVal((int)(spaceAfter*1000));\r
-        else spc.addNewSpcPts().setVal((int)(-spaceAfter*100));\r
+\r
+        if(spaceAfter >= 0) {\r
+            spc.addNewSpcPct().setVal((int)(spaceAfter*1000));\r
+        } else {\r
+            spc.addNewSpcPts().setVal((int)(-spaceAfter*100));\r
+        }\r
         pr.setSpcAft(spc);\r
     }\r
 \r
index 7824616a7f70d2ba4a470dec4d4d3764ccf031ef..b72cd76082d892a9ae09b25066958bf65cf65373 100644 (file)
@@ -326,12 +326,20 @@ public class TestXSLFTextParagraph {
         assertEquals(200.0, p.getSpaceAfter(), 0);\r
         p.setSpaceAfter(-15.);\r
         assertEquals(-15.0, p.getSpaceAfter(), 0);\r
+        p.setSpaceAfter(null);\r
+        assertNull(p.getSpaceAfter());\r
+        p.setSpaceAfter(null);\r
+        assertNull(p.getSpaceAfter());\r
 \r
         assertNull(p.getSpaceBefore());\r
         p.setSpaceBefore(200.);\r
         assertEquals(200.0, p.getSpaceBefore(), 0);\r
         p.setSpaceBefore(-15.);\r
         assertEquals(-15.0, p.getSpaceBefore(), 0);\r
+        p.setSpaceBefore(null);\r
+        assertNull(p.getSpaceBefore());\r
+        p.setSpaceBefore(null);\r
+        assertNull(p.getSpaceBefore());\r
 \r
         assertEquals(TextAlign.LEFT, p.getTextAlign());\r
         p.setTextAlign(TextAlign.RIGHT);\r
index 518557fa02ce9f2cdac35b7220920da6668c0177..951201f631cb276ff004a621e0bc71a34e5f574f 100644 (file)
@@ -21,4 +21,9 @@
        <Match>\r
                <Bug code="EI,EI2" pattern="CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE,MS_PKGPROTECT,MS_MUTABLE_ARRAY"/>\r
        </Match>\r
+\r
+       <Match>\r
+               <Class name="org.apache.poi.hssf.usermodel.DummyGraphics2d"/>\r
+               <Bug code="FI" />\r
+       </Match>\r
 </FindBugsFilter>
\ No newline at end of file
index 02a77e8d4ed806203e4a8f46846ac39e8a2e883e..4de860d98eb9216b36198f509d87c318c9485d55 100644 (file)
@@ -36,6 +36,7 @@ import org.apache.poi.POIDataSamples;
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
+import org.apache.poi.util.RecordFormatException;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -225,7 +226,14 @@ public final class TestOldExcelExtractor {
         } catch (OfficeXmlFileException e) {
             // expected here
         }
-        
+
+        // a completely different type of file
+        try {
+            createExtractor("48936-strings.txt");
+            fail("Should catch Exception here");
+        } catch (RecordFormatException e) {
+            // expected here
+        }
     }
 
     @Test
diff --git a/src/testcases/org/apache/poi/poifs/dev/TestPOIFSDump.java b/src/testcases/org/apache/poi/poifs/dev/TestPOIFSDump.java
new file mode 100644 (file)
index 0000000..44c0632
--- /dev/null
@@ -0,0 +1,199 @@
+/* ====================================================================
+   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.poifs.dev;
+
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.NotOLE2FileException;
+import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
+import org.apache.poi.poifs.property.NPropertyTable;
+import org.apache.poi.util.TempFile;
+import org.junit.After;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+public class TestPOIFSDump {
+
+    private static final String TEST_FILE = HSSFTestDataSamples.getSampleFile("46515.xls").getAbsolutePath();
+    private static final String INVALID_FILE = HSSFTestDataSamples.getSampleFile("48936-strings.txt").getAbsolutePath();
+    private static final String INVALID_XLSX_FILE = HSSFTestDataSamples.getSampleFile("47668.xlsx").getAbsolutePath();
+
+    private static final String[] DUMP_OPTIONS = new String[] {
+        "-dumprops",
+        "-dump-props",
+        "-dump-properties",
+        "-dumpmini",
+        "-dump-mini",
+        "-dump-ministream",
+        "-dump-mini-stream",
+    };
+    private static final File DUMP_DIR = new File("Root Entry");
+
+    @After
+    public void tearDown() throws IOException {
+        // clean up the directory that POIFSDump writes to
+        deleteDirectory(DUMP_DIR);
+    }
+
+    public static void deleteDirectory(File directory) throws IOException {
+        if (!directory.exists()) {
+            return;
+        }
+
+        cleanDirectory(directory);
+
+        if (!directory.delete()) {
+            String message =
+                    "Unable to delete directory " + directory + ".";
+            throw new IOException(message);
+        }
+    }
+
+    public static void cleanDirectory(File directory) throws IOException {
+        if (!directory.isDirectory()) {
+            String message = directory + " is not a directory";
+            throw new IllegalArgumentException(message);
+        }
+
+        File[] files = directory.listFiles();
+        if (files == null) {  // null if security restricted
+            throw new IOException("Failed to list contents of " + directory);
+        }
+
+        IOException exception = null;
+        for (File file : files) {
+            try {
+                forceDelete(file);
+            } catch (IOException ioe) {
+                exception = ioe;
+            }
+        }
+
+        if (null != exception) {
+            throw exception;
+        }
+    }
+
+    public static void forceDelete(File file) throws IOException {
+        if (file.isDirectory()) {
+            deleteDirectory(file);
+        } else {
+            boolean filePresent = file.exists();
+            if (!file.delete()) {
+                if (!filePresent){
+                    throw new FileNotFoundException("File does not exist: " + file);
+                }
+                String message =
+                        "Unable to delete file: " + file;
+                throw new IOException(message);
+            }
+        }
+    }
+
+    @Test
+    public void testMain() throws Exception {
+        POIFSDump.main(new String[] {
+                TEST_FILE
+        });
+
+        for(String option : DUMP_OPTIONS) {
+            POIFSDump.main(new String[]{
+                    option,
+                    TEST_FILE
+            });
+        }
+    }
+    @Test
+    public void testInvalidFile() throws Exception {
+        try {
+            POIFSDump.main(new String[]{
+                    INVALID_FILE
+            });
+            fail("Should fail with an exception");
+        } catch (NotOLE2FileException e) {
+            // expected here
+        }
+
+        try {
+            POIFSDump.main(new String[]{
+                    INVALID_XLSX_FILE
+            });
+            fail("Should fail with an exception");
+        } catch (OfficeXmlFileException e) {
+            // expected here
+        }
+
+        for(String option : DUMP_OPTIONS) {
+            try {
+                POIFSDump.main(new String[]{
+                        option,
+                        INVALID_FILE
+                });
+                fail("Should fail with an exception");
+            } catch (NotOLE2FileException e) {
+                // expected here
+            }
+
+            try {
+                POIFSDump.main(new String[]{
+                        option,
+                        INVALID_XLSX_FILE
+                });
+                fail("Should fail with an exception");
+            } catch (OfficeXmlFileException e) {
+                // expected here
+            }
+        }
+    }
+
+    @Ignore("Calls System.exit()")
+    @Test
+    public void testMainNoArgs() throws Exception {
+        POIFSDump.main(new String[] {});
+    }
+
+    @Test
+    public void testFailToWrite() throws IOException {
+        File dir = TempFile.createTempFile("TestPOIFSDump", ".tst");
+        assertTrue("Had: " + dir, dir.exists());
+        assertTrue("Had: " + dir, dir.delete());
+        assertTrue("Had: " + dir, dir.mkdirs());
+
+        FileInputStream is = new FileInputStream(TEST_FILE);
+        NPOIFSFileSystem fs = new NPOIFSFileSystem(is);
+        is.close();
+
+        NPropertyTable props = fs.getPropertyTable();
+        assertNotNull(props);
+
+        try {
+            // try with an invalid startBlock to trigger an exception
+            // to validate that file-handles are closed properly
+            POIFSDump.dump(fs, 999999999, "mini-stream", dir);
+            fail("Should catch exception here");
+        } catch (IndexOutOfBoundsException e) {
+            // expected here
+        }
+    }
+}
\ No newline at end of file