Author: tallison
Date: Fri Jul 24 14:06:30 2015
New Revision: 1692521

URL: http://svn.apache.org/r1692521
Log:
TIKA-1678: clean up and add test file and unit test

Added:
    
tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFEncodedStringDecoder.java
   (with props)
    
tika/trunk/tika-parsers/src/test/resources/test-documents/testPDF_PDFEncodedStringInXMP.pdf
Removed:
    tika/trunk/tika-parsers/src/main/java/org/apache/pdfbox/
Modified:
    
tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
    
tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java

Added: 
tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFEncodedStringDecoder.java
URL: 
http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFEncodedStringDecoder.java?rev=1692521&view=auto
==============================================================================
--- 
tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFEncodedStringDecoder.java
 (added)
+++ 
tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFEncodedStringDecoder.java
 Fri Jul 24 14:06:30 2015
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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 obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tika.parser.pdf;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.pdfbox.cos.COSString;
+import org.apache.pdfbox.pdfparser.BaseParser;
+
+/**
+ * In fairly rare cases, a PDF's XMP will contain a string that
+ * has incorrectly been encoded with PDFEncoding: an octal for non-ascii and
+ * ascii for ascii, e.g. 
"\376\377\000M\000i\000c\000r\000o\000s\000o\000f\000t\000"
+ * <p>
+ * This class can be used to decode those strings.
+ * <p>
+ * See TIKA-1678.  Many thanks to Andrew Jackson for raising this issue
+ * and Tilman Hausherr for the solution.
+ * <p>
+ * As of this writing, we are only handling strings that start with
+ * an encoded BOM.  Andrew Jackson found a handful of other examples (e.g.
+ * this ISO-8859-7 string:
+ * "Microsoft Word - \\323\\365\\354\\354\\345\\364\\357\\367\\336
+ * \\364\\347\\362 PRAKSIS \\363\\364\\357")
+ * that we aren't currently handling.
+ */
+class PDFEncodedStringDecoder {
+
+    private static final String[] PDF_ENCODING_BOMS = {
+            "\\376\\377", //UTF-16BE
+            "\\377\\376", //UTF-16LE
+            "\\357\\273\\277"//UTF-8
+    };
+
+    /**
+     * Does this string contain an octal-encoded UTF BOM?
+     * Call this statically to determine if you should bother creating a new 
parser to parse it.
+     * @param s
+     * @return
+     */
+    static boolean shouldDecode(String s) {
+        if (s == null || s.length() < 8) {
+            return false;
+        }
+        for (String BOM : PDF_ENCODING_BOMS) {
+            if (s.startsWith(BOM)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * This assumes that {@link #shouldDecode(String)} has been called
+     * and has returned true.  If you run this on a non-octal encoded string,
+     * disaster will happen!
+     *
+     * @param value
+     * @return
+     */
+    String decode(String value) {
+        try {
+            byte[] bytes = new String("(" + value + 
")").getBytes("ISO-8859-1");
+            InputStream is = new ByteArrayInputStream(bytes);
+            COSStringParser p = new COSStringParser(is);
+            String parsed = p.myParseCOSString();
+            if (parsed != null) {
+                return parsed;
+            }
+        } catch (IOException e) {
+            //oh well, we tried.
+        }
+        //just return value if something went wrong
+        return value;
+    }
+
+    class COSStringParser extends BaseParser {
+
+        COSStringParser(InputStream buffer) throws IOException {
+            super(buffer);
+        }
+
+        /**
+         *
+         * @return parsed string or null if something went wrong.
+         */
+        String myParseCOSString() {
+            try {
+                COSString cosString = parseCOSString();
+                if (cosString != null) {
+                    return cosString.getString();
+                }
+            } catch (IOException e) {
+            }
+            return null;
+        }
+    }
+}

Propchange: 
tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFEncodedStringDecoder.java
------------------------------------------------------------------------------
    svn:eol-style = LF

Modified: 
tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
URL: 
http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFParser.java?rev=1692521&r1=1692520&r2=1692521&view=diff
==============================================================================
--- 
tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFParser.java 
(original)
+++ 
tika/trunk/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDFParser.java 
Fri Jul 24 14:06:30 2015
@@ -37,7 +37,6 @@ import org.apache.pdfbox.exceptions.Cryp
 import org.apache.pdfbox.io.RandomAccess;
 import org.apache.pdfbox.io.RandomAccessBuffer;
 import org.apache.pdfbox.io.RandomAccessFile;
-import org.apache.pdfbox.pdfparser.PDFOctalUnicodeDecoder;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDDocumentInformation;
 import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
@@ -458,8 +457,8 @@ public class PDFParser extends AbstractP
     }
 
     private String decode(String value) {
-        if (PDFOctalUnicodeDecoder.shouldDecode(value)) {
-            PDFOctalUnicodeDecoder d = new PDFOctalUnicodeDecoder();
+        if (PDFEncodedStringDecoder.shouldDecode(value)) {
+            PDFEncodedStringDecoder d = new PDFEncodedStringDecoder();
             return d.decode(value);
         }
         return value;

Modified: 
tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
URL: 
http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java?rev=1692521&r1=1692520&r2=1692521&view=diff
==============================================================================
--- 
tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
 (original)
+++ 
tika/trunk/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
 Fri Jul 24 14:06:30 2015
@@ -1346,6 +1346,13 @@ public class PDFParserTest extends TikaT
         }
     }
 
+    @Test
+    public void testPDFEncodedStringsInXMP() throws Exception {
+        //TIKA-1678
+        XMLResult r = getXML("testPDF_PDFEncodedStringInXMP.pdf");
+        assertEquals("Microsoft", r.metadata.get(TikaCoreProperties.TITLE));
+    }
+
     private void assertException(String path, Parser parser, ParseContext 
context, Class expected) {
         boolean noEx = false;
         InputStream is = getResourceAsStream(path);

Added: 
tika/trunk/tika-parsers/src/test/resources/test-documents/testPDF_PDFEncodedStringInXMP.pdf
URL: 
http://svn.apache.org/viewvc/tika/trunk/tika-parsers/src/test/resources/test-documents/testPDF_PDFEncodedStringInXMP.pdf?rev=1692521&view=auto
==============================================================================
Binary files 
tika/trunk/tika-parsers/src/test/resources/test-documents/testPDF_PDFEncodedStringInXMP.pdf
 (added) and 
tika/trunk/tika-parsers/src/test/resources/test-documents/testPDF_PDFEncodedStringInXMP.pdf
 Fri Jul 24 14:06:30 2015 differ


Reply via email to