Author: tallison
Date: Tue Oct 30 13:25:20 2018
New Revision: 1845238
URL: http://svn.apache.org/viewvc?rev=1845238&view=rev
Log:
bug 62625 -- add special handling for REFERENCE_NAME record that may only
contain an ascii string, against the spec in VBAMacroReader
Added:
poi/trunk/test-data/spreadsheet/62625.bin (with props)
Modified:
poi/site/src/documentation/content/xdocs/changes.xml
poi/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java
poi/trunk/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java
Modified: poi/site/src/documentation/content/xdocs/changes.xml
URL:
http://svn.apache.org/viewvc/poi/site/src/documentation/content/xdocs/changes.xml?rev=1845238&r1=1845237&r2=1845238&view=diff
==============================================================================
--- poi/site/src/documentation/content/xdocs/changes.xml (original)
+++ poi/site/src/documentation/content/xdocs/changes.xml Tue Oct 30 13:25:20
2018
@@ -95,6 +95,7 @@
<summary-item>Upgrade to XMLBeans 3.0.2</summary-item>
</summary>
<actions>
+ <action dev="PD" type="fix" fixes-bug="62625"
context="POI_Overall">Handle off-spec, variant REFERENCE_NAME record structure
in VBAMacroReader</action>
<action dev="PD" type="fix" fixes-bug="62624"
context="POI_Overall">Handle module name mapping in VBAMacroReader</action>
<action dev="PD" type="fix" fixes-bug="62859" context="XWPF">Rare NPE
while creating XWPFSDTContent</action>
<action dev="PD" type="add" fixes-bug="62373"
context="SS_Common">Support for FREQUENCY function</action>
Modified: poi/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java?rev=1845238&r1=1845237&r2=1845238&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java
(original)
+++ poi/trunk/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java Tue Oct
30 13:25:20 2018
@@ -29,6 +29,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.PushbackInputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
@@ -462,10 +463,18 @@ public class VBAMacroReader implements C
private static class ASCIIUnicodeStringPair {
private final String ascii;
private final String unicode;
+ private final int pushbackRecordId;
+
+ ASCIIUnicodeStringPair(String ascii, int pushbackRecordId) {
+ this.ascii = ascii;
+ this.unicode = "";
+ this.pushbackRecordId = pushbackRecordId;
+ }
ASCIIUnicodeStringPair(String ascii, String unicode) {
this.ascii = ascii;
this.unicode = unicode;
+ pushbackRecordId = -1;
}
private String getAscii() {
@@ -475,6 +484,10 @@ public class VBAMacroReader implements C
private String getUnicode() {
return unicode;
}
+
+ private int getPushbackRecordId() {
+ return pushbackRecordId;
+ }
}
private void processDirStream(Entry dir, ModuleMap modules) throws
IOException {
@@ -521,7 +534,27 @@ public class VBAMacroReader implements C
if (dirState.equals(DIR_STATE.INFORMATION_RECORD))
{
dirState = DIR_STATE.REFERENCES_RECORD;
}
- readStringPair(in, modules.charset,
REFERENCE_NAME_RESERVED);
+ ASCIIUnicodeStringPair stringPair =
readStringPair(in,
+ modules.charset, REFERENCE_NAME_RESERVED,
false);
+ if (stringPair.getPushbackRecordId() == -1) {
+ break;
+ }
+ //Special handling for when there's only an ascii
string and a REFERENCED_REGISTERED
+ //record that follows.
+ //See
https://github.com/decalage2/oletools/blob/master/oletools/olevba.py#L1516
+ //and
https://github.com/decalage2/oletools/pull/135 from (@c1fe)
+ if (stringPair.getPushbackRecordId() !=
RecordType.REFERENCE_REGISTERED.id) {
+ throw new IllegalArgumentException("Unexpected
reserved character. "+
+ "Expected
"+Integer.toHexString(REFERENCE_NAME_RESERVED)
+ + " or
"+Integer.toHexString(RecordType.REFERENCE_REGISTERED.id)+
+ " not:
"+Integer.toHexString(stringPair.getPushbackRecordId()));
+ }
+ //fall through!
+ case REFERENCE_REGISTERED:
+ //REFERENCE_REGISTERED must come immediately after
+ //REFERENCE_NAME to allow for fall through in
special case of bug 62625
+ int recLength = in.readInt();
+ trySkip(in, recLength);
break;
case MODULE_DOC_STRING:
int modDocStringLength = in.readInt();
@@ -582,13 +615,27 @@ public class VBAMacroReader implements C
}
}
- private ASCIIUnicodeStringPair readStringPair(RLEDecompressingInputStream
in, Charset charset, int reservedByte) throws IOException {
+
+
+ private ASCIIUnicodeStringPair readStringPair(RLEDecompressingInputStream
in,
+ Charset charset, int
reservedByte) throws IOException {
+ return readStringPair(in, charset, reservedByte, true);
+ }
+
+ private ASCIIUnicodeStringPair readStringPair(RLEDecompressingInputStream
in,
+ Charset charset, int
reservedByte,
+ boolean
throwOnUnexpectedReservedByte) throws IOException {
int nameLength = in.readInt();
String ascii = readString(in, nameLength, charset);
int reserved = in.readShort();
+
if (reserved != reservedByte) {
- throw new IOException("Expected
"+Integer.toHexString(reservedByte)+ "after name before Unicode name, but
found: " +
- Integer.toHexString(reserved));
+ if (throwOnUnexpectedReservedByte) {
+ throw new IOException("Expected " +
Integer.toHexString(reservedByte) + "after name before Unicode name, but found:
" +
+ Integer.toHexString(reserved));
+ } else {
+ return new ASCIIUnicodeStringPair(ascii, reserved);
+ }
}
int unicodeNameRecordLength = in.readInt();
String unicode = readUnicodeString(in, unicodeNameRecordLength);
Modified:
poi/trunk/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java?rev=1845238&r1=1845237&r2=1845238&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java
(original)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java
Tue Oct 30 13:25:20 2018
@@ -300,4 +300,21 @@ public class TestVBAMacroReader {
assertEquals(Module.ModuleType.Module,
macros.get("M\u00F3dulo1").geModuleType());
r.close();
}
+
+ @Test
+ public void bug62625() throws IOException {
+ //macro comes from Common Crawl: 4BZ22N5QG5R2SUU2MNN47PO7VBQLNYIQ
+ //A REFERENCE_NAME can sometimes only have an ascii string without
+ //a reserved byte followed by the unicode string.
+ //See
https://github.com/decalage2/oletools/blob/master/oletools/olevba.py#L1516
+ //and https://github.com/decalage2/oletools/pull/135 from (@c1fe)
+
+
+ File f = POIDataSamples.getSpreadSheetInstance().getFile("62625.bin");
+ VBAMacroReader r = new VBAMacroReader(f);
+
+ Map<String, Module> macros = r.readMacroModules();
+ assertEquals(20, macros.size());
+ r.close();
+ }
}
Added: poi/trunk/test-data/spreadsheet/62625.bin
URL:
http://svn.apache.org/viewvc/poi/trunk/test-data/spreadsheet/62625.bin?rev=1845238&view=auto
==============================================================================
Binary file - no diff available.
Propchange: poi/trunk/test-data/spreadsheet/62625.bin
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]