mirror of https://github.com/apache/poi.git
Bug 50298: Fix corruption of Workbook when setting sheet order. The
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
This commit is contained in:
parent
d415bf5d06
commit
324a36e170
|
@ -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 ))
|
||||
|
@ -631,6 +578,12 @@ public final class InternalWorkbook {
|
|||
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);
|
||||
|
|
|
@ -17,29 +17,40 @@
|
|||
|
||||
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,12 +466,15 @@ public final class TestHSSFWorkbook extends BaseTestWorkbook {
|
|||
public BadlyBehavedRecord() {
|
||||
//
|
||||
}
|
||||
@Override
|
||||
public short getSid() {
|
||||
return 0x777;
|
||||
}
|
||||
@Override
|
||||
public int serialize(int offset, byte[] data) {
|
||||
return 4;
|
||||
}
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue