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;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.apache.poi.ddf.EscherBSERecord;
|
import org.apache.poi.ddf.*;
|
||||||
import org.apache.poi.ddf.EscherBoolProperty;
|
import org.apache.poi.hssf.record.*;
|
||||||
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.hssf.record.common.UnicodeString;
|
import org.apache.poi.hssf.record.common.UnicodeString;
|
||||||
import org.apache.poi.hssf.util.HSSFColor;
|
import org.apache.poi.hssf.util.HSSFColor;
|
||||||
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName;
|
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName;
|
||||||
|
@ -405,14 +352,14 @@ public final class InternalWorkbook {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int k = 0; k < 21; k++) {
|
for (int k = 0; k < 21; k++) {
|
||||||
records.add(retval.createExtendedFormat(k));
|
records.add(InternalWorkbook.createExtendedFormat(k));
|
||||||
retval.numxfs++;
|
retval.numxfs++;
|
||||||
}
|
}
|
||||||
retval.records.setXfpos( records.size() - 1 );
|
retval.records.setXfpos( records.size() - 1 );
|
||||||
for (int k = 0; k < 6; k++) {
|
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
|
int nBoundSheets = 1; // now just do 1
|
||||||
for (int k = 0; k < nBoundSheets; k++) {
|
for (int k = 0; k < nBoundSheets; k++) {
|
||||||
|
@ -422,13 +369,13 @@ public final class InternalWorkbook {
|
||||||
retval.boundsheets.add(bsr);
|
retval.boundsheets.add(bsr);
|
||||||
retval.records.setBspos(records.size() - 1);
|
retval.records.setBspos(records.size() - 1);
|
||||||
}
|
}
|
||||||
records.add( retval.createCountry() );
|
records.add( InternalWorkbook.createCountry() );
|
||||||
for ( int k = 0; k < nBoundSheets; k++ ) {
|
for ( int k = 0; k < nBoundSheets; k++ ) {
|
||||||
retval.getOrCreateLinkTable().checkExternSheet(k);
|
retval.getOrCreateLinkTable().checkExternSheet(k);
|
||||||
}
|
}
|
||||||
retval.sst = new SSTRecord();
|
retval.sst = new SSTRecord();
|
||||||
records.add(retval.sst);
|
records.add(retval.sst);
|
||||||
records.add(retval.createExtendedSST());
|
records.add(InternalWorkbook.createExtendedSST());
|
||||||
|
|
||||||
records.add(EOFRecord.instance);
|
records.add(EOFRecord.instance);
|
||||||
if (log.check( POILogger.DEBUG ))
|
if (log.check( POILogger.DEBUG ))
|
||||||
|
@ -628,9 +575,15 @@ public final class InternalWorkbook {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setSheetOrder(String sheetname, int pos ) {
|
public void setSheetOrder(String sheetname, int pos ) {
|
||||||
int sheetNumber = getSheetIndex(sheetname);
|
int sheetNumber = getSheetIndex(sheetname);
|
||||||
//remove the sheet that needs to be reordered and place it in the spot we want
|
//remove the sheet that needs to be reordered and place it in the spot we want
|
||||||
boundsheets.add(pos, boundsheets.remove(sheetNumber));
|
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 );
|
Record record = records.get( k );
|
||||||
if (record instanceof SSTRecord)
|
if (record instanceof SSTRecord)
|
||||||
sst = (SSTRecord)record;
|
sst = (SSTRecord)record;
|
||||||
|
|
||||||
if (record.getSid() == ExtSSTRecord.sid && sst != null)
|
if (record.getSid() == ExtSSTRecord.sid && sst != null)
|
||||||
retval += sst.calcExtSSTRecordSize();
|
retval += sst.calcExtSSTRecordSize();
|
||||||
else
|
else
|
||||||
retval += record.getRecordSize();
|
retval += record.getRecordSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2320,10 +2275,9 @@ public final class InternalWorkbook {
|
||||||
* @param password to set
|
* @param password to set
|
||||||
*/
|
*/
|
||||||
public void writeProtectWorkbook( String password, String username ) {
|
public void writeProtectWorkbook( String password, String username ) {
|
||||||
int protIdx = -1;
|
|
||||||
FileSharingRecord frec = getFileSharing();
|
FileSharingRecord frec = getFileSharing();
|
||||||
WriteAccessRecord waccess = getWriteAccess();
|
WriteAccessRecord waccess = getWriteAccess();
|
||||||
WriteProtectRecord wprotect = getWriteProtect();
|
/* WriteProtectRecord wprotect =*/ getWriteProtect();
|
||||||
frec.setReadOnly((short)1);
|
frec.setReadOnly((short)1);
|
||||||
frec.setPassword(FileSharingRecord.hashPassword(password));
|
frec.setPassword(FileSharingRecord.hashPassword(password));
|
||||||
frec.setUsername(username);
|
frec.setUsername(username);
|
||||||
|
|
|
@ -17,29 +17,40 @@
|
||||||
|
|
||||||
package org.apache.poi.hssf.usermodel;
|
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 java.util.List;
|
||||||
|
|
||||||
import junit.framework.AssertionFailedError;
|
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.HSSFITestDataProvider;
|
||||||
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
import org.apache.poi.hssf.model.HSSFFormulaParser;
|
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.model.InternalSheet;
|
||||||
import org.apache.poi.hssf.record.*;
|
import org.apache.poi.hssf.model.InternalWorkbook;
|
||||||
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
import org.apache.poi.hssf.record.CFRuleRecord;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.hssf.record.NameRecord;
|
||||||
import org.apache.poi.util.TempFile;
|
import org.apache.poi.hssf.record.Record;
|
||||||
import org.apache.poi.ss.usermodel.BaseTestWorkbook;
|
import org.apache.poi.hssf.record.RecordBase;
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
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.DirectoryEntry;
|
||||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
import org.apache.poi.POIDataSamples;
|
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
||||||
import org.apache.poi.ddf.EscherBSERecord;
|
import org.apache.poi.ss.usermodel.BaseTestWorkbook;
|
||||||
import org.apache.poi.hpsf.ClassID;
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
import org.apache.poi.util.TempFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link HSSFWorkbook}
|
* Tests for {@link HSSFWorkbook}
|
||||||
|
@ -455,13 +466,16 @@ public final class TestHSSFWorkbook extends BaseTestWorkbook {
|
||||||
public BadlyBehavedRecord() {
|
public BadlyBehavedRecord() {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
public short getSid() {
|
@Override
|
||||||
|
public short getSid() {
|
||||||
return 0x777;
|
return 0x777;
|
||||||
}
|
}
|
||||||
public int serialize(int offset, byte[] data) {
|
@Override
|
||||||
|
public int serialize(int offset, byte[] data) {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
public int getRecordSize() {
|
@Override
|
||||||
|
public int getRecordSize() {
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -598,6 +612,8 @@ public final class TestHSSFWorkbook extends BaseTestWorkbook {
|
||||||
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||||
assertEquals(3, wb.getNumberOfSheets());
|
assertEquals(3, wb.getNumberOfSheets());
|
||||||
assertEquals("Root xls", wb.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());
|
assertEquals("Root xls", wb.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());
|
||||||
|
|
||||||
|
fs.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCellStylesLimit() {
|
public void testCellStylesLimit() {
|
||||||
|
@ -606,12 +622,12 @@ public final class TestHSSFWorkbook extends BaseTestWorkbook {
|
||||||
int MAX_STYLES = 4030;
|
int MAX_STYLES = 4030;
|
||||||
int limit = MAX_STYLES - numBuiltInStyles;
|
int limit = MAX_STYLES - numBuiltInStyles;
|
||||||
for(int i=0; i < limit; i++){
|
for(int i=0; i < limit; i++){
|
||||||
HSSFCellStyle style = wb.createCellStyle();
|
/* HSSFCellStyle style =*/ wb.createCellStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(MAX_STYLES, wb.getNumCellStyles());
|
assertEquals(MAX_STYLES, wb.getNumCellStyles());
|
||||||
try {
|
try {
|
||||||
HSSFCellStyle style = wb.createCellStyle();
|
/*HSSFCellStyle style =*/ wb.createCellStyle();
|
||||||
fail("expected exception");
|
fail("expected exception");
|
||||||
} catch (IllegalStateException e){
|
} catch (IllegalStateException e){
|
||||||
assertEquals("The maximum number of cell styles was exceeded. " +
|
assertEquals("The maximum number of cell styles was exceeded. " +
|
||||||
|
@ -877,4 +893,31 @@ public final class TestHSSFWorkbook extends BaseTestWorkbook {
|
||||||
wb.unwriteProtectWorkbook();
|
wb.unwriteProtectWorkbook();
|
||||||
assertFalse(wb.isWriteProtected());
|
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