You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ta...@apache.org on 2018/10/30 13:25:20 UTC

svn commit: r1845238 - in /poi: site/src/documentation/content/xdocs/changes.xml trunk/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java trunk/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java trunk/test-data/spreadsheet/62625.bin

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: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org