Replace Allocate+System.arraycopy with Array.copyOf/Range and IOUtils.safelyClone

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1876640 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2020-04-16 22:11:16 +00:00
parent cdefe69aab
commit 7daeb4278c
158 changed files with 1078 additions and 1357 deletions

View File

@ -96,7 +96,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
* @param propertyNumber the property number part of the property id
* @param isBlipId {@code true}, if it references a blip
* @param complexData the data
*
*
* @deprecated use {@link #EscherArrayProperty(EscherPropertyTypes, boolean, int)} and {@link #setComplexData(byte[])}
*/
@Deprecated
@ -124,7 +124,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
// when called by user code, fix the size to be valid for the header
return complexSize == 0 ? 6 : complexSize;
}
public int getNumberOfElementsInArray() {
return (emptyComplexPart) ? 0 : LittleEndian.getUShort(getComplexData(), 0);
}
@ -171,9 +171,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
public byte[] getElement(int index) {
int actualSize = getActualSizeOfElements(getSizeOfElements());
byte[] result = IOUtils.safelyAllocate(actualSize, MAX_RECORD_LENGTH);
System.arraycopy(getComplexData(), FIXED_SIZE + index * actualSize, result, 0, result.length );
return result;
return IOUtils.safelyClone(getComplexData(), FIXED_SIZE + index * actualSize, actualSize, MAX_RECORD_LENGTH);
}
public void setElement(int index, byte[] element) {
@ -252,7 +250,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
public boolean hasNext() {
return (idx < getNumberOfElementsInArray());
}
@Override
public byte[] next() {
if (!hasNext()) {
@ -260,7 +258,7 @@ public final class EscherArrayProperty extends EscherComplexProperty implements
}
return getElement(idx++);
}
@Override
public void remove() {
throw new UnsupportedOperationException("not yet implemented");

View File

@ -103,8 +103,8 @@ public final class EscherBSERecord extends EscherRecord {
pos += 36 + bytesRead;
bytesRemaining -= bytesRead;
_remainingData = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
System.arraycopy( data, pos, _remainingData, 0, bytesRemaining );
_remainingData = IOUtils.safelyClone(data, pos, bytesRemaining, MAX_RECORD_LENGTH);
return bytesRemaining + 8 + 36 + (field_12_blipRecord == null ? 0 : field_12_blipRecord.getRecordSize()) ;
}

View File

@ -49,9 +49,7 @@ public class EscherBlipRecord extends EscherRecord {
int bytesAfterHeader = readHeader( data, offset );
int pos = offset + HEADER_SIZE;
field_pictureData = IOUtils.safelyAllocate(bytesAfterHeader, MAX_RECORD_LENGTH);
System.arraycopy(data, pos, field_pictureData, 0, bytesAfterHeader);
field_pictureData = IOUtils.safelyClone(data, pos, bytesAfterHeader, MAX_RECORD_LENGTH);
return bytesAfterHeader + 8;
}
@ -108,8 +106,7 @@ public class EscherBlipRecord extends EscherRecord {
if (pictureData == null || offset < 0 || length < 0 || pictureData.length < offset+length) {
throw new IllegalArgumentException("picture data can't be null");
}
field_pictureData = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH);
System.arraycopy(pictureData, offset, field_pictureData, 0, length);
field_pictureData = IOUtils.safelyClone(pictureData, offset, length, MAX_RECORD_LENGTH);
}
@Override

View File

@ -106,8 +106,8 @@ public class EscherClientAnchorRecord extends EscherRecord {
}
}
bytesRemaining -= size;
remainingData = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining );
remainingData = IOUtils.safelyClone(data, pos + size, bytesRemaining, MAX_RECORD_LENGTH);
return 8 + size + bytesRemaining;
}

View File

@ -50,8 +50,9 @@ public class EscherClientDataRecord extends EscherRecord {
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
int bytesRemaining = readHeader( data, offset );
int pos = offset + 8;
remainingData = (bytesRemaining == 0) ? EMPTY : IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
System.arraycopy( data, pos, remainingData, 0, bytesRemaining );
remainingData = (bytesRemaining == 0) ? EMPTY : IOUtils.safelyClone(data, pos, bytesRemaining, MAX_RECORD_LENGTH);
return 8 + bytesRemaining;
}

View File

@ -45,14 +45,11 @@ public class EscherDgRecord extends EscherRecord {
@Override
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
/*int bytesRemaining =*/ readHeader( data, offset );
readHeader( data, offset );
int pos = offset + 8;
int size = 0;
field_1_numShapes = LittleEndian.getInt( data, pos + size ); size += 4;
field_2_lastMSOSPID = LittleEndian.getInt( data, pos + size ); size += 4;
// bytesRemaining -= size;
// remainingData = new byte[bytesRemaining];
// System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining );
return getRecordSize();
}
@ -66,8 +63,6 @@ public class EscherDgRecord extends EscherRecord {
LittleEndian.putInt( data, offset + 4, 8 );
LittleEndian.putInt( data, offset + 8, field_1_numShapes );
LittleEndian.putInt( data, offset + 12, field_2_lastMSOSPID );
// System.arraycopy( remainingData, 0, data, offset + 26, remainingData.length );
// int pos = offset + 8 + 18 + remainingData.length;
listener.afterRecordSerialize( offset + 16, getRecordId(), getRecordSize(), this );
return getRecordSize();

View File

@ -106,8 +106,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
field_6_fCompression = data[pos]; pos++;
field_7_fFilter = data[pos]; pos++;
raw_pictureData = IOUtils.safelyAllocate(field_5_cbSave, MAX_RECORD_LENGTH);
System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave );
raw_pictureData = IOUtils.safelyClone(data, pos, field_5_cbSave, MAX_RECORD_LENGTH);
pos += field_5_cbSave;
// 0 means DEFLATE compression
@ -120,8 +119,7 @@ public final class EscherMetafileBlip extends EscherBlipRecord {
int remaining = bytesAfterHeader - pos + offset + HEADER_SIZE;
if(remaining > 0) {
remainingData = IOUtils.safelyAllocate(remaining, MAX_RECORD_LENGTH);
System.arraycopy( data, pos, remainingData, 0, remaining );
remainingData = IOUtils.safelyClone(data, pos, remaining, MAX_RECORD_LENGTH);
}
return bytesAfterHeader + HEADER_SIZE;
}

View File

@ -88,14 +88,11 @@ public class EscherSpRecord extends EscherRecord {
@Override
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
/*int bytesRemaining =*/ readHeader( data, offset );
readHeader( data, offset );
int pos = offset + 8;
int size = 0;
field_1_shapeId = LittleEndian.getInt( data, pos + size ); size += 4;
field_2_flags = LittleEndian.getInt( data, pos + size ); size += 4;
// bytesRemaining -= size;
// remainingData = new byte[bytesRemaining];
// System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining );
return getRecordSize();
}
@ -119,8 +116,6 @@ public class EscherSpRecord extends EscherRecord {
LittleEndian.putInt( data, offset + 4, remainingBytes );
LittleEndian.putInt( data, offset + 8, field_1_shapeId );
LittleEndian.putInt( data, offset + 12, field_2_flags );
// System.arraycopy( remainingData, 0, data, offset + 26, remainingData.length );
// int pos = offset + 8 + 18 + remainingData.length;
listener.afterRecordSerialize( offset + getRecordSize(), getRecordId(), getRecordSize(), this );
return 8 + 8;
}

View File

@ -59,8 +59,6 @@ public class EscherSpgrRecord extends EscherRecord {
if (bytesRemaining != 0) {
throw new RecordFormatException("Expected no remaining bytes but got " + bytesRemaining);
}
// remainingData = new byte[bytesRemaining];
// System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining );
return 8 + size + bytesRemaining;
}
@ -76,8 +74,6 @@ public class EscherSpgrRecord extends EscherRecord {
LittleEndian.putInt( data, offset + 12, field_2_rectY1 );
LittleEndian.putInt( data, offset + 16, field_3_rectX2 );
LittleEndian.putInt( data, offset + 20, field_4_rectY2 );
// System.arraycopy( remainingData, 0, data, offset + 26, remainingData.length );
// int pos = offset + 8 + 18 + remainingData.length;
listener.afterRecordSerialize( offset + getRecordSize(), getRecordId(), offset + getRecordSize(), this );
return 8 + 16;
}

View File

@ -54,10 +54,8 @@ public final class EscherTextboxRecord extends EscherRecord {
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
int bytesRemaining = readHeader( data, offset );
// Save the data, ready for the calling code to do something
// useful with it
thedata = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
System.arraycopy( data, offset + 8, thedata, 0, bytesRemaining );
// Save the data, ready for the calling code to do something useful with it
thedata = IOUtils.safelyClone(data, offset + 8, bytesRemaining, MAX_RECORD_LENGTH);
return bytesRemaining + 8;
}
@ -103,10 +101,8 @@ public final class EscherTextboxRecord extends EscherRecord {
* @param start the start position in the buffer
* @param length the length of the block
*/
public void setData(byte[] b, int start, int length)
{
thedata = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH);
System.arraycopy(b,start,thedata,0,length);
public void setData(byte[] b, int start, int length) {
thedata = IOUtils.safelyClone(b, start, length, MAX_RECORD_LENGTH);
}
/**

View File

@ -81,8 +81,8 @@ public final class UnknownEscherRecord extends EscherRecord {
bytesRemaining = 0;
}
thedata = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
System.arraycopy( data, offset + 8, thedata, 0, bytesRemaining );
thedata = IOUtils.safelyClone(data, offset + 8, bytesRemaining, MAX_RECORD_LENGTH);
return bytesRemaining + 8;
}

View File

@ -17,6 +17,7 @@
package org.apache.poi.hpsf;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndian;
/**
* <p>Class to manipulate data in the Clipboard Variant ({@link
@ -119,6 +120,9 @@ public final class Thumbnail {
*/
public static final int CF_BITMAP = 2;
//arbitrarily selected; may need to increase
private static final int MAX_RECORD_LENGTH = 1_000_000;
/**
* <p>A <code>byte[]</code> to hold a thumbnail image in ({@link
* Variant#VT_CF VT_CF}) format.</p>
@ -260,13 +264,6 @@ public final class Thumbnail {
"be CF_METAFILEPICT.");
}
byte[] thumbnail = getThumbnail();
int wmfImageLength = thumbnail.length - OFFSET_WMFDATA;
byte[] wmfImage = new byte[wmfImageLength];
System.arraycopy(thumbnail,
OFFSET_WMFDATA,
wmfImage,
0,
wmfImageLength);
return wmfImage;
return IOUtils.safelyClone(thumbnail, OFFSET_WMFDATA, thumbnail.length - OFFSET_WMFDATA, MAX_RECORD_LENGTH);
}
}

View File

@ -87,17 +87,17 @@ public abstract class AbstractEscherHolderRecord extends Record {
@Override
public int serialize(int offset, byte[] data)
{
LittleEndian.putShort( data, 0 + offset, getSid() );
LittleEndian.putShort(data, offset, getSid() );
LittleEndian.putShort( data, 2 + offset, (short) ( getRecordSize() - 4 ) );
byte[] rawData = getRawData();
if ( escherRecords.size() == 0 && rawData != null )
{
LittleEndian.putShort(data, 0 + offset, getSid());
LittleEndian.putShort(data, offset, getSid());
LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
System.arraycopy( rawData, 0, data, 4 + offset, rawData.length);
return rawData.length + 4;
}
LittleEndian.putShort(data, 0 + offset, getSid());
LittleEndian.putShort(data, offset, getSid());
LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
int pos = offset + 4;

View File

@ -17,6 +17,7 @@
package org.apache.poi.hssf.record;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -151,8 +152,7 @@ public final class FormatRecord extends StandardRecord {
//there can be a remaining byte (without proper final '00')
//that should be read as a byte
if (ris.available() == 1) {
char[] tmp = new char[buf.length+1];
System.arraycopy(buf, 0, tmp, 0, buf.length);
char[] tmp = Arrays.copyOf(buf, buf.length+1);
tmp[buf.length] = (char)ris.readUByte();
buf = tmp;
}

View File

@ -78,9 +78,7 @@ public final class HeaderFooterRecord extends StandardRecord {
* @return the sheet view?s GUID
*/
public byte[] getGuid(){
byte[] guid = new byte[16];
System.arraycopy(_rawData, 12, guid, 0, guid.length);
return guid;
return Arrays.copyOfRange(_rawData, 12, 12+16);
}
/**

View File

@ -17,6 +17,7 @@
package org.apache.poi.hssf.record;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -74,9 +75,7 @@ public final class UserSViewBegin extends StandardRecord {
* @return Globally unique identifier for the custom view
*/
public byte[] getGuid(){
byte[] guid = new byte[16];
System.arraycopy(_rawData, 0, guid, 0, guid.length);
return guid;
return Arrays.copyOf(_rawData, 16);
}
@Override

View File

@ -19,8 +19,8 @@
package org.apache.poi.hssf.record.cont;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.ContinueRecord;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.util.LittleEndianInput;
/**
@ -44,7 +44,7 @@ import org.apache.poi.util.LittleEndianInput;
*
* <p>
* YK: For now (March 2011) this class is only used to read
* @see org.apache.poi.hssf.record.common.UnicodeString.ExtRst blocks of a UnicodeString.
* @see org.apache.poi.hssf.record.common.ExtRst blocks of a UnicodeString.
*
* </p>
*/
@ -78,7 +78,7 @@ public class ContinuableRecordInput implements LittleEndianInput {
public int readUShort(){
int ch1 = readUByte();
int ch2 = readUByte();
return (ch2 << 8) + (ch1 << 0);
return (ch2 << 8) + (ch1);
}
@Override
@ -87,7 +87,7 @@ public class ContinuableRecordInput implements LittleEndianInput {
int ch2 = _in.readUByte();
int ch3 = _in.readUByte();
int ch4 = _in.readUByte();
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1);
}
@Override
@ -107,7 +107,7 @@ public class ContinuableRecordInput implements LittleEndianInput {
((long)b3 << 24) +
(b2 << 16) +
(b1 << 8) +
(b0 << 0));
(b0));
}
@Override
@ -124,7 +124,7 @@ public class ContinuableRecordInput implements LittleEndianInput {
public void readFully(byte[] buf, int off, int len){
_in.readFully(buf, off, len);
}
@Override
public void readPlain(byte[] buf, int off, int len) {
readFully(buf, off, len);

View File

@ -96,7 +96,7 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
* A factory method allowing the creation of conditional formatting
* rules using an Icon Set / Multi-State formatting.
* The thresholds for it will be created, but will be empty
* and require configuring with
* and require configuring with
* {@link HSSFConditionalFormattingRule#getMultiStateFormatting()}
* then
* {@link HSSFIconMultiStateFormatting#getThresholds()}
@ -109,12 +109,12 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
/**
* Create a Databar conditional formatting rule.
* <p>The thresholds and colour for it will be created, but will be
* empty and require configuring with
* <p>The thresholds and colour for it will be created, but will be
* empty and require configuring with
* {@link HSSFConditionalFormattingRule#getDataBarFormatting()}
* then
* {@link HSSFDataBarFormatting#getMinThreshold()}
* and
* and
* {@link HSSFDataBarFormatting#getMaxThreshold()}
*/
public HSSFConditionalFormattingRule createConditionalFormattingRule(HSSFExtendedColor color) {
@ -127,8 +127,8 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
/**
* Create a Color Scale / Color Gradient conditional formatting rule.
* <p>The thresholds and colours for it will be created, but will be
* empty and require configuring with
* <p>The thresholds and colours for it will be created, but will be
* empty and require configuring with
* {@link HSSFConditionalFormattingRule#getColorScaleFormatting()}
* then
* {@link HSSFColorScaleFormatting#getThresholds()}
@ -139,7 +139,7 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
CFRule12Record rr = CFRule12Record.createColorScale(_sheet);
return new HSSFConditionalFormattingRule(_sheet, rr);
}
/**
* Adds a copy of HSSFConditionalFormatting object to the sheet
* <p>This method could be used to copy HSSFConditionalFormatting object
@ -196,8 +196,9 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
public int addConditionalFormatting(CellRangeAddress[] regions, ConditionalFormattingRule[] cfRules) {
HSSFConditionalFormattingRule[] hfRules;
if(cfRules instanceof HSSFConditionalFormattingRule[]) hfRules = (HSSFConditionalFormattingRule[])cfRules;
else {
if(cfRules instanceof HSSFConditionalFormattingRule[]) {
hfRules = (HSSFConditionalFormattingRule[])cfRules;
} else {
hfRules = new HSSFConditionalFormattingRule[cfRules.length];
System.arraycopy(cfRules, 0, hfRules, 0, hfRules.length);
}
@ -206,7 +207,7 @@ public final class HSSFSheetConditionalFormatting implements SheetConditionalFor
public int addConditionalFormatting(CellRangeAddress[] regions,
HSSFConditionalFormattingRule rule1) {
return addConditionalFormatting(regions, rule1 == null ?
return addConditionalFormatting(regions, rule1 == null ?
null : new HSSFConditionalFormattingRule[] { rule1 }
);
}

View File

@ -23,7 +23,6 @@ import static org.apache.poi.hssf.model.InternalWorkbook.WORKBOOK_DIR_ENTRY_NAME
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -93,10 +92,11 @@ import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.DocumentNode;
import org.apache.poi.poifs.filesystem.EntryUtils;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.poifs.filesystem.FilteringDirectoryNode;
import org.apache.poi.poifs.filesystem.Ole10Native;
import org.apache.poi.poifs.filesystem.POIFSDocument;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.poifs.filesystem.Ole10Native;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.formula.FormulaType;
@ -133,6 +133,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
//arbitrarily selected; may need to increase
private static final int MAX_RECORD_LENGTH = 100_000;
private static final int MAX_IMAGE_LENGTH = 50_000_000;
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
@ -504,13 +505,13 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
workbook.updateNamesAfterCellShift(shifter);
updateNamedRangesAfterSheetReorder(oldSheetIndex, pos);
updateActiveSheetAfterSheetReorder(oldSheetIndex, pos);
}
/**
* copy-pasted from XSSFWorkbook#updateNamedRangesAfterSheetReorder(int, int)
*
*
* update sheet-scoped named ranges in this workbook after changing the sheet order
* of a sheet at oldIndex to newIndex.
* Sheets between these indices will move left or right by 1.
@ -540,7 +541,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
}
}
private void updateActiveSheetAfterSheetReorder(int oldIndex, int newIndex) {
// adjust active sheet if necessary
int active = getActiveSheetIndex();
@ -600,7 +601,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
}
setSelectedTabs(list);
}
/**
* Selects multiple sheets as a group. This is distinct from
* the 'active' sheet (which is the sheet with focus).
@ -624,9 +625,9 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
short nSelected = (short) set.size();
workbook.getWindowOne().setNumSelectedTabs(nSelected);
}
/**
* Gets the selected sheets (if more than one, Excel calls these a [Group]).
* Gets the selected sheets (if more than one, Excel calls these a [Group]).
*
* @return indices of selected sheets
*/
@ -641,7 +642,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
}
return Collections.unmodifiableCollection(indexes);
}
/**
* Convenience method to set the active sheet. The active sheet is is the sheet
* which is currently displayed when the workbook is viewed in Excel.
@ -743,7 +744,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
validateSheetIndex(sheetIx);
return workbook.isSheetVeryHidden(sheetIx);
}
@Override
public SheetVisibility getSheetVisibility(int sheetIx) {
return workbook.getSheetVisibility(sheetIx);
@ -945,7 +946,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
public Iterator<Sheet> iterator() {
return sheetIterator();
}
private final class SheetIterator<T extends Sheet> implements Iterator<T> {
final private Iterator<T> it;
private T cursor;
@ -1294,7 +1295,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
* the Workbook was read, if any.
*
* <p>Once this has been called, no further
* operations, updates or reads should be performed on the
* operations, updates or reads should be performed on the
* Workbook.
*/
@Override
@ -1304,42 +1305,42 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
/**
* Write out this workbook to the currently open {@link File} via the
* writeable {@link POIFSFileSystem} it was opened as.
*
* writeable {@link POIFSFileSystem} it was opened as.
*
* <p>This will fail (with an {@link IllegalStateException} if the
* Workbook was opened read-only, opened from an {@link InputStream}
* instead of a File, or if this is not the root document. For those cases,
* you must use {@link #write(OutputStream)} or {@link #write(File)} to
* instead of a File, or if this is not the root document. For those cases,
* you must use {@link #write(OutputStream)} or {@link #write(File)} to
* write to a brand new document.
*/
@Override
public void write() throws IOException {
validateInPlaceWritePossible();
final DirectoryNode dir = getDirectory();
// Update the Workbook stream in the file
DocumentNode workbookNode = (DocumentNode)dir.getEntry(
getWorkbookDirEntryName(dir));
POIFSDocument workbookDoc = new POIFSDocument(workbookNode);
workbookDoc.replaceContents(new ByteArrayInputStream(getBytes()));
// Update the properties streams in the file
writeProperties();
// Sync with the File on disk
dir.getFileSystem().writeFilesystem();
}
/**
* Method write - write out this workbook to a new {@link File}. Constructs
* a new POI POIFSFileSystem, passes in the workbook binary representation and
* writes it out. If the file exists, it will be replaced, otherwise a new one
* will be created.
*
*
* Note that you cannot write to the currently open File using this method.
* If you opened your Workbook from a File, you <i>must</i> use the {@link #write()}
* method instead!
*
*
* @param newFile The new File you wish to write the XLS to
*
* @exception IOException if anything can't be written.
@ -1352,12 +1353,12 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
fs.writeFilesystem();
}
}
/**
* Method write - write out this workbook to an {@link OutputStream}. Constructs
* a new POI POIFSFileSystem, passes in the workbook binary representation and
* writes it out.
*
*
* If {@code stream} is a {@link java.io.FileOutputStream} on a networked drive
* or has a high cost/latency associated with each written byte,
* consider wrapping the OutputStream in a {@link java.io.BufferedOutputStream}
@ -1375,7 +1376,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
fs.writeFilesystem(stream);
}
}
/** Writes the workbook out to a brand new, empty POIFS */
private void write(POIFSFileSystem fs) throws IOException {
// For tracking what we've written out, used if we're
@ -1387,7 +1388,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
// Write out our HPFS properties, if we have them
writeProperties(fs, excepts);
if (preserveNodes) {
// Don't write out the old Workbook, we'll be doing our new one
// If the file had an "incorrect" name for the workbook stream,
@ -1457,7 +1458,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
if (log.check( POILogger.DEBUG )) {
log.log(DEBUG, "HSSFWorkbook.getBytes()");
}
HSSFSheet[] sheets = getSheets();
int nSheets = sheets.length;
@ -1502,7 +1503,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
}
encryptBytes(retval);
return retval;
}
@ -1555,7 +1556,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
throw new EncryptedDocumentException(e);
}
}
/*package*/ InternalWorkbook getWorkbook() {
return workbook;
}
@ -1873,12 +1874,9 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
short escherTag;
switch (format) {
case PICTURE_TYPE_WMF:
// remove first 22 bytes if file starts with magic bytes D7-CD-C6-9A
// see also http://de.wikipedia.org/wiki/Windows_Metafile#Hinweise_zur_WMF-Spezifikation
if (LittleEndian.getInt(pictureData) == 0x9AC6CDD7) {
byte[] picDataNoHeader = new byte[pictureData.length - 22];
System.arraycopy(pictureData, 22, picDataNoHeader, 0, pictureData.length-22);
pictureData = picDataNoHeader;
// remove first 22 bytes if file starts with the WMF placeable header
if (FileMagic.valueOf(pictureData) == FileMagic.WMF) {
pictureData = IOUtils.safelyClone(pictureData, 22, pictureData.length - 22, MAX_IMAGE_LENGTH);
}
// fall through
case PICTURE_TYPE_EMF:
@ -2047,7 +2045,7 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
} while (oleDir == null);
Ole10Native.createOleMarkerEntry(oleDir);
Ole10Native oleNative = new Ole10Native(label, fileName, command, oleData);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
oleNative.writeOut(bos);
@ -2213,15 +2211,15 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
public boolean changeExternalReference(String oldUrl, String newUrl) {
return workbook.changeExternalReference(oldUrl, newUrl);
}
@Internal
public InternalWorkbook getInternalWorkbook() {
return workbook;
}
/**
* Returns the spreadsheet version (EXCLE97) of this workbook
*
*
* @return EXCEL97 SpreadsheetVersion enum
* @since 3.14 beta 2
*/

View File

@ -135,8 +135,7 @@ public class BinaryRC4Decryptor extends Decryptor {
hashAlg.update(salt);
}
hash = new byte[5];
System.arraycopy(hashAlg.digest(), 0, hash, 0, 5);
hash = Arrays.copyOf(hashAlg.digest(), 5);
return new SecretKeySpec(hash, ver.getCipherAlgorithm().jceId);
}

View File

@ -43,12 +43,12 @@ public class Ole10Native {
/**
* Default content of the \u0001Ole entry
*/
private static final byte[] OLE_MARKER_BYTES =
private static final byte[] OLE_MARKER_BYTES =
{ 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
private static final String OLE_MARKER_NAME = "\u0001Ole";
// (the fields as they appear in the raw record:)
private int totalSize; // 4 bytes, total size of record not including this field
private short flags1 = 2; // 2 bytes, unknown, mostly [02 00]
@ -59,10 +59,10 @@ public class Ole10Native {
private String command; // ASCIIZ, stored in this field without the terminating zero
private byte[] dataBuffer; // varying size, the actual native data
private short flags3; // some final flags? or zero terminators?, sometimes not there
/**
* the field encoding mode - merely a try-and-error guess ...
**/
**/
private enum EncodingMode {
/**
* the data is stored in parsed format - including label, command, etc.
@ -77,11 +77,11 @@ public class Ole10Native {
*/
compact
}
private EncodingMode mode;
/**
* Creates an instance of this class from an embedded OLE Object. The OLE Object is expected
* to include a stream &quot;{01}Ole10Native&quot; which contains the actual
@ -95,7 +95,7 @@ public class Ole10Native {
public static Ole10Native createFromEmbeddedOleObject(POIFSFileSystem poifs) throws IOException, Ole10NativeException {
return createFromEmbeddedOleObject(poifs.getRoot());
}
/**
* Creates an instance of this class from an embedded OLE Object. The OLE Object is expected
* to include a stream &quot;{01}Ole10Native&quot; which contains the actual
@ -113,7 +113,7 @@ public class Ole10Native {
return new Ole10Native(data, 0);
}
}
/**
* Creates an instance and fills the fields based on ... the fields
*/
@ -124,7 +124,7 @@ public class Ole10Native {
setDataBuffer(data);
mode = EncodingMode.parsed;
}
/**
* Creates an instance and fills the fields based on the data in the given buffer.
*
@ -134,14 +134,14 @@ public class Ole10Native {
*/
public Ole10Native(byte[] data, int offset) throws Ole10NativeException {
int ofs = offset; // current offset, initialized to start
if (data.length < offset + 2) {
throw new Ole10NativeException("data is too small");
}
totalSize = LittleEndian.getInt(data, ofs);
ofs += LittleEndianConsts.INT_SIZE;
mode = EncodingMode.unparsed;
if (LittleEndian.getShort(data, ofs) == 2) {
// some files like equations don't have a valid filename,
@ -157,36 +157,36 @@ public class Ole10Native {
switch (mode) {
case parsed: {
flags1 = LittleEndian.getShort(data, ofs);
// structured format
ofs += LittleEndianConsts.SHORT_SIZE;
int len = getStringLength(data, ofs);
label = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
ofs += len;
len = getStringLength(data, ofs);
fileName = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
ofs += len;
flags2 = LittleEndian.getShort(data, ofs);
ofs += LittleEndianConsts.SHORT_SIZE;
unknown1 = LittleEndian.getShort(data, ofs);
ofs += LittleEndianConsts.SHORT_SIZE;
len = LittleEndian.getInt(data, ofs);
ofs += LittleEndianConsts.INT_SIZE;
command = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
ofs += len;
if (totalSize < ofs) {
throw new Ole10NativeException("Invalid Ole10Native");
}
dataSize = LittleEndian.getInt(data, ofs);
ofs += LittleEndianConsts.INT_SIZE;
if (dataSize < 0 || totalSize - (ofs - LittleEndianConsts.INT_SIZE) < dataSize) {
throw new Ole10NativeException("Invalid Ole10Native");
}
@ -206,14 +206,12 @@ public class Ole10Native {
if ((long)dataSize + (long)ofs > (long)data.length) { //cast to avoid overflow
throw new Ole10NativeException("Invalid Ole10Native: declared data length > available data");
}
dataBuffer = IOUtils.safelyAllocate(dataSize, MAX_RECORD_LENGTH);
System.arraycopy(data, ofs, dataBuffer, 0, dataSize);
ofs += dataSize;
dataBuffer = IOUtils.safelyClone(data, ofs, dataSize, MAX_RECORD_LENGTH);
}
/**
* Add the \1OLE marker entry, which is not the Ole10Native entry.
* Beside this "\u0001Ole" record there were several other records, e.g. CompObj,
* Beside this "\u0001Ole" record there were several other records, e.g. CompObj,
* OlePresXXX, but it seems, that they aren't necessary
*/
public static void createOleMarkerEntry(final DirectoryEntry parent) throws IOException {
@ -224,14 +222,14 @@ public class Ole10Native {
/**
* Add the \1OLE marker entry, which is not the Ole10Native entry.
* Beside this "\u0001Ole" record there were several other records, e.g. CompObj,
* Beside this "\u0001Ole" record there were several other records, e.g. CompObj,
* OlePresXXX, but it seems, that they aren't necessary
*/
public static void createOleMarkerEntry(final POIFSFileSystem poifs) throws IOException {
createOleMarkerEntry(poifs.getRoot());
}
/*
* Helper - determine length of zero terminated string (ASCIIZ).
*/
@ -247,7 +245,7 @@ public class Ole10Native {
/**
* Returns the value of the totalSize field - the total length of the
* structure is totalSize + 4 (value of this field + size of this field).
*
*
* @return the totalSize
*/
public int getTotalSize() {
@ -256,7 +254,7 @@ public class Ole10Native {
/**
* Returns flags1 - currently unknown - usually 0x0002.
*
*
* @return the flags1
*/
public short getFlags1() {
@ -267,7 +265,7 @@ public class Ole10Native {
* Returns the label field - usually the name of the file (without
* directory) but probably may be any name specified during
* packaging/embedding the data.
*
*
* @return the label
*/
public String getLabel() {
@ -277,7 +275,7 @@ public class Ole10Native {
/**
* Returns the fileName field - usually the name of the file being embedded
* including the full path.
*
*
* @return the fileName
*/
public String getFileName() {
@ -286,7 +284,7 @@ public class Ole10Native {
/**
* Returns flags2 - currently unknown - mostly 0x0000.
*
*
* @return the flags2
*/
public short getFlags2() {
@ -295,7 +293,7 @@ public class Ole10Native {
/**
* Returns unknown1 field - currently unknown.
*
*
* @return the unknown1
*/
public short getUnknown1() {
@ -306,7 +304,7 @@ public class Ole10Native {
* Returns the command field - usually the name of the file being embedded
* including the full path, may be a command specified during embedding the
* file.
*
*
* @return the command
*/
public String getCommand() {
@ -317,7 +315,7 @@ public class Ole10Native {
* Returns the size of the embedded file. If the size is 0 (zero), no data
* has been embedded. To be sure, that no data has been embedded, check
* whether {@link #getDataBuffer()} returns <code>null</code>.
*
*
* @return the dataSize
*/
public int getDataSize() {
@ -330,7 +328,7 @@ public class Ole10Native {
* provide information about the data, but the actual data is not included.
* (So label, filename etc. are available, but this method returns
* <code>null</code>.)
*
*
* @return the dataBuffer
*/
public byte[] getDataBuffer() {
@ -339,7 +337,7 @@ public class Ole10Native {
/**
* Returns the flags3 - currently unknown.
*
*
* @return the flags3
*/
public short getFlags3() {
@ -358,7 +356,7 @@ public class Ole10Native {
@SuppressWarnings("resource")
LittleEndianOutputStream leosOut = new LittleEndianOutputStream(out);
switch (mode) {
case parsed: {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
@ -379,7 +377,7 @@ public class Ole10Native {
leos.write(getDataBuffer());
leos.writeShort(getFlags3());
leos.close(); // satisfy compiler ...
leosOut.writeInt(bos.size()); // total size
bos.writeTo(out);
break;

View File

@ -124,19 +124,13 @@ public abstract class Property implements Child, POIFSViewable {
*/
protected Property(int index, byte [] array, int offset)
{
_raw_data = new byte[ POIFSConstants.PROPERTY_SIZE ];
System.arraycopy(array, offset, _raw_data, 0,
POIFSConstants.PROPERTY_SIZE);
_raw_data = Arrays.copyOfRange(array, offset, offset + POIFSConstants.PROPERTY_SIZE);
_name_size = new ShortField(_name_size_offset, _raw_data);
_property_type =
new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET, _raw_data);
_property_type = new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET, _raw_data);
_node_color = new ByteField(_node_color_offset, _raw_data);
_previous_property = new IntegerField(_previous_property_offset,
_raw_data);
_next_property = new IntegerField(_next_property_offset,
_raw_data);
_child_property = new IntegerField(_child_property_offset,
_raw_data);
_previous_property = new IntegerField(_previous_property_offset, _raw_data);
_next_property = new IntegerField(_next_property_offset, _raw_data);
_child_property = new IntegerField(_child_property_offset, _raw_data);
_storage_clsid = new ClassID(_raw_data,_storage_clsid_offset);
_user_flags = new IntegerField(_user_flags_offset, 0, _raw_data);
_seconds_1 = new IntegerField(_seconds_1_offset, _raw_data);
@ -146,8 +140,7 @@ public abstract class Property implements Child, POIFSViewable {
_start_block = new IntegerField(_start_block_offset, _raw_data);
_size = new IntegerField(_size_offset, _raw_data);
_index = index;
int name_length = (_name_size.get() / LittleEndianConsts.SHORT_SIZE)
- 1;
int name_length = (_name_size.get() / LittleEndianConsts.SHORT_SIZE) - 1;
if (name_length < 1)
{

View File

@ -245,8 +245,7 @@ public class EmbeddedExtractor implements Iterable<EmbeddedExtractor> {
}
int pictureBytesLen = idxEnd-idxStart+6;
byte[] pdfBytes = IOUtils.safelyAllocate(pictureBytesLen, MAX_RECORD_LENGTH);
System.arraycopy(pictureBytes, idxStart, pdfBytes, 0, pictureBytesLen);
byte[] pdfBytes = IOUtils.safelyClone(pictureBytes, idxStart, pictureBytesLen, MAX_RECORD_LENGTH);
String filename = source.getShapeName().trim();
if (!endsWithIgnoreCase(filename, ".pdf")) {
filename += ".pdf";

View File

@ -18,6 +18,8 @@
package org.apache.poi.ss.formula.functions;
import java.util.Arrays;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.EvaluationException;
@ -60,8 +62,7 @@ public class Mirr extends MultiOperandNumericFunction {
double financeRate = values[values.length-1];
double reinvestRate = values[values.length-2];
double[] mirrValues = new double[values.length - 2];
System.arraycopy(values, 0, mirrValues, 0, mirrValues.length);
double[] mirrValues = Arrays.copyOf(values, values.length - 2);
boolean mirrValuesAreAllNegatives = true;
for (double mirrValue : mirrValues) {

View File

@ -17,6 +17,8 @@
package org.apache.poi.ss.formula.functions;
import java.util.Arrays;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.ThreeDEval;
import org.apache.poi.ss.formula.TwoDEval;
@ -67,20 +69,13 @@ public abstract class MultiOperandNumericFunction implements Function {
}
public double[] toArray() {
if (_count < 1) {
return EMPTY_DOUBLE_ARRAY;
}
double[] result = new double[_count];
System.arraycopy(_array, 0, result, 0, _count);
return result;
return _count < 1 ? EMPTY_DOUBLE_ARRAY : Arrays.copyOf(_array, _count);
}
private void ensureCapacity(int reqSize) {
if (reqSize > _array.length) {
int newSize = reqSize * 3 / 2; // grow with 50% extra
double[] newArr = new double[newSize];
System.arraycopy(_array, 0, newArr, 0, _count);
_array = newArr;
_array = Arrays.copyOf(_array, newSize);
}
}
@ -159,7 +154,7 @@ public abstract class MultiOperandNumericFunction implements Function {
public boolean isHiddenRowCounted() {
return true;
}
/**
* Collects values from a single argument
*/

View File

@ -17,6 +17,8 @@
package org.apache.poi.ss.formula.functions;
import java.util.Arrays;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.EvaluationException;
import org.apache.poi.ss.formula.eval.NumberEval;
@ -43,8 +45,7 @@ public final class Npv implements Function {
try {
double rate = NumericFunction.singleOperandEvaluate(args[0], srcRowIndex, srcColumnIndex);
// convert tail arguments into an array of doubles
ValueEval[] vargs = new ValueEval[args.length-1];
System.arraycopy(args, 1, vargs, 0, vargs.length);
ValueEval[] vargs = Arrays.copyOfRange(args, 1, args.length, ValueEval[].class);
double[] values = AggregateFunction.ValueCollector.collectValues(vargs);
double result = FinanceLib.npv(rate, values);

View File

@ -17,6 +17,8 @@
package org.apache.poi.ss.formula.functions;
import java.util.Arrays;
import org.apache.poi.ss.formula.TwoDEval;
import org.apache.poi.ss.formula.eval.AreaEval;
import org.apache.poi.ss.formula.eval.BlankEval;
@ -124,9 +126,9 @@ public final class Sumproduct implements Function {
private static ValueEval evaluateAreaSumProduct(ValueEval[] evalArgs) throws EvaluationException {
int maxN = evalArgs.length;
TwoDEval[] args = new TwoDEval[maxN];
TwoDEval[] args;
try {
System.arraycopy(evalArgs, 0, args, 0, maxN);
args = Arrays.copyOf(evalArgs, maxN, TwoDEval[].class);
} catch (ArrayStoreException e) {
// one of the other args was not an AreaRef
return ErrorEval.VALUE_INVALID;

View File

@ -18,6 +18,8 @@
package org.apache.poi.util;
import java.util.Arrays;
/**
* Utility classes for dealing with arrays.
*/
@ -54,8 +56,7 @@ public final class ArrayUtil {
}
// Grab the bit to move
Object[] toMove = new Object[numToMove];
System.arraycopy(array, moveFrom, toMove, 0, numToMove);
Object[] toMove = Arrays.copyOfRange(array, moveFrom, moveFrom+numToMove);
// Grab the bit to be shifted
Object[] toShift;
@ -63,14 +64,12 @@ public final class ArrayUtil {
if(moveFrom > moveTo) {
// Moving to an earlier point in the array
// Grab everything between the two points
toShift = new Object[(moveFrom-moveTo)];
System.arraycopy(array, moveTo, toShift, 0, toShift.length);
toShift = Arrays.copyOfRange(array, moveTo, moveFrom);
shiftTo = moveTo + numToMove;
} else {
// Moving to a later point in the array
// Grab everything from after the toMove block, to the new point
toShift = new Object[(moveTo-moveFrom)];
System.arraycopy(array, moveFrom+numToMove, toShift, 0, toShift.length);
toShift = Arrays.copyOfRange(array, moveFrom+numToMove, moveTo+numToMove);
shiftTo = moveFrom;
}

View File

@ -28,6 +28,7 @@ import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.util.Arrays;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
@ -35,6 +36,8 @@ import org.apache.poi.EmptyFileException;
import org.apache.poi.POIDocument;
import org.apache.poi.ss.usermodel.Workbook;
@Internal
public final class IOUtils {
private static final POILogger logger = POILogFactory.getLogger( IOUtils.class );
@ -610,6 +613,18 @@ public final class IOUtils {
checkLength(length, maxLength);
}
public static byte[] safelyClone(byte[] src, int offset, int length, int maxLength) {
if (src == null) {
return null;
}
assert(offset >= 0 && length >= 0 && maxLength >= 0);
safelyAllocateCheck(Math.min(src.length-offset,length), maxLength);
return Arrays.copyOfRange(src, offset, offset+length);
}
/**
* Simple utility function to check that you haven't hit EOF
* when reading a byte.

View File

@ -26,93 +26,38 @@ import java.io.Serializable;
* a utility class for handling little-endian numbers, which the 80x86 world is
* replete with. The methods are all static, and input/output is from/to byte
* arrays, or from InputStreams.
*
* @author Marc Johnson (mjohnson at apache dot org)
* @author Andrew Oliver (acoliver at apache dot org)
*/
public class LittleEndian implements LittleEndianConsts
{
@Internal
public final class LittleEndian implements LittleEndianConsts {
/**
* Exception to handle buffer underruns
*
*
* @author Marc Johnson (mjohnson at apache dot org)
*/
public static final class BufferUnderrunException extends IOException
{
public static final class BufferUnderrunException extends IOException {
/**
* Serial version UID
*
*
* @see Serializable
*/
private static final long serialVersionUID = 8736973884877006145L;
BufferUnderrunException()
{
BufferUnderrunException() {
super( "buffer underrun" );
}
}
/**
* Copy a portion of a byte array
*
* @param data
* the original byte array
* @param offset
* Where to start copying from.
* @param size
* Number of bytes to copy.
* @return The byteArray value
*
* @see #getByteArray(byte[], int, int, int) if size is not a constant
*
* @throws IndexOutOfBoundsException
* - if copying would cause access of data outside array bounds.
*/
public static byte[] getByteArray( byte[] data, int offset, int size )
{
byte[] copy = new byte[size];
System.arraycopy( data, offset, copy, 0, size );
return copy;
}
/**
* Copy a portion of a byte array
*
* @param data
* the original byte array
* @param offset
* Where to start copying from.
* @param size
* Number of bytes to copy.
* @param maxSize
* Size must be <= maxSize or an exception is thrown.
* Use this to avoid potential OOMs on corrupt data.
* @return The byteArray value
* @throws IndexOutOfBoundsException
* - if copying would cause access of data outside array bounds.
*/
public static byte[] getByteArray( byte[] data, int offset, int size, int maxSize)
{
byte[] copy = IOUtils.safelyAllocate(size, maxSize);
System.arraycopy( data, offset, copy, 0, size );
return copy;
}
/**
* get a double value from a byte array, reads it in little endian format
* then converts the resulting revolting IEEE 754 (curse them) floating
* point number to a happy java double
*
*
* @param data
* the byte array
* @return the double (64-bit) value
*/
public static double getDouble( byte[] data )
{
public static double getDouble( byte[] data ) {
return Double.longBitsToDouble( getLong( data, 0 ) );
}
@ -120,15 +65,14 @@ public class LittleEndian implements LittleEndianConsts
* get a double value from a byte array, reads it in little endian format
* then converts the resulting revolting IEEE 754 (curse them) floating
* point number to a happy java double
*
*
* @param data
* the byte array
* @param offset
* a starting offset into the byte array
* @return the double (64-bit) value
*/
public static double getDouble( byte[] data, int offset )
{
public static double getDouble( byte[] data, int offset ) {
return Double.longBitsToDouble( getLong( data, offset ) );
}
@ -136,13 +80,12 @@ public class LittleEndian implements LittleEndianConsts
* get a float value from a byte array, reads it in little endian format
* then converts the resulting revolting IEEE 754 (curse them) floating
* point number to a happy java float
*
*
* @param data
* the byte array
* @return the double (64-bit) value
*/
public static float getFloat( byte[] data )
{
public static float getFloat( byte[] data ) {
return getFloat( data, 0 );
}
@ -150,72 +93,67 @@ public class LittleEndian implements LittleEndianConsts
* get a float value from a byte array, reads it in little endian format
* then converts the resulting revolting IEEE 754 (curse them) floating
* point number to a happy java float
*
*
* @param data
* the byte array
* @param offset
* a starting offset into the byte array
* @return the double (64-bit) value
*/
public static float getFloat( byte[] data, int offset )
{
public static float getFloat( byte[] data, int offset ) {
return Float.intBitsToFloat( getInt( data, offset ) );
}
/**
* get an int value from the beginning of a byte array
*
*
* @param data
* the byte array
* @return the int (32-bit) value
*/
public static int getInt( byte[] data )
{
public static int getInt( byte[] data ) {
return getInt( data, 0 );
}
/**
* get an int value from a byte array
*
*
* @param data
* the byte array
* @param offset
* a starting offset into the byte array
* @return the int (32-bit) value
*/
public static int getInt( byte[] data, int offset )
{
public static int getInt( byte[] data, int offset ) {
int i = offset;
int b0 = data[i++] & 0xFF;
int b1 = data[i++] & 0xFF;
int b2 = data[i++] & 0xFF;
int b3 = data[i++] & 0xFF;
return ( b3 << 24 ) + ( b2 << 16 ) + ( b1 << 8 ) + ( b0 << 0 );
int b3 = data[i ] & 0xFF;
return ( b3 << 24 ) + ( b2 << 16 ) + ( b1 << 8 ) + (b0);
}
/**
* get a long value from a byte array
*
*
* @param data
* the byte array
* @return the long (64-bit) value
*/
public static long getLong( byte[] data )
{
public static long getLong( byte[] data ) {
return getLong( data, 0 );
}
/**
* get a long value from a byte array
*
*
* @param data
* the byte array
* @param offset
* a starting offset into the byte array
* @return the long (64-bit) value
*/
public static long getLong( byte[] data, int offset )
{
public static long getLong( byte[] data, int offset ) {
long result = 0xff & data[offset + 7];
for ( int j = offset + LONG_SIZE - 1; j >= offset; j-- )
@ -228,35 +166,33 @@ public class LittleEndian implements LittleEndianConsts
/**
* get a short value from the beginning of a byte array
*
*
* @param data
* the byte array
* @return the short (16-bit) value
*/
public static short getShort( byte[] data )
{
public static short getShort( byte[] data ) {
return getShort( data, 0 );
}
/**
* get a short value from a byte array
*
*
* @param data
* the byte array
* @param offset
* a starting offset into the byte array
* @return the short (16-bit) value
*/
public static short getShort( byte[] data, int offset )
{
public static short getShort( byte[] data, int offset ) {
int b0 = data[offset] & 0xFF;
int b1 = data[offset + 1] & 0xFF;
return (short) ( ( b1 << 8 ) + ( b0 << 0 ) );
return (short) ( ( b1 << 8 ) + (b0) );
}
/**
* Read short array
*
*
* @param data
* the original byte array
* @param offset
@ -266,8 +202,7 @@ public class LittleEndian implements LittleEndianConsts
* @throws IndexOutOfBoundsException
* - if read would cause access of data outside array bounds.
*/
public static short[] getShortArray( byte[] data, int offset, int size )
{
public static short[] getShortArray( byte[] data, int offset, int size ) {
short[] result = new short[size / SHORT_SIZE];
for ( int i = 0; i < result.length; i++ )
{
@ -278,83 +213,77 @@ public class LittleEndian implements LittleEndianConsts
/**
* get the unsigned value of a byte.
*
*
* @param data
* the byte array.
* @return the unsigned value of the byte as a 16 bit short
*/
public static short getUByte( byte[] data )
{
public static short getUByte( byte[] data ) {
return (short) ( data[0] & 0xFF );
}
/**
* get the unsigned value of a byte.
*
*
* @param data
* the byte array.
* @param offset
* a starting offset into the byte array.
* @return the unsigned value of the byte as a 16 bit short
*/
public static short getUByte( byte[] data, int offset )
{
public static short getUByte( byte[] data, int offset ) {
return (short) ( data[offset] & 0xFF );
}
/**
* get an unsigned int value from a byte array
*
*
* @param data
* the byte array
* @return the unsigned int (32-bit) value in a long
*/
public static long getUInt( byte[] data )
{
public static long getUInt( byte[] data ) {
return getUInt( data, 0 );
}
/**
* get an unsigned int value from a byte array
*
*
* @param data
* the byte array
* @param offset
* a starting offset into the byte array
* @return the unsigned int (32-bit) value in a long
*/
public static long getUInt( byte[] data, int offset )
{
public static long getUInt( byte[] data, int offset ) {
long retNum = getInt( data, offset );
return retNum & 0x00FFFFFFFFl;
return retNum & 0x00FFFFFFFFL;
}
/**
* get an unsigned short value from the beginning of a byte array
*
*
* @param data
* the byte array
* @return the unsigned short (16-bit) value in an int
*/
public static int getUShort( byte[] data )
{
public static int getUShort( byte[] data ) {
return getUShort( data, 0 );
}
/**
* get an unsigned short value from a byte array
*
*
* @param data
* the byte array
* @param offset
* a starting offset into the byte array
* @return the unsigned short (16-bit) value in an integer
*/
public static int getUShort( byte[] data, int offset )
{
public static int getUShort( byte[] data, int offset ) {
int b0 = data[offset] & 0xFF;
int b1 = data[offset + 1] & 0xFF;
return ( b1 << 8 ) + ( b0 << 0 );
return ( b1 << 8 ) + (b0);
}
/**
@ -366,14 +295,13 @@ public class LittleEndian implements LittleEndianConsts
* </p>
* Added for consistency with other put~() methods
*/
public static void putByte( byte[] data, int offset, int value )
{
public static void putByte( byte[] data, int offset, int value ) {
data[offset] = (byte) value;
}
/**
* put a double value into a byte array
*
*
* @param data
* the byte array
* @param offset
@ -381,14 +309,13 @@ public class LittleEndian implements LittleEndianConsts
* @param value
* the double (64-bit) value
*/
public static void putDouble( byte[] data, int offset, double value )
{
public static void putDouble( byte[] data, int offset, double value ) {
putLong( data, offset, Double.doubleToLongBits( value ) );
}
/**
* put a double value into a byte array
*
*
* @param value
* the double (64-bit) value
* @param outputStream
@ -396,15 +323,13 @@ public class LittleEndian implements LittleEndianConsts
* @throws IOException
* if an I/O error occurs
*/
public static void putDouble( double value, OutputStream outputStream )
throws IOException
{
public static void putDouble( double value, OutputStream outputStream ) throws IOException {
putLong( Double.doubleToLongBits( value ), outputStream );
}
/**
* put a float value into a byte array
*
*
* @param data
* the byte array
* @param offset
@ -412,14 +337,13 @@ public class LittleEndian implements LittleEndianConsts
* @param value
* the float (32-bit) value
*/
public static void putFloat( byte[] data, int offset, float value )
{
public static void putFloat( byte[] data, int offset, float value ) {
putInt( data, offset, Float.floatToIntBits( value ) );
}
/**
* put a float value into a byte array
*
*
* @param value
* the float (32-bit) value
* @param outputStream
@ -427,15 +351,14 @@ public class LittleEndian implements LittleEndianConsts
* @throws IOException
* if an I/O error occurs
*/
public static void putFloat( float value, OutputStream outputStream )
throws IOException
{
@SuppressWarnings("unused")
public static void putFloat(float value, OutputStream outputStream ) throws IOException {
putInt( Float.floatToIntBits( value ), outputStream );
}
/**
* put an int value into a byte array
*
*
* @param data
* the byte array
* @param offset
@ -443,18 +366,17 @@ public class LittleEndian implements LittleEndianConsts
* @param value
* the int (32-bit) value
*/
public static void putInt( byte[] data, int offset, int value )
{
public static void putInt( byte[] data, int offset, int value ) {
int i = offset;
data[i++] = (byte) ( ( value >>> 0 ) & 0xFF );
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
data[i++] = (byte) ( ( value ) & 0xFF );
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
data[i++] = (byte) ( ( value >>> 16 ) & 0xFF );
data[i++] = (byte) ( ( value >>> 24 ) & 0xFF );
data[i] = (byte) ( ( value >>> 24 ) & 0xFF );
}
/**
* Put int into output stream
*
*
* @param value
* the int (32-bit) value
* @param outputStream
@ -462,18 +384,16 @@ public class LittleEndian implements LittleEndianConsts
* @throws IOException
* if an I/O error occurs
*/
public static void putInt( int value, OutputStream outputStream )
throws IOException
{
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
public static void putInt( int value, OutputStream outputStream ) throws IOException {
outputStream.write( (byte) ( ( value ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) );
}
/**
* put a long value into a byte array
*
*
* @param data
* the byte array
* @param offset
@ -481,10 +401,9 @@ public class LittleEndian implements LittleEndianConsts
* @param value
* the long (64-bit) value
*/
public static void putLong( byte[] data, int offset, long value )
{
data[offset + 0] = (byte) ( ( value >>> 0 ) & 0xFF );
data[offset + 1] = (byte) ( ( value >>> 8 ) & 0xFF );
public static void putLong( byte[] data, int offset, long value ) {
data[offset ] = (byte) ( ( value ) & 0xFF );
data[offset + 1] = (byte) ( ( value >>> 8 ) & 0xFF );
data[offset + 2] = (byte) ( ( value >>> 16 ) & 0xFF );
data[offset + 3] = (byte) ( ( value >>> 24 ) & 0xFF );
data[offset + 4] = (byte) ( ( value >>> 32 ) & 0xFF );
@ -495,7 +414,7 @@ public class LittleEndian implements LittleEndianConsts
/**
* Put long into output stream
*
*
* @param value
* the long (64-bit) value
* @param outputStream
@ -503,11 +422,9 @@ public class LittleEndian implements LittleEndianConsts
* @throws IOException
* if an I/O error occurs
*/
public static void putLong( long value, OutputStream outputStream )
throws IOException
{
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
public static void putLong( long value, OutputStream outputStream ) throws IOException {
outputStream.write( (byte) ( ( value ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 32 ) & 0xFF ) );
@ -518,7 +435,7 @@ public class LittleEndian implements LittleEndianConsts
/**
* put a short value into a byte array
*
*
* @param data
* the byte array
* @param offset
@ -526,16 +443,15 @@ public class LittleEndian implements LittleEndianConsts
* @param value
* the short (16-bit) value
*/
public static void putShort( byte[] data, int offset, short value )
{
public static void putShort( byte[] data, int offset, short value ) {
int i = offset;
data[i++] = (byte) ( ( value >>> 0 ) & 0xFF );
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
data[i++] = (byte) ( ( value ) & 0xFF );
data[i ] = (byte) ( ( value >>> 8 ) & 0xFF );
}
/**
* Put signed short into output stream
*
*
* @param value
* the short (16-bit) value
* @param outputStream
@ -543,16 +459,14 @@ public class LittleEndian implements LittleEndianConsts
* @throws IOException
* if an I/O error occurs
*/
public static void putShort( OutputStream outputStream, short value )
throws IOException
{
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
public static void putShort( OutputStream outputStream, short value ) throws IOException {
outputStream.write( (byte) ( ( value ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
}
/**
* Stores short array in buffer
*
*
* @param data
* the byte array
* @param startOffset
@ -560,9 +474,7 @@ public class LittleEndian implements LittleEndianConsts
* @param value
* the short (16-bit) values
*/
public static void putShortArray( byte[] data, int startOffset,
short[] value )
{
public static void putShortArray( byte[] data, int startOffset, short[] value ) {
int offset = startOffset;
for ( short s : value )
{
@ -573,47 +485,45 @@ public class LittleEndian implements LittleEndianConsts
/**
* put an unsigned byte value into a byte array
*
*
* @param data
* the byte array
* @param offset
* a starting offset into the byte array
* @param value
* the short (16-bit) value
*
*
* @exception ArrayIndexOutOfBoundsException
* may be thrown
*/
public static void putUByte( byte[] data, int offset, short value )
{
public static void putUByte( byte[] data, int offset, short value ) {
data[offset] = (byte) ( value & 0xFF );
}
/**
* put an unsigned int value into a byte array
*
*
* @param data
* the byte array
* @param offset
* a starting offset into the byte array
* @param value
* the int (32-bit) value
*
*
* @exception ArrayIndexOutOfBoundsException
* may be thrown
*/
public static void putUInt( byte[] data, int offset, long value )
{
public static void putUInt( byte[] data, int offset, long value ) {
int i = offset;
data[i++] = (byte) ( ( value >>> 0 ) & 0xFF );
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
data[i++] = (byte) ( ( value ) & 0xFF );
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
data[i++] = (byte) ( ( value >>> 16 ) & 0xFF );
data[i++] = (byte) ( ( value >>> 24 ) & 0xFF );
data[i ] = (byte) ( ( value >>> 24 ) & 0xFF );
}
/**
* Put unsigned int into output stream
*
*
* @param value
* the int (32-bit) value
* @param outputStream
@ -621,38 +531,35 @@ public class LittleEndian implements LittleEndianConsts
* @throws IOException
* if an I/O error occurs
*/
public static void putUInt( long value, OutputStream outputStream )
throws IOException
{
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
public static void putUInt( long value, OutputStream outputStream ) throws IOException {
outputStream.write( (byte) ( ( value ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 16 ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 24 ) & 0xFF ) );
}
/**
* put an unsigned short value into a byte array
*
*
* @param data
* the byte array
* @param offset
* a starting offset into the byte array
* @param value
* the short (16-bit) value
*
*
* @exception ArrayIndexOutOfBoundsException
* may be thrown
*/
public static void putUShort( byte[] data, int offset, int value )
{
public static void putUShort( byte[] data, int offset, int value ) {
int i = offset;
data[i++] = (byte) ( ( value >>> 0 ) & 0xFF );
data[i++] = (byte) ( ( value >>> 8 ) & 0xFF );
data[i++] = (byte) ( ( value ) & 0xFF );
data[i ] = (byte) ( ( value >>> 8 ) & 0xFF );
}
/**
* Put unsigned short into output stream
*
*
* @param value
* the unsigned short (16-bit) value
* @param outputStream
@ -660,16 +567,14 @@ public class LittleEndian implements LittleEndianConsts
* @throws IOException
* if an I/O error occurs
*/
public static void putUShort( int value, OutputStream outputStream )
throws IOException
{
outputStream.write( (byte) ( ( value >>> 0 ) & 0xFF ) );
public static void putUShort( int value, OutputStream outputStream ) throws IOException {
outputStream.write( (byte) ( ( value ) & 0xFF ) );
outputStream.write( (byte) ( ( value >>> 8 ) & 0xFF ) );
}
/**
* get an int value from an InputStream
*
*
* @param stream
* the InputStream from which the int is to be read
* @return the int (32-bit) value
@ -678,9 +583,7 @@ public class LittleEndian implements LittleEndianConsts
* @exception BufferUnderrunException
* if the stream cannot provide enough bytes
*/
public static int readInt( InputStream stream ) throws IOException,
BufferUnderrunException
{
public static int readInt( InputStream stream ) throws IOException {
int ch1 = stream.read();
int ch2 = stream.read();
int ch3 = stream.read();
@ -689,12 +592,12 @@ public class LittleEndian implements LittleEndianConsts
{
throw new BufferUnderrunException();
}
return ( ch4 << 24 ) + ( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 << 0 );
return ( ch4 << 24 ) + ( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 );
}
/**
* get an unsigned int value from an InputStream
*
*
* @param stream
* the InputStream from which the int is to be read
* @return the unsigned int (32-bit) value
@ -703,16 +606,14 @@ public class LittleEndian implements LittleEndianConsts
* @exception BufferUnderrunException
* if the stream cannot provide enough bytes
*/
public static long readUInt( InputStream stream ) throws IOException,
BufferUnderrunException
{
public static long readUInt( InputStream stream ) throws IOException {
long retNum = readInt(stream);
return retNum & 0x00FFFFFFFFl;
return retNum & 0x00FFFFFFFFL;
}
/**
* get a long value from an InputStream
*
*
* @param stream
* the InputStream from which the long is to be read
* @return the long (64-bit) value
@ -721,9 +622,7 @@ public class LittleEndian implements LittleEndianConsts
* @exception BufferUnderrunException
* if the stream cannot provide enough bytes
*/
public static long readLong( InputStream stream ) throws IOException,
BufferUnderrunException
{
public static long readLong( InputStream stream ) throws IOException {
int ch1 = stream.read();
int ch2 = stream.read();
int ch3 = stream.read();
@ -732,8 +631,7 @@ public class LittleEndian implements LittleEndianConsts
int ch6 = stream.read();
int ch7 = stream.read();
int ch8 = stream.read();
if ( ( ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8 ) < 0 )
{
if ( ( ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8 ) < 0 ) {
throw new BufferUnderrunException();
}
@ -741,12 +639,12 @@ public class LittleEndian implements LittleEndianConsts
+ ( (long) ch6 << 40 ) + ( (long) ch5 << 32 )
+ ( (long) ch4 << 24 ) + // cast to long to preserve bit 31
// (sign bit for ints)
( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 << 0 );
( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 );
}
/**
* get a short value from an InputStream
*
*
* @param stream
* the InputStream from which the short is to be read
* @return the short (16-bit) value
@ -755,39 +653,32 @@ public class LittleEndian implements LittleEndianConsts
* @exception BufferUnderrunException
* if the stream cannot provide enough bytes
*/
public static short readShort( InputStream stream ) throws IOException,
BufferUnderrunException
{
public static short readShort( InputStream stream ) throws IOException {
return (short) readUShort( stream );
}
public static int readUShort( InputStream stream ) throws IOException,
BufferUnderrunException
{
public static int readUShort( InputStream stream ) throws IOException {
int ch1 = stream.read();
int ch2 = stream.read();
if ( ( ch1 | ch2 ) < 0 )
{
if ( ( ch1 | ch2 ) < 0 ) {
throw new BufferUnderrunException();
}
return ( ch2 << 8 ) + ( ch1 << 0 );
return ( ch2 << 8 ) + ( ch1 );
}
/**
* Convert an 'unsigned' byte to an integer. ie, don't carry across the
* sign.
*
*
* @param b
* Description of the Parameter
* @return Description of the Return Value
*/
public static int ubyteToInt( byte b )
{
public static int ubyteToInt( byte b ) {
return b & 0xFF;
}
private LittleEndian()
{
private LittleEndian() {
// no instances of this class
}
}

View File

@ -65,6 +65,9 @@ public final class StringUtil {
final int offset,
final int len)
throws ArrayIndexOutOfBoundsException, IllegalArgumentException {
if (len == 0) {
return "";
}
if ((offset < 0) || (offset >= string.length)) {
throw new ArrayIndexOutOfBoundsException("Illegal offset " + offset + " (String data is of length " + string.length + ")");
}

View File

@ -41,7 +41,7 @@ public class XSSFColor extends ExtendedColor {
//noinspection deprecation
return color == null ? null : new XSSFColor(color, map);
}
/**
* Create an instance of XSSFColor from the supplied XML bean, with default color indexes
* @param color The {@link CTColor} to use as color-value.
@ -52,7 +52,7 @@ public class XSSFColor extends ExtendedColor {
public XSSFColor(CTColor color) {
this(color, new DefaultIndexedColorMap());
}
/**
* Create an instance of XSSFColor from the supplied XML bean, with the given color indexes
* @param color The {@link CTColor} to use as color-value.
@ -119,7 +119,7 @@ public class XSSFColor extends ExtendedColor {
this(CTColor.Factory.newInstance(), colorMap);
ctColor.setRgb(rgb);
}
/**
* @param indexedColor color index (Enum named for default colors)
* @param colorMap The IndexedColorMap to use instead of the default one
@ -167,7 +167,7 @@ public class XSSFColor extends ExtendedColor {
public boolean isThemed() {
return ctColor.isSetTheme();
}
/**
* @return true if the ctColor has a alpha
*/
@ -215,14 +215,8 @@ public class XSSFColor extends ExtendedColor {
return null;
}
if(rgb.length == 4) {
// Need to trim off the alpha
byte[] tmp = new byte[3];
System.arraycopy(rgb, 1, tmp, 0, 3);
return tmp;
} else {
return rgb;
}
// Need to trim off the alpha
return rgb.length == 4 ? Arrays.copyOfRange(rgb, 1, 4) : rgb;
}
/**
@ -258,7 +252,7 @@ public class XSSFColor extends ExtendedColor {
}
return null;
}
/**
* Standard Alpha Red Green Blue ctColor value (ARGB).
*/
@ -403,7 +397,7 @@ public class XSSFColor extends ExtendedColor {
}
return (XSSFColor)color;
}
@Override
public int hashCode(){
return ctColor.toString().hashCode();
@ -437,7 +431,7 @@ public class XSSFColor extends ExtendedColor {
private boolean sameAuto(XSSFColor other) {
return isAuto() == other.isAuto();
}
@Override
public boolean equals(Object o){
if(!(o instanceof XSSFColor)) {
@ -445,7 +439,7 @@ public class XSSFColor extends ExtendedColor {
}
XSSFColor other = (XSSFColor)o;
// Compare each field in ctColor.
// Cannot compare ctColor's XML string representation because equivalent
// colors may have different relation namespace URI's

View File

@ -188,8 +188,7 @@ public final class ChunkFactory {
}
// Now, create the chunk
byte[] contents = IOUtils.safelyAllocate(header.getLength(), MAX_RECORD_LENGTH);
System.arraycopy(data, offset+header.getSizeInBytes(), contents, 0, contents.length);
byte[] contents = IOUtils.safelyClone(data, offset+header.getSizeInBytes(), header.getLength(), MAX_RECORD_LENGTH);
Chunk chunk = new Chunk(header, trailer, separator, contents);
// Feed in the stuff from chunks_parse_cmds.tbl

View File

@ -17,16 +17,17 @@
package org.apache.poi.hdgf.chunks;
import java.util.Arrays;
/**
* A separator between the trailer of one chunk, and the
* header of the next one
*/
public final class ChunkSeparator {
protected byte[] separatorData;
final byte[] separatorData;
public ChunkSeparator(byte[] data, int offset) {
separatorData = new byte[4];
System.arraycopy(data, offset, separatorData, 0, 4);
separatorData = Arrays.copyOfRange(data, offset, offset+4);
}
public String toString() {

View File

@ -17,15 +17,16 @@
package org.apache.poi.hdgf.chunks;
import java.util.Arrays;
/**
* A trailer that follows a chunk
*/
public final class ChunkTrailer {
private byte[] trailerData;
private final byte[] trailerData;
public ChunkTrailer(byte[] data, int offset) {
trailerData = new byte[8];
System.arraycopy(data, offset, trailerData, 0, 8);
trailerData = Arrays.copyOfRange(data, offset, offset+8);
}
public String toString() {

View File

@ -38,21 +38,19 @@ public final class CompressedStreamStore extends StreamStore {
* We're not sure what this is, but it comes before the
* real contents in the de-compressed data
*/
private byte[] blockHeader = new byte[4];
private final byte[] blockHeader;
private boolean blockHeaderInContents;
protected byte[] _getCompressedContents() { return compressedContents; }
protected byte[] _getBlockHeader() { return blockHeader; }
byte[] _getCompressedContents() { return compressedContents; }
byte[] _getBlockHeader() { return blockHeader; }
/**
* Creates a new compressed StreamStore, which will handle
* the decompression.
*/
protected CompressedStreamStore(byte[] data, int offset, int length) throws IOException {
CompressedStreamStore(byte[] data, int offset, int length) throws IOException {
this(decompress(data,offset,length));
compressedContents = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH);
System.arraycopy(data, offset, compressedContents, 0, length);
compressedContents = IOUtils.safelyClone(data, offset, length, MAX_RECORD_LENGTH);
}
/**
* Handles passing the de-compressed data onto our superclass.

View File

@ -34,8 +34,7 @@ public class StreamStore { // TODO - instantiable superclass
* Creates a new, non compressed Stream Store
*/
protected StreamStore(byte[] data, int offset, int length) {
contents = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH);
System.arraycopy(data, offset, contents, 0, length);
contents = IOUtils.safelyClone(data, offset, length, MAX_RECORD_LENGTH);
}
protected void prependContentsWith(byte[] b) {

View File

@ -20,7 +20,7 @@ package org.apache.poi.hmef;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LZWDecompresser;
@ -43,18 +43,18 @@ public final class CompressedRTF extends LZWDecompresser {
LittleEndian.getInt(COMPRESSED_SIGNATURE);
public static final int UNCOMPRESSED_SIGNATURE_INT =
LittleEndian.getInt(UNCOMPRESSED_SIGNATURE);
// The 4096 byte LZW dictionary is pre-loaded with some common
// RTF fragments. These come from RTFLIB32.LIB, which ships
// with older versions of Visual Studio or the EDK
public static final String LZW_RTF_PRELOAD =
public static final String LZW_RTF_PRELOAD =
"{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}{\\f0\\fnil \\froman \\fswiss " +
"\\fmodern \\fscript \\fdecor MS Sans SerifSymbolArialTimes New RomanCourier" +
"{\\colortbl\\red0\\green0\\blue0\n\r\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab\\tx";
private int compressedSize;
private int decompressedSize;
public CompressedRTF() {
// Out flag has the normal meaning
// Length wise, we're 2 longer than we say, so the max len is 18
@ -76,9 +76,9 @@ public final class CompressedRTF extends LZWDecompresser {
decompressedSize = LittleEndian.readInt(src);
int compressionType = LittleEndian.readInt(src);
/* int dataCRC = */ LittleEndian.readInt(src);
// TODO - Handle CRC checking on the output side
// Do we need to do anything?
if(compressionType == UNCOMPRESSED_SIGNATURE_INT) {
// Nope, nothing fancy to do
@ -92,7 +92,7 @@ public final class CompressedRTF extends LZWDecompresser {
// Have it processed
super.decompress(src, res);
}
/**
* Returns how big the compressed version was.
*/
@ -100,7 +100,7 @@ public final class CompressedRTF extends LZWDecompresser {
// Return the size less the header
return compressedSize - 12;
}
/**
* Returns how big the decompressed version was.
*/
@ -119,10 +119,10 @@ public final class CompressedRTF extends LZWDecompresser {
@Override
protected int populateDictionary(byte[] dict) {
// Copy in the RTF constants
byte[] preload = LZW_RTF_PRELOAD.getBytes(Charset.forName("US-ASCII"));
// Copy in the RTF constants
byte[] preload = LZW_RTF_PRELOAD.getBytes(StandardCharsets.US_ASCII);
System.arraycopy(preload, 0, dict, 0, preload.length);
// Start adding new codes after the constants
return preload.length;
}

View File

@ -21,6 +21,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.poi.hmef.Attachment;
@ -45,7 +46,7 @@ public class MAPIAttribute {
private final MAPIProperty property;
private final int type;
private final byte[] data;
/**
* Constructs a single new attribute from
* the contents of the stream
@ -67,21 +68,20 @@ public class MAPIAttribute {
public byte[] getData() {
return data;
}
public String toString() {
String hex;
if(data.length <= 16) {
hex = HexDump.toHex(data);
} else {
byte[] d = new byte[16];
System.arraycopy(data, 0, d, 0, 16);
byte[] d = Arrays.copyOf(data, 16);
hex = HexDump.toHex(d);
hex = hex.substring(0, hex.length()-1) + ", ....]";
}
return property + " " + hex;
}
/**
* Parses a MAPI Properties TNEF Attribute, and returns
* the list of MAPI Attributes contained within it
@ -101,16 +101,16 @@ public class MAPIAttribute {
);
}
ByteArrayInputStream inp = new ByteArrayInputStream(parent.getData());
// First up, get the number of attributes
int count = LittleEndian.readInt(inp);
List<MAPIAttribute> attrs = new ArrayList<>();
// Now, read each one in in turn
for(int i=0; i<count; i++) {
int typeAndMV = LittleEndian.readUShort(inp);
int id = LittleEndian.readUShort(inp);
// Is it either Multi-Valued or Variable-Length?
boolean isMV = false;
boolean isVL = false;
@ -123,13 +123,13 @@ public class MAPIAttribute {
typeId == Types.BINARY.getId() || typeId == Types.DIRECTORY.getId()) {
isVL = true;
}
// Turn the type ID into a strongly typed thing
MAPIType type = Types.getById(typeId);
if (type == null) {
type = Types.createCustom(typeId);
}
// If it's a named property, rather than a standard
// MAPI property, grab the details of it
MAPIProperty prop = MAPIProperty.get(id);
@ -137,7 +137,7 @@ public class MAPIAttribute {
byte[] guid = new byte[16];
IOUtils.readFully(inp, guid);
int mptype = LittleEndian.readInt(inp);
// Get the name of it
String name;
if(mptype == 0) {
@ -153,14 +153,14 @@ public class MAPIAttribute {
name = StringUtil.getFromUnicodeLE(mpdata, 0, (mplen/2)-1);
skipToBoundary(mplen, inp);
}
// Now create
prop = MAPIProperty.createCustom(id, type, name);
}
if(prop == MAPIProperty.UNKNOWN) {
prop = MAPIProperty.createCustom(id, type, "(unknown " + Integer.toHexString(id) + ")");
}
// Now read in the value(s)
int values = 1;
if(isMV || isVL) {
@ -171,7 +171,7 @@ public class MAPIAttribute {
byte[] data = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
IOUtils.readFully(inp, data);
skipToBoundary(len, inp);
// Create
MAPIAttribute attr;
if(type == Types.UNICODE_STRING || type == Types.ASCII_STRING) {
@ -186,7 +186,7 @@ public class MAPIAttribute {
attrs.add(attr);
}
}
// All done
return attrs;
}

View File

@ -28,7 +28,7 @@ import org.apache.poi.util.IOUtils;
import org.apache.poi.util.StringUtil;
/**
* A pure-MAPI attribute holding RTF (compressed or not), which applies
* A pure-MAPI attribute holding RTF (compressed or not), which applies
* to a {@link HMEFMessage} or one of its {@link Attachment}s.
*/
public final class MAPIRtfAttribute extends MAPIAttribute {
@ -38,45 +38,44 @@ public final class MAPIRtfAttribute extends MAPIAttribute {
private final byte[] decompressed;
private final String data;
public MAPIRtfAttribute(MAPIProperty property, int type, byte[] data) throws IOException {
super(property, type, data);
// Decompress it, removing any trailing padding as needed
CompressedRTF rtf = new CompressedRTF();
byte[] tmp = rtf.decompress(new ByteArrayInputStream(data));
if(tmp.length > rtf.getDeCompressedSize()) {
this.decompressed = IOUtils.safelyAllocate(rtf.getDeCompressedSize(), MAX_RECORD_LENGTH);
System.arraycopy(tmp, 0, decompressed, 0, decompressed.length);
this.decompressed = IOUtils.safelyClone(tmp, 0, rtf.getDeCompressedSize(), MAX_RECORD_LENGTH);
} else {
this.decompressed = tmp;
}
// Turn the RTF data into a more useful string
this.data = StringUtil.getFromCompressedUnicode(decompressed, 0, decompressed.length);
}
/**
* Returns the original, compressed RTF
*/
public byte[] getRawData() {
return super.getData();
}
/**
* Returns the raw uncompressed RTF data
*/
public byte[] getData() {
return decompressed;
}
/**
* Returns the uncompressed RTF as a string
*/
public String getDataString() {
return data;
}
public String toString() {
return getProperty() + " " + data;
}

View File

@ -44,7 +44,7 @@ public final class HMEFDumper {
if(args.length < 1) {
throw new IllegalArgumentException("Filename must be given");
}
boolean truncatePropData = true;
for (String arg : args) {
if (arg.equalsIgnoreCase("--full")) {
@ -62,77 +62,77 @@ public final class HMEFDumper {
private InputStream inp;
private boolean truncatePropertyData;
public HMEFDumper(InputStream inp) throws IOException {
this.inp = inp;
// Check the signature matches
int sig = LittleEndian.readInt(inp);
if(sig != HMEFMessage.HEADER_SIGNATURE) {
throw new IllegalArgumentException(
"TNEF signature not detected in file, " +
"expected " + HMEFMessage.HEADER_SIGNATURE +
"expected " + HMEFMessage.HEADER_SIGNATURE +
" but got " + sig
);
}
// Skip over the File ID
LittleEndian.readUShort(inp);
}
public void setTruncatePropertyData(boolean truncate) {
truncatePropertyData = truncate;
}
private void dump() throws IOException {
int level;
int attachments = 0;
while(true) {
// Fetch the level
level = inp.read();
if(level == TNEFProperty.LEVEL_END_OF_FILE) {
break;
}
// Build the attribute
TNEFAttribute attr = TNEFAttribute.create(inp);
// Is it a new attachment?
if(level == TNEFProperty.LEVEL_ATTACHMENT &&
if(level == TNEFProperty.LEVEL_ATTACHMENT &&
attr.getProperty() == TNEFProperty.ID_ATTACHRENDERDATA) {
attachments++;
System.out.println();
System.out.println("Attachment # " + attachments);
System.out.println();
}
// Print the attribute into
System.out.println(
"Level " + level + " : Type " + attr.getType() +
" : ID " + attr.getProperty()
);
// Print the contents
String indent = " ";
if(attr instanceof TNEFStringAttribute) {
System.out.println(indent + indent + indent + ((TNEFStringAttribute)attr).getString());
}
if(attr instanceof TNEFDateAttribute) {
System.out.println(indent + indent + indent + ((TNEFDateAttribute)attr).getDate());
}
System.out.println(indent + "Data of length " + attr.getData().length);
if(attr.getData().length > 0) {
int len = attr.getData().length;
if(truncatePropertyData) {
len = Math.min( attr.getData().length, 48 );
}
int loops = len/16;
if(loops == 0) loops = 1;
for(int i=0; i<loops; i++) {
int thisLen = 16;
int offset = i*16;
@ -140,16 +140,15 @@ public final class HMEFDumper {
thisLen = len - offset;
}
byte[] data = IOUtils.safelyAllocate(thisLen, MAX_RECORD_LENGTH);
System.arraycopy(attr.getData(), offset, data, 0, thisLen);
byte[] data = IOUtils.safelyClone(attr.getData(), offset, thisLen, MAX_RECORD_LENGTH);
System.out.print(
indent + HexDump.dump(data, 0, 0)
);
}
}
System.out.println();
if(attr.getProperty() == TNEFProperty.ID_MAPIPROPERTIES ||
attr.getProperty() == TNEFProperty.ID_ATTACHMENT) {
List<MAPIAttribute> attrs = MAPIAttribute.create(attr);

View File

@ -69,8 +69,7 @@ public final class QuillContents extends HPBFPart {
int from = (int)LittleEndian.getUInt(data, offset+16);
int len = (int)LittleEndian.getUInt(data, offset+20);
byte[] bitData = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
System.arraycopy(data, from, bitData, 0, len);
byte[] bitData = IOUtils.safelyClone(data, from, len, MAX_RECORD_LENGTH);
// Create
if(bitType.equals("TEXT")) {

View File

@ -39,9 +39,7 @@ public abstract class Bitmap extends HSLFPictureData {
public byte[] getData(){
byte[] rawdata = getRawData();
int prefixLen = 16*getUIDInstanceCount()+1;
byte[] imgdata = IOUtils.safelyAllocate(rawdata.length-prefixLen, rawdata.length);
System.arraycopy(rawdata, prefixLen, imgdata, 0, imgdata.length);
return imgdata;
return IOUtils.safelyClone(rawdata, prefixLen, rawdata.length-prefixLen, rawdata.length);
}
@Override

View File

@ -62,9 +62,9 @@ public final class DIB extends Bitmap {
break;
default:
throw new IllegalArgumentException(signature+" is not a valid instance/signature value for DIB");
}
}
}
}
@Override
public byte[] getData(){
return addBMPHeader ( super.getData() );
@ -83,14 +83,14 @@ public final class DIB extends Bitmap {
int imageSize = LittleEndian.getInt(data, 0x22 - HEADER_SIZE);
int fileSize = data.length + HEADER_SIZE;
int offset = fileSize - imageSize;
// specifies the size, in bytes, of the bitmap file - must add the length of the header
LittleEndian.putInt(header, 2, fileSize);
LittleEndian.putInt(header, 2, fileSize);
// Reserved; set to zero
LittleEndian.putInt(header, 6, 0);
// the offset, i.e. starting address, of the byte where the bitmap data can be found
LittleEndian.putInt(header, 10, offset);
//DIB data is the header + dib bytes
byte[] dib = IOUtils.safelyAllocate(header.length + data.length, MAX_RECORD_LENGTH);
System.arraycopy(header, 0, dib, 0, header.length);
@ -102,8 +102,7 @@ public final class DIB extends Bitmap {
@Override
public void setData(byte[] data) throws IOException {
//cut off the bitmap file-header
byte[] dib = IOUtils.safelyAllocate(data.length-HEADER_SIZE, data.length);
System.arraycopy(data, HEADER_SIZE, dib, 0, dib.length);
byte[] dib = IOUtils.safelyClone(data, HEADER_SIZE, data.length-HEADER_SIZE, data.length);
super.setData(dib);
}
}

View File

@ -36,8 +36,8 @@ import org.apache.poi.util.Units;
*/
public final class PICT extends Metafile {
private static final POILogger LOG = POILogFactory.getLogger(PICT.class);
@Override
public byte[] getData(){
byte[] rawdata = getRawData();
@ -95,7 +95,7 @@ public final class PICT extends Metafile {
// skip the first 512 bytes - they are MAC specific crap
final int nOffset = ImageHeaderPICT.PICT_HEADER_OFFSET;
ImageHeaderPICT nHeader = new ImageHeaderPICT(data, nOffset);
Header header = new Header();
int wmfSize = data.length - nOffset;
header.setWmfSize(wmfSize);
@ -144,12 +144,12 @@ public final class PICT extends Metafile {
break;
default:
throw new IllegalArgumentException(signature+" is not a valid instance/signature value for PICT");
}
}
}
/*
* initialize a smaller piece of the array and use the System.arraycopy
* initialize a smaller piece of the array and use the System.arraycopy
* call to fill in the rest of the array in an expanding binary fashion
*/
private static void bytefill(byte[] array, byte value) {
@ -161,7 +161,7 @@ public final class PICT extends Metafile {
}
for (int i = 1; i < len; i += i) {
System.arraycopy(array, 0, array, i, ((len - i) < i) ? (len - i) : i);
System.arraycopy(array, 0, array, i, Math.min(len - i, i));
}
}
}

View File

@ -26,6 +26,7 @@ import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
@ -161,20 +162,18 @@ public final class PPTXMLDump {
public void dumpPictures(byte[] data, int padding) throws IOException {
int pos = 0;
while (pos < data.length) {
byte[] header = new byte[PICT_HEADER_SIZE];
if(data.length - pos < header.length) {
if(data.length - pos < PICT_HEADER_SIZE) {
// corrupt file, cannot read header
return;
}
System.arraycopy(data, pos, header, 0, header.length);
byte[] header = Arrays.copyOfRange(data, pos, pos + PICT_HEADER_SIZE);
int size = LittleEndian.getInt(header, 4) - 17;
if(size < 0) {
// corrupt file, negative image size
return;
}
byte[] pictdata = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
System.arraycopy(data, pos + PICT_HEADER_SIZE, pictdata, 0, pictdata.length);
byte[] pictdata = IOUtils.safelyClone(data, pos + PICT_HEADER_SIZE, size, MAX_RECORD_LENGTH);
pos += PICT_HEADER_SIZE + size;
padding++;

View File

@ -58,7 +58,7 @@ public final class SlideShowDumper {
private boolean ddfEscher;
/** Do we use our own built-in basic escher groker to understand the escher objects? */
private boolean basicEscher;
private PrintStream out;
/**
@ -213,8 +213,7 @@ public void walkTree(int depth, int startPos, int maxLen) throws IOException {
final String ind = (indent == 0) ? "%1$s" : "%1$"+indent+"s";
byte[] contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
System.arraycopy(docstream,pos,contents,0,len);
byte[] contents = IOUtils.safelyClone(docstream, pos, len, MAX_RECORD_LENGTH);
DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory();
EscherRecord record = erf.createRecord(contents,0);
@ -229,8 +228,8 @@ public void walkTree(int depth, int startPos, int maxLen) throws IOException {
String fmt = ind+"At position %2$d (%2$04x): type is %3$d (%3$04x), len is %4$d (%4$04x) (%5$d) - record claims %6$d";
out.println(String.format(Locale.ROOT, fmt, "", pos, atomType, atomLen, atomLen+8, recordLen));
// Check for corrupt / lying ones
if(recordLen != 8 && (recordLen != (atomLen+8))) {
out.println(String.format(Locale.ROOT, ind+"** Atom length of $2d ($3d) doesn't match record length of %4d", "", atomLen, atomLen+8, recordLen));

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
@ -39,8 +40,7 @@ public final class AnimationInfo extends RecordContainer {
*/
protected AnimationInfo(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);

View File

@ -21,6 +21,7 @@ import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -101,7 +102,7 @@ public final class AnimationInfoAtom extends RecordAtom {
/**
* record data
*/
private byte[] _recdata;
private final byte[] _recdata;
/**
* Constructs a brand new link related atom record.
@ -125,12 +126,10 @@ public final class AnimationInfoAtom extends RecordAtom {
*/
protected AnimationInfoAtom(byte[] source, int start, int len) {
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Grab the record data
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_recdata,0,len-8);
_recdata = IOUtils.safelyClone(source,start+8, len-8, MAX_RECORD_LENGTH);
}
/**

View File

@ -17,9 +17,11 @@
package org.apache.poi.hslf.record;
import org.apache.poi.util.LittleEndian;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
/**
* If we come across a record we know has children of (potential)
@ -44,8 +46,7 @@ public final class BinaryTagDataBlob extends PositionDependentRecordContainer
*/
protected BinaryTagDataBlob(byte[] source, int start, int len) {
// Just grab the header, not the whole contents
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
_type = LittleEndian.getUShort(_header,2);
// Find our children

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -86,12 +87,10 @@ public final class CString extends RecordAtom {
if(len < 8) { len = 8; }
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Grab the text
_text = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_text,0,len-8);
_text = IOUtils.safelyClone(source,start+8, len-8, MAX_RECORD_LENGTH);
}
/**
* Create an empty CString

View File

@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
@ -108,11 +109,10 @@ public final class ColorSchemeAtom extends RecordAtom {
}
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Grab the rgb values
backgroundColourRGB = LittleEndian.getInt(source,start+8+0);
backgroundColourRGB = LittleEndian.getInt(source, start+8);
textAndLinesColourRGB = LittleEndian.getInt(source,start+8+4);
shadowsColourRGB = LittleEndian.getInt(source,start+8+8);
titleTextColourRGB = LittleEndian.getInt(source,start+8+12);

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
@ -101,8 +102,7 @@ public final class Comment2000 extends RecordContainer {
*/
protected Comment2000(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = org.apache.poi.hslf.record.Record.findChildRecords(source,start+8,len-8);

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.function.Supplier;
@ -72,12 +73,10 @@ public final class Comment2000Atom extends RecordAtom
*/
protected Comment2000Atom(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the record data.
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_data,0,len-8);
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
}
/**

View File

@ -192,17 +192,12 @@ public class CurrentUserAtom
// Grab the unicode username, if stored
int start = 28+(int)usernameLen+4;
int len = 2*(int)usernameLen;
if(_contents.length >= start+len) {
byte[] textBytes = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
System.arraycopy(_contents,start,textBytes,0,len);
lastEditUser = StringUtil.getFromUnicodeLE(textBytes);
if(_contents.length >= start+2*usernameLen) {
lastEditUser = StringUtil.getFromUnicodeLE(_contents, start, (int)usernameLen);
} else {
// Fake from the 8 bit version
byte[] textBytes = IOUtils.safelyAllocate(usernameLen, MAX_RECORD_LENGTH);
System.arraycopy(_contents,28,textBytes,0,(int)usernameLen);
lastEditUser = StringUtil.getFromCompressedUnicode(textBytes,0,(int)usernameLen);
lastEditUser = StringUtil.getFromCompressedUnicode(_contents, 28, (int)usernameLen);
}
}

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -38,8 +39,7 @@ public final class DocInfoListContainer extends RecordContainer {
*/
protected DocInfoListContainer(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source,start,start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);

View File

@ -17,11 +17,12 @@
package org.apache.poi.hslf.record;
import org.apache.poi.util.POILogger;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import org.apache.poi.util.POILogger;
/**
* Master container for Document. There is one of these for every
@ -46,24 +47,24 @@ public final class Document extends PositionDependentRecordContainer
* Returns the DocumentAtom of this Document
*/
public DocumentAtom getDocumentAtom() { return documentAtom; }
/**
* Returns the Environment of this Notes, which lots of
* settings for the document in it
*/
public Environment getEnvironment() { return environment; }
/**
* Returns the PPDrawingGroup, which holds an Escher Structure
* that contains information on pictures in the slides.
*/
public PPDrawingGroup getPPDrawingGroup() { return ppDrawing; }
/**
* Returns the ExObjList, which holds the references to
* external objects used in the slides. This may be null, if
* there are no external references.
*
*
* @param create if true, create an ExObjList if it doesn't exist
*/
public ExObjList getExObjList(boolean create) {
@ -126,8 +127,7 @@ public final class Document extends PositionDependentRecordContainer
*/
/* package */ Document(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);

View File

@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -51,8 +52,7 @@ public final class DocumentEncryptionAtom extends PositionDependentRecordAtom {
*/
protected DocumentEncryptionAtom(byte[] source, int start, int len) {
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source,start,start+8);
ByteArrayInputStream bis = new ByteArrayInputStream(source, start+8, len-8);
try (LittleEndianInputStream leis = new LittleEndianInputStream(bis)) {
@ -67,10 +67,10 @@ public final class DocumentEncryptionAtom extends PositionDependentRecordAtom {
LittleEndian.putShort(_header, 0, (short)0x000F);
LittleEndian.putShort(_header, 2, (short)_type);
// record length not yet known ...
ei = new EncryptionInfo(EncryptionMode.cryptoAPI);
}
/**
* Initializes the encryption settings
*
@ -79,7 +79,7 @@ public final class DocumentEncryptionAtom extends PositionDependentRecordAtom {
public void initializeEncryptionInfo(int keyBits) {
ei = new EncryptionInfo(EncryptionMode.cryptoAPI, CipherAlgorithm.rc4, HashAlgorithm.sha1, keyBits, -1, null);
}
/**
* Return the length of the encryption key, in bits
*/
@ -100,8 +100,8 @@ public final class DocumentEncryptionAtom extends PositionDependentRecordAtom {
public EncryptionInfo getEncryptionInfo() {
return ei;
}
/**
* We are of type 12052
*/
@ -119,10 +119,10 @@ public final class DocumentEncryptionAtom extends PositionDependentRecordAtom {
bos.writeShort(ei.getVersionMajor());
bos.writeShort(ei.getVersionMinor());
bos.writeInt(ei.getEncryptionFlags());
((CryptoAPIEncryptionHeader)ei.getHeader()).write(bos);
((CryptoAPIEncryptionVerifier)ei.getVerifier()).write(bos);
// Header
LittleEndian.putInt(_header, 4, bos.getWriteIndex());
out.write(_header);

View File

@ -17,9 +17,11 @@
package org.apache.poi.hslf.record;
import org.apache.poi.util.LittleEndian;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
/**
* If we come across a record we know has children of (potential)
@ -44,8 +46,7 @@ public final class DummyPositionSensitiveRecordWithChildren extends PositionDepe
*/
protected DummyPositionSensitiveRecordWithChildren(byte[] source, int start, int len) {
// Just grab the header, not the whole contents
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source,start,start+8);
_type = LittleEndian.getUShort(_header,2);
// Find our children

View File

@ -17,9 +17,11 @@
package org.apache.poi.hslf.record;
import org.apache.poi.util.LittleEndian;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
/**
* If we come across a record we know has children of (potential)
@ -39,8 +41,7 @@ public final class DummyRecordWithChildren extends RecordContainer
*/
protected DummyRecordWithChildren(byte[] source, int start, int len) {
// Just grab the header, not the whole contents
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
_type = LittleEndian.getUShort(_header,2);
// Find our children

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
/**
* Environment, which contains lots of settings for the document.
@ -47,8 +48,7 @@ public final class Environment extends PositionDependentRecordContainer
*/
protected Environment(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -63,8 +64,7 @@ public final class ExControlAtom extends RecordAtom {
*/
protected ExControlAtom(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source, start, _header, 0, 8);
_header = Arrays.copyOfRange(source, start, start+8);
_id = LittleEndian.getInt(source, start + 8);
}

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
@ -49,8 +50,7 @@ public class ExEmbed extends RecordContainer {
*/
protected ExEmbed(final byte[] source, final int start, final int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);
@ -66,9 +66,9 @@ public class ExEmbed extends RecordContainer {
this();
_children[0] = this.embedAtom = embedAtom;
}
/**
* Create a new ExEmbed, with blank fields
*/
@ -163,7 +163,7 @@ public class ExEmbed extends RecordContainer {
/**
* Gets the OLE Programmatic Identifier.
*
*
* @return the OLE Programmatic Identifier.
*/
public String getProgId() {
@ -175,8 +175,8 @@ public class ExEmbed extends RecordContainer {
this.progId.setText(progId);
}
/**
* Gets the name that appears in the paste special dialog.
*
@ -190,7 +190,7 @@ public class ExEmbed extends RecordContainer {
this.clipboardName = safeCString(this.clipboardName, 0x3);
this.clipboardName.setText(clipboardName);
}
/**
* Returns the type (held as a little endian in bytes 3 and 4)
* that this class handles.
@ -213,7 +213,7 @@ public class ExEmbed extends RecordContainer {
public void writeOut(final OutputStream out) throws IOException {
writeOut(_header[0],_header[1],getRecordType(),_children,out);
}
private CString safeCString(CString oldStr, int optionsId) {
CString newStr = oldStr;
if (newStr == null) {
@ -233,7 +233,7 @@ public class ExEmbed extends RecordContainer {
if (!found) {
appendChildRecord(newStr);
}
return newStr;
}
}

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -94,12 +95,10 @@ public class ExEmbedAtom extends RecordAtom {
*/
protected ExEmbedAtom(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the record data.
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_data,0,len-8);
_data = IOUtils.safelyClone(source,start+8,len-8, MAX_RECORD_LENGTH);
// Must be at least 8 bytes long
if(_data.length < 8) {
@ -130,7 +129,7 @@ public class ExEmbedAtom extends RecordAtom {
public void setCantLockServerB(boolean cantBeLocked) {
_data[4] = (byte)(cantBeLocked ? 1 : 0);
}
/**
* Gets whether it is not required to send the dimensions to the embedded object.
*

View File

@ -18,12 +18,13 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
/**
* This class represents the data of a link in the document.
* This class represents the data of a link in the document.
* @author Nick Burch
*/
public class ExHyperlink extends RecordContainer {
@ -35,12 +36,12 @@ public class ExHyperlink extends RecordContainer {
private ExHyperlinkAtom linkAtom;
private CString linkDetailsA;
private CString linkDetailsB;
/**
/**
* Returns the ExHyperlinkAtom of this link
*/
*/
public ExHyperlinkAtom getExHyperlinkAtom() { return linkAtom; }
/**
* Returns the URL of the link.
*
@ -68,7 +69,7 @@ public class ExHyperlink extends RecordContainer {
linkDetailsB.setText(url);
}
}
public void setLinkOptions(int options) {
if(linkDetailsB != null) {
linkDetailsB.setOptions(options);
@ -80,7 +81,7 @@ public class ExHyperlink extends RecordContainer {
linkDetailsA.setText(title);
}
}
/**
* Get the link details (field A)
*/
@ -94,13 +95,12 @@ public class ExHyperlink extends RecordContainer {
return linkDetailsB == null ? null : linkDetailsB.getText();
}
/**
/**
* Set things up, and find our more interesting children
*/
protected ExHyperlink(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);
@ -111,7 +111,7 @@ public class ExHyperlink extends RecordContainer {
* Go through our child records, picking out the ones that are
* interesting, and saving those for use by the easy helper
* methods.
*/
*/
private void findInterestingChildren() {
// First child should be the ExHyperlinkAtom
@ -138,11 +138,11 @@ public class ExHyperlink extends RecordContainer {
public ExHyperlink() {
_header = new byte[8];
_children = new org.apache.poi.hslf.record.Record[3];
// Setup our header block
_header[0] = 0x0f; // We are a container record
LittleEndian.putShort(_header, 2, (short)_type);
// Setup our child records
CString csa = new CString();
CString csb = new CString();

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -70,12 +71,10 @@ public final class ExHyperlinkAtom extends RecordAtom {
*/
protected ExHyperlinkAtom(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the record data.
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_data,0,len-8);
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
// Must be at least 4 bytes long
if(_data.length < 4) {

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
@ -39,8 +40,7 @@ public class ExMCIMovie extends RecordContainer { // TODO - instantiable supercl
*/
protected ExMCIMovie(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source, start, _header, 0, 8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source, start + 8, len - 8);

View File

@ -21,6 +21,7 @@ import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -89,12 +90,10 @@ public final class ExMediaAtom extends RecordAtom
*/
protected ExMediaAtom(byte[] source, int start, int len) {
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Grab the record data
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_recdata,0,len-8);
_recdata = IOUtils.safelyClone(source,start+8, len-8, MAX_RECORD_LENGTH);
}
/**

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
@ -30,15 +31,15 @@ import org.apache.poi.util.LittleEndian;
public class ExObjList extends RecordContainer {
private byte[] _header;
private static final long _type = RecordTypes.ExObjList.typeID;
// Links to our more interesting children
private ExObjListAtom exObjListAtom;
/**
private ExObjListAtom exObjListAtom;
/**
* Returns the ExObjListAtom of this list
*/
*/
public ExObjListAtom getExObjListAtom() { return exObjListAtom; }
/**
* Returns all the ExHyperlinks
*/
@ -53,13 +54,12 @@ public class ExObjList extends RecordContainer {
return links.toArray(new ExHyperlink[0]);
}
/**
/**
* Set things up, and find our more interesting children
*/
protected ExObjList(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);
@ -70,7 +70,7 @@ public class ExObjList extends RecordContainer {
* Go through our child records, picking out the ones that are
* interesting, and saving those for use by the easy helper
* methods.
*/
*/
private void findInterestingChildren() {
// First child should be the atom
if(_children[0] instanceof ExObjListAtom) {
@ -79,18 +79,18 @@ public class ExObjList extends RecordContainer {
throw new IllegalStateException("First child record wasn't a ExObjListAtom, was of type " + _children[0].getRecordType());
}
}
/**
* Create a new ExObjList, with blank fields
*/
public ExObjList() {
_header = new byte[8];
_children = new org.apache.poi.hslf.record.Record[1];
// Setup our header block
_header[0] = 0x0f; // We are a container record
LittleEndian.putShort(_header, 2, (short)_type);
// Setup our child records
_children[0] = new ExObjListAtom();
findInterestingChildren();

View File

@ -14,12 +14,13 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -58,7 +59,7 @@ public class ExObjListAtom extends RecordAtom
LittleEndian.putShort(_header, 2, (short)getRecordType());
LittleEndian.putInt(_header, 4, _data.length);
// It is fine for the other values to be zero
}
@ -72,13 +73,11 @@ public class ExObjListAtom extends RecordAtom
*/
protected ExObjListAtom(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the record data.
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_data,0,len-8);
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
// Must be at least 4 bytes long
if(_data.length < 4) {
throw new IllegalArgumentException("The length of the data for a ExObjListAtom must be at least 4 bytes, but was only " + _data.length);
@ -101,7 +100,7 @@ public class ExObjListAtom extends RecordAtom
public void setObjectIDSeed(int seed) {
LittleEndian.putInt(_data,0,seed);
}
/**
* Gets the record type.
* @return the record type.

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -55,17 +56,14 @@ public final class ExObjRefAtom extends RecordAtom {
/**
* Build an instance of <code>ExObjRefAtom</code> from on-disk data
*
*
* @param source the source data as a byte array.
* @param start the start offset into the byte array.
* @param len the length of the slice in the byte array.
*/
protected ExObjRefAtom(byte[] source, int start, int len) {
_header = new byte[8];
int offset = start;
System.arraycopy(source,start,_header,0,8);
offset += _header.length;
exObjIdRef = (int)LittleEndian.getUInt(source, offset);
_header = Arrays.copyOfRange(source, start, start+8);
exObjIdRef = (int)LittleEndian.getUInt(source, start+8);
}
/**

View File

@ -22,6 +22,7 @@ import static org.apache.poi.util.GenericRecordUtil.safeEnum;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -187,12 +188,10 @@ public class ExOleObjAtom extends RecordAtom {
*/
protected ExOleObjAtom(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the record data.
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_data,0,len-8);
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
// Must be at least 24 bytes long
if(_data.length < 24) {
@ -258,7 +257,7 @@ public class ExOleObjAtom extends RecordAtom {
/**
* Gets the type of OLE object.
*
*
* @return the sub-type, one of the {@code SUBTYPE_*} constants.
*/
public int getSubType() {
@ -303,7 +302,7 @@ public class ExOleObjAtom extends RecordAtom {
// Even though this is a mere boolean, KOffice's code says it's an int.
return LittleEndian.getInt(_data, 20) != 0;
}
/**
* Gets misc options (the last four bytes in the atom).
*

View File

@ -22,6 +22,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
import java.util.zip.DeflaterOutputStream;
@ -51,7 +52,7 @@ public class ExOleObjStg extends PositionDependentRecordAtom implements PersistR
* Record data.
*/
private byte[] _data;
/**
* Constructs a new empty storage container.
*/
@ -74,12 +75,10 @@ public class ExOleObjStg extends PositionDependentRecordAtom implements PersistR
*/
protected ExOleObjStg(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the record data.
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_data,0,len-8);
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
}
public boolean isCompressed() {
@ -155,7 +154,7 @@ public class ExOleObjStg extends PositionDependentRecordAtom implements PersistR
public int getRecordInstance() {
return (LittleEndian.getUShort(_header, 0) >>> 4);
}
/**
* Write the contents of the record back, so it can be written
* to disk.

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
@ -41,8 +42,7 @@ public final class ExVideoContainer extends RecordContainer {
*/
protected ExVideoContainer(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);

View File

@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -47,8 +48,7 @@ public final class FontCollection extends RecordContainer {
private byte[] _header;
/* package */ FontCollection(byte[] source, int start, int len) {
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
_children = Record.findChildRecords(source,start+8,len-8);
@ -86,10 +86,10 @@ public final class FontCollection extends RecordContainer {
/**
* Add font with the given FontInfo configuration to the font collection.
* The returned FontInfo contains the HSLF specific details and the collection
* The returned FontInfo contains the HSLF specific details and the collection
* uniquely contains fonts based on their typeface, i.e. calling the method with FontInfo
* objects having the same name results in the same HSLFFontInfo reference.
*
*
* @param fontInfo the FontInfo configuration, can be a instance of {@link HSLFFontInfo},
* {@link HSLFFontInfoPredefined} or a custom implementation
* @return the register HSLFFontInfo object
@ -168,9 +168,9 @@ public final class FontCollection extends RecordContainer {
/**
* Lookup a FontInfo object by its typeface
*
*
* @param typeface the full font name
*
*
* @return the HSLFFontInfo for the given name or {@code null} if not found
*/
public HSLFFontInfo getFontInfo(String typeface) {
@ -195,9 +195,9 @@ public final class FontCollection extends RecordContainer {
/**
* Lookup a FontInfo object by its internal font index
*
*
* @param index the internal font index
*
*
* @return the HSLFFontInfo for the given index or {@code null} if not found
*/
public HSLFFontInfo getFontInfo(int index) {
@ -208,7 +208,7 @@ public final class FontCollection extends RecordContainer {
}
return null;
}
/**
* @return the number of registered fonts
*/

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -63,12 +64,10 @@ public class FontEmbeddedData extends RecordAtom implements FontFacet {
*/
/* package */ FontEmbeddedData(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the record data.
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_data,0,len-8);
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
// Must be at least 4 bytes long
if(_data.length < 4) {

View File

@ -62,7 +62,7 @@ public final class FontEntityAtom extends RecordAtom {
/**
* record header
*/
private final byte[] _header = new byte[8];
private final byte[] _header;
/**
* record data
@ -74,11 +74,10 @@ public final class FontEntityAtom extends RecordAtom {
*/
/* package */ FontEntityAtom(byte[] source, int start, int len) {
// Get the header
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Grab the record data
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_recdata,0,len-8);
_recdata = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
}
/**
@ -86,6 +85,7 @@ public final class FontEntityAtom extends RecordAtom {
*/
public FontEntityAtom() {
_recdata = new byte[68];
_header = new byte[8];
LittleEndian.putShort(_header, 2, (short)getRecordType());
LittleEndian.putInt(_header, 4, _recdata.length);

View File

@ -68,8 +68,7 @@ public class HSLFEscherClientDataRecord extends EscherClientDataRecord {
@Override
public int fillFields(byte[] data, int offset, EscherRecordFactory recordFactory) {
int bytesRemaining = readHeader( data, offset );
byte[] remainingData = IOUtils.safelyAllocate(bytesRemaining, MAX_RECORD_LENGTH);
System.arraycopy(data, offset+8, remainingData, 0, bytesRemaining);
byte[] remainingData = IOUtils.safelyClone(data, offset+8, bytesRemaining, MAX_RECORD_LENGTH);
setRemainingData(remainingData);
return bytesRemaining + 8;
}

View File

@ -22,6 +22,7 @@ import static org.apache.poi.util.GenericRecordUtil.safeEnum;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -142,12 +143,10 @@ public final class HeadersFootersAtom extends RecordAtom {
*/
protected HeadersFootersAtom(byte[] source, int start, int len) {
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Grab the record data
_recdata = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_recdata,0,len-8);
_recdata = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
}
/**

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
@ -59,8 +60,7 @@ public final class HeadersFootersContainer extends RecordContainer {
protected HeadersFootersContainer(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
_children = Record.findChildRecords(source,start+8,len-8);
findInterestingChildren();

View File

@ -18,6 +18,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
@ -31,22 +32,21 @@ import org.apache.poi.util.POILogger;
public class InteractiveInfo extends RecordContainer {
private byte[] _header;
private static final long _type = RecordTypes.InteractiveInfo.typeID;
// Links to our more interesting children
private InteractiveInfoAtom infoAtom;
/**
/**
* Returns the InteractiveInfoAtom of this InteractiveInfo
*/
*/
public InteractiveInfoAtom getInteractiveInfoAtom() { return infoAtom; }
/**
/**
* Set things up, and find our more interesting children
*/
protected InteractiveInfo(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);
@ -57,7 +57,7 @@ public class InteractiveInfo extends RecordContainer {
* Go through our child records, picking out the ones that are
* interesting, and saving those for use by the easy helper
* methods.
*/
*/
private void findInterestingChildren() {
// First child should be the InteractiveInfoAtom
if (_children == null || _children.length == 0 || !(_children[0] instanceof InteractiveInfoAtom)) {
@ -67,18 +67,18 @@ public class InteractiveInfo extends RecordContainer {
infoAtom = (InteractiveInfoAtom)_children[0];
}
/**
* Create a new InteractiveInfo, with blank fields
*/
public InteractiveInfo() {
_header = new byte[8];
_children = new org.apache.poi.hslf.record.Record[1];
// Setup our header block
_header[0] = 0x0f; // We are a container record
LittleEndian.putShort(_header, 2, (short)_type);
// Setup our child records
infoAtom = new InteractiveInfoAtom();
_children[0] = infoAtom;

View File

@ -22,6 +22,7 @@ import static org.apache.poi.util.GenericRecordUtil.safeEnum;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -153,12 +154,10 @@ public class InteractiveInfoAtom extends RecordAtom {
*/
protected InteractiveInfoAtom(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the record data.
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_data,0,len-8);
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
// Must be at least 16 bytes long
if(_data.length < 16) {

View File

@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Master slide
@ -57,8 +58,7 @@ public final class MainMaster extends SheetContainer {
*/
protected MainMaster(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);
@ -66,19 +66,19 @@ public final class MainMaster extends SheetContainer {
ArrayList<TxMasterStyleAtom> tx = new ArrayList<>();
ArrayList<ColorSchemeAtom> clr = new ArrayList<>();
// Find the interesting ones in there
for(int i=0; i<_children.length; i++) {
if(_children[i] instanceof SlideAtom) {
slideAtom = (SlideAtom)_children[i];
} else if(_children[i] instanceof PPDrawing) {
ppDrawing = (PPDrawing)_children[i];
} else if(_children[i] instanceof TxMasterStyleAtom) {
tx.add( (TxMasterStyleAtom)_children[i] );
} else if(_children[i] instanceof ColorSchemeAtom) {
clr.add( (ColorSchemeAtom)_children[i] );
for (Record child : _children) {
if (child instanceof SlideAtom) {
slideAtom = (SlideAtom) child;
} else if (child instanceof PPDrawing) {
ppDrawing = (PPDrawing) child;
} else if (child instanceof TxMasterStyleAtom) {
tx.add((TxMasterStyleAtom) child);
} else if (child instanceof ColorSchemeAtom) {
clr.add((ColorSchemeAtom) child);
}
if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) {
_colorScheme = (ColorSchemeAtom)_children[i];
if (ppDrawing != null && child instanceof ColorSchemeAtom) {
_colorScheme = (ColorSchemeAtom) child;
}
}

View File

@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -76,12 +77,10 @@ public final class MasterTextPropAtom extends RecordAtom {
*/
protected MasterTextPropAtom(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the record data.
_data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_data,0,len-8);
_data = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
try {
read();

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
/**
* Master container for Notes. There is one of these for every page of
@ -53,23 +54,22 @@ public final class Notes extends SheetContainer
*/
protected Notes(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);
// Find the interesting ones in there
for(int i=0; i<_children.length; i++) {
if(_children[i] instanceof NotesAtom) {
notesAtom = (NotesAtom)_children[i];
for (Record child : _children) {
if (child instanceof NotesAtom) {
notesAtom = (NotesAtom) child;
}
if(_children[i] instanceof PPDrawing) {
ppDrawing = (PPDrawing)_children[i];
if (child instanceof PPDrawing) {
ppDrawing = (PPDrawing) child;
}
if (ppDrawing != null && child instanceof ColorSchemeAtom) {
_colorScheme = (ColorSchemeAtom) child;
}
if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) {
_colorScheme = (ColorSchemeAtom)_children[i];
}
}
}

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -70,33 +71,19 @@ public final class NotesAtom extends RecordAtom
if(len < 8) { len = 8; }
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the slide ID
slideID = LittleEndian.getInt(source,start+8);
// Grok the flags, stored as bits
int flags = LittleEndian.getUShort(source,start+12);
if((flags&4) == 4) {
followMasterBackground = true;
} else {
followMasterBackground = false;
}
if((flags&2) == 2) {
followMasterScheme = true;
} else {
followMasterScheme = false;
}
if((flags&1) == 1) {
followMasterObjects = true;
} else {
followMasterObjects = false;
}
followMasterBackground = (flags & 4) == 4;
followMasterScheme = (flags & 2) == 2;
followMasterObjects = (flags & 1) == 1;
// There might be 2 more bytes, which are a reserved field
reserved = IOUtils.safelyAllocate(len-14, MAX_RECORD_LENGTH);
System.arraycopy(source,start+14,reserved,0,reserved.length);
reserved = IOUtils.safelyClone(source, start+14, len-14, MAX_RECORD_LENGTH);
}
/**

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -28,7 +29,7 @@ import org.apache.poi.util.LittleEndian;
/**
* OEPlaceholderAtom (3011).<p>
*
*
* An atom record that specifies whether a shape is a placeholder shape.
*
* @see Placeholder
@ -77,10 +78,8 @@ public final class OEPlaceholderAtom extends RecordAtom{
* Build an instance of {@code OEPlaceholderAtom} from on-disk data
*/
protected OEPlaceholderAtom(byte[] source, int start, int len) {
_header = new byte[8];
int offset = start;
System.arraycopy(source,start,_header,0,8);
offset += _header.length;
_header = Arrays.copyOfRange(source, start, start+8);
int offset = start+8;
placementId = LittleEndian.getInt(source, offset); offset += 4;
placeholderId = LittleEndian.getUByte(source, offset); offset++;
@ -96,7 +95,7 @@ public final class OEPlaceholderAtom extends RecordAtom{
/**
* Returns the placement Id.<p>
*
*
* The placement Id is a number assigned to the placeholder. It goes from -1 to the number of placeholders.
* It SHOULD be unique among all PlacholderAtom records contained in the corresponding slide.
* The value 0xFFFFFFFF specifies that the corresponding shape is not a placeholder shape.

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -55,8 +56,7 @@ public final class OutlineTextRefAtom extends RecordAtom {
*/
protected OutlineTextRefAtom(byte[] source, int start, int len) {
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Grab the record data
_index = LittleEndian.getInt(source, start+8);

View File

@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -114,15 +115,13 @@ public final class PPDrawing extends RecordAtom implements Iterable<EscherRecord
*/
PPDrawing(byte[] source, int start, int len) {
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the type
_type = LittleEndian.getUShort(_header,2);
// Get the contents for now
final byte[] contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
System.arraycopy(source,start,contents,0,len);
final byte[] contents = IOUtils.safelyClone(source, start, len, MAX_RECORD_LENGTH);
// Build up a tree of Escher records contained within
final DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory();
@ -342,7 +341,7 @@ public final class PPDrawing extends RecordAtom implements Iterable<EscherRecord
spContainer.addChildRecord(opt);
dgContainer.addChildRecord(spContainer);
childRecords.add(dgContainer);
}
@ -364,7 +363,7 @@ public final class PPDrawing extends RecordAtom implements Iterable<EscherRecord
public EscherContainerRecord getDgContainer() {
return (EscherContainerRecord)firstEscherRecord(this, EscherRecordTypes.DG_CONTAINER).orElse(null);
}
/**
* Return EscherDgRecord which keeps track of the number of shapes and shapeId in this drawing group
*

View File

@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -50,12 +51,10 @@ public final class PPDrawingGroup extends RecordAtom {
protected PPDrawingGroup(byte[] source, int start, int len) {
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the contents for now
byte[] contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
System.arraycopy(source,start,contents,0,len);
byte[] contents = IOUtils.safelyClone(source, start, len, MAX_RECORD_LENGTH);
DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory();
EscherRecord child = erf.createRecord(contents, 0);

View File

@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ -65,7 +66,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
private static final BitField persistIdFld = BitFieldFactory.getInstance(0X000FFFFF);
private static final BitField cntPersistFld = BitFieldFactory.getInstance(0XFFF00000);
/**
* Return the value we were given at creation, be it 6001 or 6002
*/
@ -93,7 +94,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
public Map<Integer,Integer> getSlideLocationsLookup() {
return Collections.unmodifiableMap(_slideLocations);
}
/**
* Create a new holder for a PersistPtr record
*/
@ -103,8 +104,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
if(len < 8) { len = 8; }
// Treat as an atom, grab and hold everything
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
_type = LittleEndian.getUShort(_header,2);
// Try to make sense of the data part:
@ -115,8 +115,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
// count * 32 bit offsets
// Repeat as many times as you have data
_slideLocations = new HashMap<>();
_ptrData = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
System.arraycopy(source,start+8,_ptrData,0,_ptrData.length);
_ptrData = IOUtils.safelyClone(source, start+8, len-8, MAX_RECORD_LENGTH);
int pos = 0;
while(pos < _ptrData.length) {
@ -127,7 +126,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
// Remaining 12 bits = offset count
int offset_no = persistIdFld.getValue(info);
int offset_count = cntPersistFld.getValue(info);
// Wind on by the 4 byte info header
pos += 4;
@ -145,13 +144,13 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
/**
* remove all slide references
*
*
* Convenience method provided, for easier reviewing of invocations
*/
public void clear() {
_slideLocations.clear();
}
/**
* Adds a new slide, notes or similar, to be looked up by this.
*/
@ -187,7 +186,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
private void normalizePersistDirectory() {
TreeMap<Integer,Integer> orderedSlideLocations = new TreeMap<>(_slideLocations);
@SuppressWarnings("resource")
BufAccessBAOS bos = new BufAccessBAOS(); // NOSONAR
byte[] intbuf = new byte[4];
@ -200,7 +199,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
// Building the info block
// First 20 bits = offset number = slide ID (persistIdFld, i.e. first slide ID of a continuous group)
// Remaining 12 bits = offset count = 1 (cntPersistFld, i.e. continuous entries in a group)
if (lastSlideId+1 == nextSlideId) {
// use existing PersistDirectoryEntry, need to increase entry count
assert(lastPersistEntry != -1);
@ -225,14 +224,14 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
throw new HSLFException(e);
}
}
// Save the new ptr data
_ptrData = bos.toByteArray();
// Update the atom header
LittleEndian.putInt(_header,4,bos.size());
}
/**
* Write the contents of the record back, so it can be written
* to disk
@ -243,7 +242,7 @@ public final class PersistPtrHolder extends PositionDependentRecordAtom
out.write(_header);
out.write(_ptrData);
}
private static class BufAccessBAOS extends ByteArrayOutputStream {
public byte[] getBuf() {
return buf;

View File

@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -76,8 +77,7 @@ public abstract class RecordContainer extends Record
*/
private int appendChild(Record newChild) {
// Copy over, and pop the child in at the end
Record[] nc = new org.apache.poi.hslf.record.Record[(_children.length + 1)];
System.arraycopy(_children, 0, nc, 0, _children.length);
Record[] nc = Arrays.copyOf(_children, _children.length+1, org.apache.poi.hslf.record.Record[].class);
// Switch the arrays
nc[_children.length] = newChild;
_children = nc;

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -55,7 +56,7 @@ public final class RoundTripHFPlaceholder12 extends RecordAtom {
LittleEndian.putInt(_header, 4, 8);
_placeholderId = 0;
}
/**
* Constructs the comment atom record from its source data.
*
@ -65,8 +66,7 @@ public final class RoundTripHFPlaceholder12 extends RecordAtom {
*/
protected RoundTripHFPlaceholder12(byte[] source, int start, int len) {
// Get the header.
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Get the record data.
_placeholderId = source[start+8];

View File

@ -21,6 +21,7 @@ import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -31,7 +32,7 @@ import org.apache.poi.util.LittleEndianConsts;
/**
* A SlideShowSlideInfo Atom (type 1017).<br>
* <br>
*
*
* An atom record that specifies which transition effects to perform
* during a slide show, and how to advance to the next presentation slide.<br>
* <br>
@ -70,30 +71,30 @@ public class SSSlideInfoAtom extends RecordAtom {
* manually advanced by the user during the slide show.
*/
public static final int MANUAL_ADVANCE_BIT = 1 << 0;
/**
* A bit that specifies whether the corresponding slide is
* A bit that specifies whether the corresponding slide is
* hidden and is not displayed during the slide show.
*/
public static final int HIDDEN_BIT = 1 << 2;
/**
* A bit that specifies whether to play the sound specified by soundIfRef.
*/
public static final int SOUND_BIT = 1 << 4;
/**
* A bit that specifies whether the sound specified by soundIdRef is
* looped continuously when playing until the next sound plays.
*/
public static final int LOOP_SOUND_BIT = 1 << 6;
/**
* A bit that specifies whether to stop any currently playing
* A bit that specifies whether to stop any currently playing
* sound when the transition starts.
*/
public static final int STOP_SOUND_BIT = 1 << 8;
/**
* A bit that specifies whether the slide will automatically
* advance after slideTime milliseconds during the slide show.
@ -102,10 +103,10 @@ public class SSSlideInfoAtom extends RecordAtom {
/**
* A bit that specifies whether to display the cursor during
* the slide show.
* the slide show.
*/
public static final int CURSOR_VISIBLE_BIT = 1 << 12;
// public static int RESERVED1_BIT = 1 << 1;
// public static int RESERVED2_BIT = 1 << 3;
// public static int RESERVED3_BIT = 1 << 5;
@ -144,9 +145,9 @@ public class SSSlideInfoAtom extends RecordAtom {
* less than or equal to 86399000. It MUST be ignored unless AUTO_ADVANCE_BIT is TRUE.
*/
private int _slideTime;
/**
* A SoundIdRef that specifies which sound to play when the transition starts.
* A SoundIdRef that specifies which sound to play when the transition starts.
*/
private int _soundIdRef;
@ -155,23 +156,23 @@ public class SSSlideInfoAtom extends RecordAtom {
* there are further restriction and specification of this field.
*/
private short _effectDirection; // byte
/**
* A byte that specifies which transition is used when transitioning to the
* next presentation slide during a slide show. Exact rendering of any transition is
* next presentation slide during a slide show. Exact rendering of any transition is
* determined by the rendering application. As such, the same transition can have
* many variations depending on the implementation.
*/
private short _effectType; // byte
/**
* Various flags - see bitmask for more details
*/
private short _effectTransitionFlags;
/**
* A byte value that specifies how long the transition takes to run.
* (0x00 = 0.75 seconds, 0x01 = 0.5 seconds, 0x02 = 0.25 seconds)
* (0x00 = 0.75 seconds, 0x01 = 0.5 seconds, 0x02 = 0.25 seconds)
*/
private short _speed; // byte
private byte[] _unused; // 3-byte
@ -184,18 +185,18 @@ public class SSSlideInfoAtom extends RecordAtom {
LittleEndian.putShort(_header, 6, (short)0);
_unused = new byte[3];
}
public SSSlideInfoAtom(byte[] source, int offset, int len) {
int ofs = offset;
// Sanity Checking
if(len != 24) len = 24;
assert(source.length >= offset+len);
// Get the header
_header = LittleEndian.getByteArray(source,ofs,8);
_header = Arrays.copyOfRange(source, ofs, ofs+8);
ofs += _header.length;
assert(LittleEndian.getShort(_header, 0) == 0);
assert(LittleEndian.getShort(_header, 2) == RecordTypes.SSSlideInfoAtom.typeID);
assert(LittleEndian.getShort(_header, 4) == 0x10);
@ -214,7 +215,7 @@ public class SSSlideInfoAtom extends RecordAtom {
ofs += LittleEndianConsts.SHORT_SIZE;
_speed = LittleEndian.getUByte(source, ofs);
ofs += LittleEndianConsts.BYTE_SIZE;
_unused = LittleEndian.getByteArray(source,ofs,3);
_unused = Arrays.copyOfRange(source,ofs,ofs+3);
}
/**
@ -232,7 +233,7 @@ public class SSSlideInfoAtom extends RecordAtom {
out.write(byteBuf);
LittleEndian.putUByte(byteBuf, 0, _effectType);
out.write(byteBuf);
writeLittleEndian(_effectTransitionFlags, out);
LittleEndian.putUByte(byteBuf, 0, _speed);
out.write(byteBuf);
@ -240,7 +241,7 @@ public class SSSlideInfoAtom extends RecordAtom {
assert(_unused.length == 3);
out.write(_unused);
}
/**
* We are of type 1017
*/
@ -303,7 +304,7 @@ public class SSSlideInfoAtom extends RecordAtom {
public boolean getEffectTransitionFlagByBit(int bitmask) {
return ((_effectTransitionFlags & bitmask) != 0);
}
public short getSpeed() {
return _speed;
}

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.LittleEndian;
@ -56,24 +57,22 @@ public final class Slide extends SheetContainer
*/
protected Slide(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);
// Find the interesting ones in there
for(int i=0; i<_children.length; i++) {
if(_children[i] instanceof SlideAtom) {
slideAtom = (SlideAtom)_children[i];
}
else if(_children[i] instanceof PPDrawing) {
ppDrawing = (PPDrawing)_children[i];
for (Record child : _children) {
if (child instanceof SlideAtom) {
slideAtom = (SlideAtom) child;
} else if (child instanceof PPDrawing) {
ppDrawing = (PPDrawing) child;
}
if(ppDrawing != null && _children[i] instanceof ColorSchemeAtom) {
_colorScheme = (ColorSchemeAtom)_children[i];
}
if (ppDrawing != null && child instanceof ColorSchemeAtom) {
_colorScheme = (ColorSchemeAtom) child;
}
}
}

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -83,12 +84,10 @@ public final class SlideAtom extends RecordAtom {
if(len < 30) { len = 30; }
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Grab the 12 bytes that is "SSlideLayoutAtom"
byte[] SSlideLayoutAtomData = new byte[12];
System.arraycopy(source,start+8,SSlideLayoutAtomData,0,12);
byte[] SSlideLayoutAtomData = Arrays.copyOfRange(source,start+8, start+12+8);
// Use them to build up the SSlideLayoutAtom
layoutAtom = new SlideAtomLayout(SSlideLayoutAtomData);
@ -98,26 +97,13 @@ public final class SlideAtom extends RecordAtom {
// Grok the flags, stored as bits
int flags = LittleEndian.getUShort(source,start+20+8);
if((flags&4) == 4) {
followMasterBackground = true;
} else {
followMasterBackground = false;
}
if((flags&2) == 2) {
followMasterScheme = true;
} else {
followMasterScheme = false;
}
if((flags&1) == 1) {
followMasterObjects = true;
} else {
followMasterObjects = false;
}
followMasterBackground = (flags & 4) == 4;
followMasterScheme = (flags & 2) == 2;
followMasterObjects = (flags & 1) == 1;
// If there's any other bits of data, keep them about
// 8 bytes header + 20 bytes to flags + 2 bytes flags = 30 bytes
reserved = IOUtils.safelyAllocate(len-30, MAX_RECORD_LENGTH);
System.arraycopy(source,start+30,reserved,0,reserved.length);
reserved = IOUtils.safelyClone(source,start+30, len-30, MAX_RECORD_LENGTH);
}
/**

View File

@ -19,6 +19,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -32,7 +33,7 @@ import org.apache.poi.util.LittleEndian;
* Holds the geometry of the Slide, and the ID of the placeholders on the slide.
* Embedded inside a SlideAtom is a SlideAtomLayout, without the usual record header.
* Since it's a fixed size and tied to the SlideAtom, we'll hold it here.<p>
*
*
* This might eventually merged with the XSLF counterpart
*/
@Internal
@ -82,7 +83,7 @@ public class SlideAtomLayout implements GenericRecord {
SlideLayoutType(int nativeId) {
this.nativeId = nativeId;
}
public int getNativeId() {
return nativeId;
}
@ -117,8 +118,7 @@ public class SlideAtomLayout implements GenericRecord {
// Grab out our data
geometry = SlideLayoutType.forNativeID(LittleEndian.getInt(data,0));
placeholderIDs = new byte[8];
System.arraycopy(data,4,placeholderIDs,0,8);
placeholderIDs = Arrays.copyOfRange(data,4, 4+8);
}
/**

View File

@ -20,6 +20,7 @@ package org.apache.poi.hslf.record;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.poi.util.LittleEndian;
@ -74,8 +75,7 @@ public final class SlideListWithText extends RecordContainer {
*/
protected SlideListWithText(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);
@ -96,8 +96,7 @@ public final class SlideListWithText extends RecordContainer {
// Create a SlideAtomsSets, not caring if they're empty
//if(emptySet) { continue; }
org.apache.poi.hslf.record.Record[] spaChildren = new org.apache.poi.hslf.record.Record[clen];
System.arraycopy(_children,i+1,spaChildren,0,clen);
org.apache.poi.hslf.record.Record[] spaChildren = Arrays.copyOfRange(_children,i+1, i+1+clen, org.apache.poi.hslf.record.Record[].class);
SlideAtomsSet set = new SlideAtomsSet((SlidePersistAtom)_children[i],spaChildren);
sets.add(set);

View File

@ -21,6 +21,7 @@ import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Supplier;
@ -44,7 +45,7 @@ public final class SlidePersistAtom extends RecordAtom {
private static final String[] FLAGS_NAMES = { "HAS_SHAPES_OTHER_THAN_PLACEHOLDERS" };
private final byte[] _header = new byte[8];
private final byte[] _header;
/** Slide reference ID. Should correspond to the PersistPtr "sheet ID" of the matching slide/notes record */
private int refID;
@ -91,7 +92,7 @@ public final class SlidePersistAtom extends RecordAtom {
if(len < 8) { len = 8; }
// Get the header
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Grab the reference ID
refID = LittleEndian.getInt(source,start+8);
@ -107,14 +108,14 @@ public final class SlidePersistAtom extends RecordAtom {
// Finally you have typically 4 or 8 bytes of reserved fields,
// all zero running from 24 bytes in to the end
reservedFields = IOUtils.safelyAllocate(len-24, MAX_RECORD_LENGTH);
System.arraycopy(source,start+24,reservedFields,0,reservedFields.length);
reservedFields = IOUtils.safelyClone(source,start+24, len-24, MAX_RECORD_LENGTH);
}
/**
* Create a new SlidePersistAtom, for use with a new Slide
*/
public SlidePersistAtom() {
_header = new byte[8];
LittleEndian.putUShort(_header, 0, 0);
LittleEndian.putUShort(_header, 2, (int)_type);
LittleEndian.putInt(_header, 4, 20);

View File

@ -17,10 +17,11 @@
package org.apache.poi.hslf.record;
import org.apache.poi.util.POILogger;
import java.io.OutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import org.apache.poi.util.POILogger;
/**
* A container holding information about a sound. It contains:
@ -55,8 +56,7 @@ public final class Sound extends RecordContainer {
*/
protected Sound(byte[] source, int start, int len) {
// Grab the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
_header = Arrays.copyOfRange(source, start, start+8);
// Find our children
_children = Record.findChildRecords(source,start+8,len-8);

Some files were not shown because too many files have changed in this diff Show More