]> source.dussan.org Git - poi.git/commitdiff
Bug 50298: Fix corruption of Workbook when setting sheet order. The
authorDominik Stadler <centic@apache.org>
Wed, 21 Aug 2013 22:08:20 +0000 (22:08 +0000)
committerDominik Stadler <centic@apache.org>
Wed, 21 Aug 2013 22:08:20 +0000 (22:08 +0000)
boundssheets themselves were adjusted, but not the corresponding
records.

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

src/java/org/apache/poi/hssf/model/InternalWorkbook.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java
test-data/spreadsheet/50298.xls [new file with mode: 0644]

index a989c32b98d012a3af99aa6ca603c842b13a18be..0a489d29cf6d1ceae13e2d24ffca7173b80297cd 100644 (file)
@@ -26,61 +26,8 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import org.apache.poi.ddf.EscherBSERecord;
-import org.apache.poi.ddf.EscherBoolProperty;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherDgRecord;
-import org.apache.poi.ddf.EscherDggRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherProperties;
-import org.apache.poi.ddf.EscherRGBProperty;
-import org.apache.poi.ddf.EscherRecord;
-import org.apache.poi.ddf.EscherSimpleProperty;
-import org.apache.poi.ddf.EscherSpRecord;
-import org.apache.poi.ddf.EscherSplitMenuColorsRecord;
-import org.apache.poi.hssf.record.BOFRecord;
-import org.apache.poi.hssf.record.BackupRecord;
-import org.apache.poi.hssf.record.BookBoolRecord;
-import org.apache.poi.hssf.record.BoundSheetRecord;
-import org.apache.poi.hssf.record.CodepageRecord;
-import org.apache.poi.hssf.record.CountryRecord;
-import org.apache.poi.hssf.record.DSFRecord;
-import org.apache.poi.hssf.record.DateWindow1904Record;
-import org.apache.poi.hssf.record.DrawingGroupRecord;
-import org.apache.poi.hssf.record.EOFRecord;
-import org.apache.poi.hssf.record.EscherAggregate;
-import org.apache.poi.hssf.record.ExtSSTRecord;
-import org.apache.poi.hssf.record.ExtendedFormatRecord;
-import org.apache.poi.hssf.record.ExternSheetRecord;
-import org.apache.poi.hssf.record.FileSharingRecord;
-import org.apache.poi.hssf.record.FnGroupCountRecord;
-import org.apache.poi.hssf.record.FontRecord;
-import org.apache.poi.hssf.record.FormatRecord;
-import org.apache.poi.hssf.record.HideObjRecord;
-import org.apache.poi.hssf.record.HyperlinkRecord;
-import org.apache.poi.hssf.record.InterfaceEndRecord;
-import org.apache.poi.hssf.record.InterfaceHdrRecord;
-import org.apache.poi.hssf.record.MMSRecord;
-import org.apache.poi.hssf.record.NameCommentRecord;
-import org.apache.poi.hssf.record.NameRecord;
-import org.apache.poi.hssf.record.PaletteRecord;
-import org.apache.poi.hssf.record.PasswordRecord;
-import org.apache.poi.hssf.record.PasswordRev4Record;
-import org.apache.poi.hssf.record.PrecisionRecord;
-import org.apache.poi.hssf.record.ProtectRecord;
-import org.apache.poi.hssf.record.ProtectionRev4Record;
-import org.apache.poi.hssf.record.RecalcIdRecord;
-import org.apache.poi.hssf.record.Record;
-import org.apache.poi.hssf.record.RefreshAllRecord;
-import org.apache.poi.hssf.record.SSTRecord;
-import org.apache.poi.hssf.record.StyleRecord;
-import org.apache.poi.hssf.record.SupBookRecord;
-import org.apache.poi.hssf.record.TabIdRecord;
-import org.apache.poi.hssf.record.UseSelFSRecord;
-import org.apache.poi.hssf.record.WindowOneRecord;
-import org.apache.poi.hssf.record.WindowProtectRecord;
-import org.apache.poi.hssf.record.WriteAccessRecord;
-import org.apache.poi.hssf.record.WriteProtectRecord;
+import org.apache.poi.ddf.*;
+import org.apache.poi.hssf.record.*;
 import org.apache.poi.hssf.record.common.UnicodeString;
 import org.apache.poi.hssf.util.HSSFColor;
 import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName;
@@ -405,14 +352,14 @@ public final class InternalWorkbook {
         }
 
         for (int k = 0; k < 21; k++) {
-            records.add(retval.createExtendedFormat(k));
+            records.add(InternalWorkbook.createExtendedFormat(k));
             retval.numxfs++;
         }
         retval.records.setXfpos( records.size() - 1 );
         for (int k = 0; k < 6; k++) {
-            records.add(retval.createStyle(k));
+            records.add(InternalWorkbook.createStyle(k));
         }
-        records.add(retval.createUseSelFS());
+        records.add(InternalWorkbook.createUseSelFS());
 
         int nBoundSheets = 1; // now just do 1
         for (int k = 0; k < nBoundSheets; k++) {
@@ -422,13 +369,13 @@ public final class InternalWorkbook {
             retval.boundsheets.add(bsr);
             retval.records.setBspos(records.size() - 1);
         }
-        records.add( retval.createCountry() );
+        records.add( InternalWorkbook.createCountry() );
         for ( int k = 0; k < nBoundSheets; k++ ) {
             retval.getOrCreateLinkTable().checkExternSheet(k);
         }
         retval.sst = new SSTRecord();
         records.add(retval.sst);
-        records.add(retval.createExtendedSST());
+        records.add(InternalWorkbook.createExtendedSST());
 
         records.add(EOFRecord.instance);
         if (log.check( POILogger.DEBUG ))
@@ -628,9 +575,15 @@ public final class InternalWorkbook {
      */
 
     public void setSheetOrder(String sheetname, int pos ) {
-    int sheetNumber = getSheetIndex(sheetname);
-    //remove the sheet that needs to be reordered and place it in the spot we want
-    boundsheets.add(pos, boundsheets.remove(sheetNumber));
+        int sheetNumber = getSheetIndex(sheetname);
+        //remove the sheet that needs to be reordered and place it in the spot we want
+        boundsheets.add(pos, boundsheets.remove(sheetNumber));
+        
+        // also adjust order of Records, calculate the position of the Boundsheets via getBspos()...
+        int pos0 = records.getBspos() - (boundsheets.size() - 1);
+        Record removed = records.get(pos0 + sheetNumber);
+        records.remove(pos0 + sheetNumber);
+               records.add(pos0 + pos, removed);
     }
 
     /**
@@ -1087,11 +1040,13 @@ public final class InternalWorkbook {
             Record record = records.get( k );
             if (record instanceof SSTRecord)
                 sst = (SSTRecord)record;
+
             if (record.getSid() == ExtSSTRecord.sid && sst != null)
                 retval += sst.calcExtSSTRecordSize();
             else
                 retval += record.getRecordSize();
         }
+
         return retval;
     }
 
@@ -2320,10 +2275,9 @@ public final class InternalWorkbook {
      * @param password to set
      */
     public void writeProtectWorkbook( String password, String username ) {
-        int protIdx = -1;
         FileSharingRecord frec = getFileSharing();
         WriteAccessRecord waccess = getWriteAccess();
-        WriteProtectRecord wprotect = getWriteProtect();
+        /* WriteProtectRecord wprotect =*/ getWriteProtect();
         frec.setReadOnly((short)1);
         frec.setPassword(FileSharingRecord.hashPassword(password));
         frec.setUsername(username);
index eab7b57dac18da262d26a90697f3e1bcaa3596c0..c1b226b87f91ba34fef45b4483e91aff77edba91 100644 (file)
 
 package org.apache.poi.hssf.usermodel;
 
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.List;
 
 import junit.framework.AssertionFailedError;
 
-import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.ddf.EscherBSERecord;
+import org.apache.poi.hpsf.ClassID;
 import org.apache.poi.hssf.HSSFITestDataProvider;
+import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.model.HSSFFormulaParser;
-import org.apache.poi.hssf.model.InternalWorkbook;
 import org.apache.poi.hssf.model.InternalSheet;
-import org.apache.poi.hssf.record.*;
-import org.apache.poi.ss.formula.ptg.Area3DPtg;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.TempFile;
-import org.apache.poi.ss.usermodel.BaseTestWorkbook;
-import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.hssf.model.InternalWorkbook;
+import org.apache.poi.hssf.record.CFRuleRecord;
+import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordBase;
+import org.apache.poi.hssf.record.RecordFormatException;
+import org.apache.poi.hssf.record.WindowOneRecord;
 import org.apache.poi.poifs.filesystem.DirectoryEntry;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.apache.poi.POIDataSamples;
-import org.apache.poi.ddf.EscherBSERecord;
-import org.apache.poi.hpsf.ClassID;
+import org.apache.poi.ss.formula.ptg.Area3DPtg;
+import org.apache.poi.ss.usermodel.BaseTestWorkbook;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.TempFile;
 
 /**
  * Tests for {@link HSSFWorkbook}
@@ -455,13 +466,16 @@ public final class TestHSSFWorkbook extends BaseTestWorkbook {
         public BadlyBehavedRecord() {
             //
         }
-        public short getSid() {
+        @Override
+               public short getSid() {
             return 0x777;
         }
-        public int serialize(int offset, byte[] data) {
+        @Override
+               public int serialize(int offset, byte[] data) {
             return 4;
         }
-        public int getRecordSize() {
+        @Override
+               public int getRecordSize() {
             return 8;
         }
     }
@@ -598,6 +612,8 @@ public final class TestHSSFWorkbook extends BaseTestWorkbook {
        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
        assertEquals(3, wb.getNumberOfSheets());
        assertEquals("Root xls", wb.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());
+       
+       fs.close();
     }
    
     public void testCellStylesLimit() {
@@ -606,12 +622,12 @@ public final class TestHSSFWorkbook extends BaseTestWorkbook {
         int MAX_STYLES = 4030;
         int limit = MAX_STYLES - numBuiltInStyles;
         for(int i=0; i < limit; i++){
-            HSSFCellStyle style = wb.createCellStyle();
+            /* HSSFCellStyle style =*/ wb.createCellStyle();
         }
 
         assertEquals(MAX_STYLES, wb.getNumCellStyles());
         try {
-            HSSFCellStyle style = wb.createCellStyle();
+            /*HSSFCellStyle style =*/ wb.createCellStyle();
             fail("expected exception");
         } catch (IllegalStateException e){
             assertEquals("The maximum number of cell styles was exceeded. " +
@@ -877,4 +893,31 @@ public final class TestHSSFWorkbook extends BaseTestWorkbook {
         wb.unwriteProtectWorkbook();
         assertFalse(wb.isWriteProtected());
     }
+
+       public void testBug50298() throws Exception {
+               HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("50298.xls");
+
+               
+               HSSFSheet sheet = wb.cloneSheet(0);
+
+               wb.setSheetName(wb.getSheetIndex(sheet), "copy");
+
+               wb.setSheetOrder("copy", 0);
+
+               wb.removeSheetAt(0);
+               
+               // check that the overall workbook serializes with its correct size
+               int expected = wb.getWorkbook().getSize();
+               int written = wb.getWorkbook().serialize(0, new byte[expected*2]);
+               
+               assertEquals("Did not have the expected size when writing the workbook: written: " + written + ", but expected: " + expected,
+                               expected, written);
+               
+               FileOutputStream fileOut = new FileOutputStream("/tmp/workbook.xls");
+               try {
+                       wb.write(fileOut);
+               } finally {
+                       fileOut.close();
+               }
+       }
 }
diff --git a/test-data/spreadsheet/50298.xls b/test-data/spreadsheet/50298.xls
new file mode 100644 (file)
index 0000000..99eb764
Binary files /dev/null and b/test-data/spreadsheet/50298.xls differ