mirror of https://github.com/apache/poi.git
Bug 56880 - switch exception to logged warning that non-extended pascal strings are not supported. Full fix would add parsing for these strings.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1728547 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d1e2c186ec
commit
991c5d0a00
|
@ -1,249 +1,258 @@
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
this work for additional information regarding copyright ownership.
|
this work for additional information regarding copyright ownership.
|
||||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
(the "License"); you may not use this file except in compliance with
|
(the "License"); you may not use this file except in compliance with
|
||||||
the License. You may obtain a copy of the License at
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.hwpf.model;
|
package org.apache.poi.hwpf.model;
|
||||||
|
|
||||||
import org.apache.poi.util.LittleEndian;
|
import java.util.Arrays;
|
||||||
import org.apache.poi.util.StringUtil;
|
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
import java.util.Arrays;
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
/**
|
import org.apache.poi.util.StringUtil;
|
||||||
* The STTB is a string table that is made up of a header that is followed by an
|
|
||||||
* array of elements. The cData value specifies the number of elements that are
|
/**
|
||||||
* contained in the array.
|
* The STTB is a string table that is made up of a header that is followed by an
|
||||||
* <p>
|
* array of elements. The cData value specifies the number of elements that are
|
||||||
* Class and fields descriptions are quoted from [MS-DOC] -- v20121003 Word
|
* contained in the array.
|
||||||
* (.doc) Binary File Format; Copyright (c) 2012 Microsoft Corporation; Release:
|
* <p>
|
||||||
* October 8, 2012
|
* Class and fields descriptions are quoted from [MS-DOC] -- v20121003 Word
|
||||||
* <p>
|
* (.doc) Binary File Format; Copyright (c) 2012 Microsoft Corporation; Release:
|
||||||
* This class is internal. It content or properties may change without notice
|
* October 8, 2012
|
||||||
* due to changes in our knowledge of internal Microsoft Word binary structures.
|
* <p>
|
||||||
*
|
* This class is internal. It content or properties may change without notice
|
||||||
* @author Sergey Vladimirov; according to [MS-DOC] -- v20121003 Word (.doc)
|
* due to changes in our knowledge of internal Microsoft Word binary structures.
|
||||||
* Binary File Format; Copyright (c) 2012 Microsoft Corporation;
|
*
|
||||||
* Release: October 8, 2012
|
* @author Sergey Vladimirov; according to [MS-DOC] -- v20121003 Word (.doc)
|
||||||
*/
|
* Binary File Format; Copyright (c) 2012 Microsoft Corporation;
|
||||||
public class Sttb
|
* Release: October 8, 2012
|
||||||
{
|
*/
|
||||||
|
public class Sttb
|
||||||
private int _cbExtra;
|
{
|
||||||
|
|
||||||
private final int _cDataLength;
|
private int _cbExtra;
|
||||||
|
|
||||||
private String[] _data;
|
private final int _cDataLength;
|
||||||
|
|
||||||
private byte[][] _extraData;
|
private String[] _data;
|
||||||
|
|
||||||
private final boolean _fExtend = true;
|
private byte[][] _extraData;
|
||||||
|
|
||||||
public Sttb( byte[] buffer, int startOffset )
|
private final boolean _fExtend = true;
|
||||||
{
|
|
||||||
this( 2, buffer, startOffset );
|
public Sttb( byte[] buffer, int startOffset )
|
||||||
}
|
{
|
||||||
|
this( 2, buffer, startOffset );
|
||||||
public Sttb( int cDataLength, byte[] buffer, int startOffset )
|
}
|
||||||
{
|
|
||||||
this._cDataLength = cDataLength;
|
public Sttb( int cDataLength, byte[] buffer, int startOffset )
|
||||||
fillFields( buffer, startOffset );
|
{
|
||||||
}
|
this._cDataLength = cDataLength;
|
||||||
|
fillFields( buffer, startOffset );
|
||||||
public Sttb( int cDataLength, String[] data )
|
}
|
||||||
{
|
|
||||||
this._cDataLength = cDataLength;
|
public Sttb( int cDataLength, String[] data )
|
||||||
|
{
|
||||||
this._data = Arrays.copyOf(data, data.length);
|
this._cDataLength = cDataLength;
|
||||||
|
|
||||||
this._cbExtra = 0;
|
this._data = Arrays.copyOf(data, data.length);
|
||||||
this._extraData = null;
|
|
||||||
}
|
this._cbExtra = 0;
|
||||||
|
this._extraData = null;
|
||||||
public void fillFields( byte[] buffer, int startOffset )
|
}
|
||||||
{
|
|
||||||
short ffff = LittleEndian.getShort( buffer, startOffset );
|
public void fillFields( byte[] buffer, int startOffset )
|
||||||
int offset = startOffset + LittleEndian.SHORT_SIZE;
|
{
|
||||||
|
short ffff = LittleEndian.getShort( buffer, startOffset );
|
||||||
if ( ffff != (short) 0xffff )
|
int offset = startOffset + LittleEndian.SHORT_SIZE;
|
||||||
{
|
|
||||||
// Non-extended character Pascal strings
|
if ( ffff != (short) 0xffff )
|
||||||
throw new UnsupportedOperationException(
|
{
|
||||||
"Non-extended character Pascal strings are not supported right now. "
|
POILogFactory.getLogger(Sttb.class).log(
|
||||||
+ "Please, contact POI developers for update." );
|
POILogger.WARN,
|
||||||
}
|
"Non-extended character Pascal strings are not supported right now. "
|
||||||
// strings are extended character strings
|
+ "Creating empty values in the RevisionMarkAuthorTable for now. " +
|
||||||
|
"Please, contact POI developers for update.");
|
||||||
int cData = _cDataLength == 2 ? LittleEndian.getUShort( buffer, offset )
|
//set data and extraData to empty values to avoid
|
||||||
: LittleEndian.getInt( buffer, offset );
|
//downstream NPE in case someone calls getEntries on RevisionMarkAuthorTable
|
||||||
offset += _cDataLength;
|
_data = new String[0];
|
||||||
|
_extraData = new byte[0][];
|
||||||
this._cbExtra = LittleEndian.getUShort( buffer, offset );
|
|
||||||
offset += 2;
|
return;
|
||||||
|
}
|
||||||
_data = new String[cData];
|
// strings are extended character strings
|
||||||
_extraData = new byte[cData][];
|
|
||||||
|
int cData = _cDataLength == 2 ? LittleEndian.getUShort( buffer, offset )
|
||||||
for ( int i = 0; i < cData; i++ )
|
: LittleEndian.getInt( buffer, offset );
|
||||||
{
|
offset += _cDataLength;
|
||||||
int cchData = LittleEndian.getShort( buffer, offset );
|
|
||||||
offset += 2;
|
this._cbExtra = LittleEndian.getUShort( buffer, offset );
|
||||||
|
offset += 2;
|
||||||
if ( cchData < 0 )
|
|
||||||
continue;
|
_data = new String[cData];
|
||||||
|
_extraData = new byte[cData][];
|
||||||
_data[i] = StringUtil.getFromUnicodeLE( buffer, offset, cchData );
|
|
||||||
offset += cchData * 2;
|
for ( int i = 0; i < cData; i++ )
|
||||||
|
{
|
||||||
_extraData[i] = LittleEndian
|
int cchData = LittleEndian.getShort( buffer, offset );
|
||||||
.getByteArray( buffer, offset, _cbExtra );
|
offset += 2;
|
||||||
offset += _cbExtra;
|
|
||||||
}
|
if ( cchData < 0 )
|
||||||
}
|
continue;
|
||||||
|
|
||||||
/**
|
_data[i] = StringUtil.getFromUnicodeLE( buffer, offset, cchData );
|
||||||
* The definition of each STTB specifies the meaning of this field. If this
|
offset += cchData * 2;
|
||||||
* STTB uses extended characters, the size of this field is 2*cchData bytes
|
|
||||||
* and it is a Unicode string unless otherwise specified by the STTB
|
_extraData[i] = LittleEndian
|
||||||
* definition. If this STTB does not use extended characters, then the size
|
.getByteArray( buffer, offset, _cbExtra );
|
||||||
* of this field is cchData bytes and it is an ANSI string, unless otherwise
|
offset += _cbExtra;
|
||||||
* specified by the STTB definition.
|
}
|
||||||
*/
|
}
|
||||||
public String[] getData()
|
|
||||||
{
|
/**
|
||||||
return _data;
|
* The definition of each STTB specifies the meaning of this field. If this
|
||||||
}
|
* STTB uses extended characters, the size of this field is 2*cchData bytes
|
||||||
|
* and it is a Unicode string unless otherwise specified by the STTB
|
||||||
public int getSize()
|
* definition. If this STTB does not use extended characters, then the size
|
||||||
{
|
* of this field is cchData bytes and it is an ANSI string, unless otherwise
|
||||||
// ffff
|
* specified by the STTB definition.
|
||||||
int size = LittleEndian.SHORT_SIZE;
|
*/
|
||||||
|
public String[] getData()
|
||||||
// cData
|
{
|
||||||
size += _cDataLength;
|
return _data;
|
||||||
|
}
|
||||||
// cbExtra
|
|
||||||
size += LittleEndian.SHORT_SIZE;
|
public int getSize()
|
||||||
|
{
|
||||||
if ( this._fExtend )
|
// ffff
|
||||||
{
|
int size = LittleEndian.SHORT_SIZE;
|
||||||
for ( String data : _data )
|
|
||||||
{
|
// cData
|
||||||
// cchData
|
size += _cDataLength;
|
||||||
size += LittleEndian.SHORT_SIZE;
|
|
||||||
// data
|
// cbExtra
|
||||||
size += 2 * data.length();
|
size += LittleEndian.SHORT_SIZE;
|
||||||
}
|
|
||||||
}
|
if ( this._fExtend )
|
||||||
else
|
{
|
||||||
{
|
for ( String data : _data )
|
||||||
for ( String data : _data )
|
{
|
||||||
{
|
// cchData
|
||||||
// cchData
|
size += LittleEndian.SHORT_SIZE;
|
||||||
size += LittleEndian.BYTE_SIZE;
|
// data
|
||||||
// data
|
size += 2 * data.length();
|
||||||
size += 1 * data.length();
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
// extraData
|
for ( String data : _data )
|
||||||
if ( _extraData != null )
|
{
|
||||||
{
|
// cchData
|
||||||
size += _cbExtra * _data.length;
|
size += LittleEndian.BYTE_SIZE;
|
||||||
}
|
// data
|
||||||
|
size += 1 * data.length();
|
||||||
return size;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] serialize()
|
// extraData
|
||||||
{
|
if ( _extraData != null )
|
||||||
final byte[] buffer = new byte[getSize()];
|
{
|
||||||
|
size += _cbExtra * _data.length;
|
||||||
LittleEndian.putShort( buffer, 0, (short) 0xffff );
|
}
|
||||||
|
|
||||||
if ( _data == null || _data.length == 0 )
|
return size;
|
||||||
{
|
}
|
||||||
if ( _cDataLength == 4 )
|
|
||||||
{
|
public byte[] serialize()
|
||||||
LittleEndian.putInt( buffer, 2, 0 );
|
{
|
||||||
LittleEndian.putUShort( buffer, 6, _cbExtra );
|
final byte[] buffer = new byte[getSize()];
|
||||||
return buffer;
|
|
||||||
}
|
LittleEndian.putShort( buffer, 0, (short) 0xffff );
|
||||||
|
|
||||||
LittleEndian.putUShort( buffer, 2, 0 );
|
if ( _data == null || _data.length == 0 )
|
||||||
LittleEndian.putUShort( buffer, 4, _cbExtra );
|
{
|
||||||
return buffer;
|
if ( _cDataLength == 4 )
|
||||||
}
|
{
|
||||||
|
LittleEndian.putInt( buffer, 2, 0 );
|
||||||
int offset;
|
LittleEndian.putUShort( buffer, 6, _cbExtra );
|
||||||
if ( _cDataLength == 4 )
|
return buffer;
|
||||||
{
|
}
|
||||||
LittleEndian.putInt( buffer, 2, _data.length );
|
|
||||||
LittleEndian.putUShort( buffer, 6, _cbExtra );
|
LittleEndian.putUShort( buffer, 2, 0 );
|
||||||
offset = 2 + LittleEndian.INT_SIZE + LittleEndian.SHORT_SIZE;
|
LittleEndian.putUShort( buffer, 4, _cbExtra );
|
||||||
}
|
return buffer;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
LittleEndian.putUShort( buffer, 2, _data.length );
|
int offset;
|
||||||
LittleEndian.putUShort( buffer, 4, _cbExtra );
|
if ( _cDataLength == 4 )
|
||||||
offset = 2 + LittleEndian.SHORT_SIZE + LittleEndian.SHORT_SIZE;
|
{
|
||||||
}
|
LittleEndian.putInt( buffer, 2, _data.length );
|
||||||
|
LittleEndian.putUShort( buffer, 6, _cbExtra );
|
||||||
for ( int i = 0; i < _data.length; i++ )
|
offset = 2 + LittleEndian.INT_SIZE + LittleEndian.SHORT_SIZE;
|
||||||
{
|
}
|
||||||
String entry = _data[i];
|
else
|
||||||
if ( entry == null )
|
{
|
||||||
{
|
LittleEndian.putUShort( buffer, 2, _data.length );
|
||||||
// is it correct?
|
LittleEndian.putUShort( buffer, 4, _cbExtra );
|
||||||
buffer[offset] = -1;
|
offset = 2 + LittleEndian.SHORT_SIZE + LittleEndian.SHORT_SIZE;
|
||||||
buffer[offset + 1] = 0;
|
}
|
||||||
offset += 2;
|
|
||||||
continue;
|
for ( int i = 0; i < _data.length; i++ )
|
||||||
}
|
{
|
||||||
|
String entry = _data[i];
|
||||||
if ( _fExtend )
|
if ( entry == null )
|
||||||
{
|
{
|
||||||
LittleEndian.putUShort( buffer, offset, entry.length() );
|
// is it correct?
|
||||||
offset += LittleEndian.SHORT_SIZE;
|
buffer[offset] = -1;
|
||||||
|
buffer[offset + 1] = 0;
|
||||||
StringUtil.putUnicodeLE( entry, buffer, offset );
|
offset += 2;
|
||||||
offset += 2 * entry.length();
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if ( _fExtend )
|
||||||
throw new UnsupportedOperationException(
|
{
|
||||||
"ANSI STTB is not supported yet" );
|
LittleEndian.putUShort( buffer, offset, entry.length() );
|
||||||
}
|
offset += LittleEndian.SHORT_SIZE;
|
||||||
|
|
||||||
if ( _cbExtra != 0 )
|
StringUtil.putUnicodeLE( entry, buffer, offset );
|
||||||
{
|
offset += 2 * entry.length();
|
||||||
if ( _extraData[i] != null && _extraData[i].length != 0 )
|
}
|
||||||
{
|
else
|
||||||
System.arraycopy( _extraData[i], 0, buffer, offset,
|
{
|
||||||
Math.min( _extraData[i].length, _cbExtra ) );
|
throw new UnsupportedOperationException(
|
||||||
}
|
"ANSI STTB is not supported yet" );
|
||||||
offset += _cbExtra;
|
}
|
||||||
}
|
|
||||||
}
|
if ( _cbExtra != 0 )
|
||||||
|
{
|
||||||
return buffer;
|
if ( _extraData[i] != null && _extraData[i].length != 0 )
|
||||||
}
|
{
|
||||||
|
System.arraycopy( _extraData[i], 0, buffer, offset,
|
||||||
public int serialize( byte[] buffer, int offset )
|
Math.min( _extraData[i].length, _cbExtra ) );
|
||||||
{
|
}
|
||||||
byte[] bs = serialize();
|
offset += _cbExtra;
|
||||||
System.arraycopy( bs, 0, buffer, offset, bs.length );
|
}
|
||||||
return bs.length;
|
}
|
||||||
}
|
|
||||||
}
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int serialize( byte[] buffer, int offset )
|
||||||
|
{
|
||||||
|
byte[] bs = serialize();
|
||||||
|
System.arraycopy( bs, 0, buffer, offset, bs.length );
|
||||||
|
return bs.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue