You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ye...@apache.org on 2012/07/25 17:45:09 UTC

svn commit: r1365638 - in /poi/trunk/src: documentation/content/xdocs/ scratchpad/src/org/apache/poi/hdgf/chunks/ scratchpad/src/org/apache/poi/hdgf/streams/ scratchpad/testcases/org/apache/poi/hdgf/

Author: yegor
Date: Wed Jul 25 15:45:09 2012
New Revision: 1365638

URL: http://svn.apache.org/viewvc?rev=1365638&view=rev
Log:
Bugzilla 53205 - Fix some parsing errors and encoding issues in HDGF

Modified:
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=1365638&r1=1365637&r2=1365638&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Wed Jul 25 15:45:09 2012
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.9-beta1" date="2012-??-??">
+          <action dev="poi-developers" type="fix">53205 - Fix some parsing errors and encoding issues in HDGF </action>
           <action dev="poi-developers" type="add">53204 - Improved performanceof PageSettingsBlock in HSSF </action>
           <action dev="poi-developers" type="add">53500 - Getter for repeating rows and columns</action>
           <action dev="poi-developers" type="fix">53369 - Fixed tests failing on JDK 1.7</action>

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java?rev=1365638&r1=1365637&r2=1365638&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java Wed Jul 25 15:45:09 2012
@@ -161,70 +161,76 @@ public final class Chunk {
 				continue;
 			}
 
-			// Process
-			switch(type) {
-			// Types 0->7 = a flat at bit 0->7
-			case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
-				int val = contents[offset] & (1<<type);
-				command.value = Boolean.valueOf(val > 0);
-				break;
-			case 8:
-				command.value = Byte.valueOf(contents[offset]);
-				break;
-			case 9:
-				command.value = new Double(
-						LittleEndian.getDouble(contents, offset)
-				);
-				break;
-			case 12:
-				// A Little Endian String
-				// Starts 8 bytes into the data segment
-				// Ends at end of data, or 00 00
-			   
-				// Ensure we have enough data
-				if(contents.length < 8) {
-					command.value = "";
+			try {
+				// Process
+				switch(type) {
+				// Types 0->7 = a flat at bit 0->7
+				case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+					int val = contents[offset] & (1<<type);
+					command.value = Boolean.valueOf(val > 0);
 					break;
-				}
-			   
-				// Find the end point
-				int startsAt = 8;
-				int endsAt = startsAt;
-				for(int j=startsAt; j<contents.length-1 && endsAt == startsAt; j++) {
-					if(contents[j] == 0 && contents[j+1] == 0) {
-						endsAt = j;
+				case 8:
+					command.value = Byte.valueOf(contents[offset]);
+					break;
+				case 9:
+					command.value = new Double(
+							LittleEndian.getDouble(contents, offset)
+					);
+					break;
+				case 12:
+					// A Little Endian String
+					// Starts 8 bytes into the data segment
+					// Ends at end of data, or 00 00
+
+					// Ensure we have enough data
+					if(contents.length < 8) {
+						command.value = "";
+						break;
+					}
+
+					// Find the end point
+					int startsAt = 8;
+					int endsAt = startsAt;
+					for(int j=startsAt; j<contents.length-1 && endsAt == startsAt; j++) {
+						if(contents[j] == 0 && contents[j+1] == 0) {
+							endsAt = j;
+						}
+					}
+					if(endsAt == startsAt) {
+						endsAt = contents.length;
 					}
-				}
-				if(endsAt == startsAt) {
-					endsAt = contents.length;
-				}
-				
-				int strLen = (endsAt-startsAt) / 2;
-				command.value = StringUtil.getFromUnicodeLE(contents, startsAt, strLen);
-				break;
-			case 25:
-				command.value = Short.valueOf(
-					LittleEndian.getShort(contents, offset)
-				);
-				break;
-			case 26:
-				command.value = Integer.valueOf(
-						LittleEndian.getInt(contents, offset)
-				);
-				break;
-
-			// Types 11 and 21 hold the offset to the blocks
-			case 11: case 21:
-				if(offset < contents.length - 3) {
-					int bOffset = (int)LittleEndian.getUInt(contents, offset);
-					BlockOffsetCommand bcmd = (BlockOffsetCommand)command;
-					bcmd.setOffset(bOffset);
-				}
-				break;
 
-			default:
-				logger.log(POILogger.INFO,
-						"Command of type " + type + " not processed!");
+					int strLen = endsAt - startsAt;
+					command.value = new String(contents, startsAt, strLen, header.getChunkCharset().name());
+					break;
+				case 25:
+					command.value = Short.valueOf(
+						LittleEndian.getShort(contents, offset)
+					);
+					break;
+				case 26:
+					command.value = Integer.valueOf(
+							LittleEndian.getInt(contents, offset)
+					);
+					break;
+
+				// Types 11 and 21 hold the offset to the blocks
+				case 11: case 21:
+					if(offset < contents.length - 3) {
+						int bOffset = (int)LittleEndian.getUInt(contents, offset);
+						BlockOffsetCommand bcmd = (BlockOffsetCommand)command;
+						bcmd.setOffset(bOffset);
+					}
+					break;
+
+				default:
+					logger.log(POILogger.INFO,
+							"Command of type " + type + " not processed!");
+				}
+			}
+			catch (Exception e) {
+				logger.log(POILogger.ERROR, "Unexpected error processing command, ignoring and continuing. Command: " +
+						command, e);
 			}
 
 			// Add to the array

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java?rev=1365638&r1=1365637&r2=1365638&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java Wed Jul 25 15:45:09 2012
@@ -19,6 +19,8 @@ package org.apache.poi.hdgf.chunks;
 
 import org.apache.poi.util.LittleEndian;
 
+import java.nio.charset.Charset;
+
 /**
  * A chunk header
  */
@@ -80,6 +82,7 @@ public abstract class ChunkHeader {
 	public abstract int getSizeInBytes();
 	public abstract boolean hasTrailer();
 	public abstract boolean hasSeparator();
+	public abstract Charset getChunkCharset();
 
 	/**
 	 * Returns the ID/IX of the chunk

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java?rev=1365638&r1=1365637&r2=1365638&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java Wed Jul 25 15:45:09 2012
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hdgf.chunks;
 
+import java.nio.charset.Charset;
+
 /**
  * A chunk header from v11+
  */
@@ -42,4 +44,9 @@ public final class ChunkHeaderV11 extend
 
 		return false;
 	}
+
+	@Override
+	public Charset getChunkCharset() {
+		return Charset.forName("UTF-16LE");
+	}
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java?rev=1365638&r1=1365637&r2=1365638&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java Wed Jul 25 15:45:09 2012
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hdgf.chunks;
 
+import java.nio.charset.Charset;
+
 /**
  * A chunk header from v4 or v5
  */
@@ -54,4 +56,9 @@ public final class ChunkHeaderV4V5 exten
 		// V4 and V5 never has separators
 		return false;
 	}
+
+	@Override
+	public Charset getChunkCharset() {
+		return Charset.forName("ASCII");
+	}
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java?rev=1365638&r1=1365637&r2=1365638&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java Wed Jul 25 15:45:09 2012
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hdgf.chunks;
 
+import java.nio.charset.Charset;
+
 /**
  * A chunk header from v6
  */
@@ -59,4 +61,9 @@ public class ChunkHeaderV6 extends Chunk
 		// V6 never has separators
 		return false;
 	}
+
+	@Override
+	public Charset getChunkCharset() {
+		return Charset.forName("ASCII");
+	}
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java?rev=1365638&r1=1365637&r2=1365638&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java Wed Jul 25 15:45:09 2012
@@ -52,19 +52,25 @@ public final class ChunkStream extends S
 
 		int pos = 0;
 		byte[] contents = getStore().getContents();
-		while(pos < contents.length) {
-			// Ensure we have enough data to create a chunk from
-			int headerSize = ChunkHeader.getHeaderSize(chunkFactory.getVersion());
-			if(pos+headerSize <= contents.length) {
-				Chunk chunk = chunkFactory.createChunk(contents, pos);
-				chunksA.add(chunk);
+		try {
+			while(pos < contents.length) {
+				// Ensure we have enough data to create a chunk from
+				int headerSize = ChunkHeader.getHeaderSize(chunkFactory.getVersion());
+				if(pos+headerSize <= contents.length) {
+					Chunk chunk = chunkFactory.createChunk(contents, pos);
+					chunksA.add(chunk);
 
-				pos += chunk.getOnDiskSize();
-			} else {
-				System.err.println("Needed " + headerSize + " bytes to create the next chunk header, but only found " + (contents.length-pos) + " bytes, ignoring rest of data");
-				pos = contents.length;
+					pos += chunk.getOnDiskSize();
+				} else {
+					System.err.println("Needed " + headerSize + " bytes to create the next chunk header, but only found " + (contents.length-pos) + " bytes, ignoring rest of data");
+					pos = contents.length;
+				}
 			}
 		}
+		catch (Exception e)
+		{
+			System.err.println("Failed to create chunk at " + pos + ", ignoring rest of data." + e);
+		}
 
 		chunks = chunksA.toArray(new Chunk[chunksA.size()]);
 	}

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java?rev=1365638&r1=1365637&r2=1365638&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java Wed Jul 25 15:45:09 2012
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hdgf;
 
+import org.apache.poi.hdgf.extractor.VisioTextExtractor;
 import org.apache.poi.hdgf.streams.PointerContainingStream;
 import org.apache.poi.hdgf.streams.TrailerStream;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
@@ -88,4 +89,28 @@ public final class TestHDGFCore extends 
       HDGFDiagram hdgf = new HDGFDiagram(fs);
       assertNotNull(hdgf);
 	}
+
+    public void testV6NonUtf16LE() throws Exception {
+   		fs = new POIFSFileSystem(_dgTests.openResourceAsStream("v6-non-utf16le.vsd"));
+
+   		HDGFDiagram hdgf = new HDGFDiagram(fs);
+   		assertNotNull(hdgf);
+
+        VisioTextExtractor textExtractor = new VisioTextExtractor(hdgf);
+        String text = textExtractor.getText().replace("\u0000", "").trim();
+
+        assertEquals("Table\n\n\nPropertySheet\n\n\n\nPropertySheetField", text);
+   	}
+
+    public void testUtf16LE() throws Exception {
+   		fs = new POIFSFileSystem(_dgTests.openResourceAsStream("Test_Visio-Some_Random_Text.vsd"));
+
+   		HDGFDiagram hdgf = new HDGFDiagram(fs);
+   		assertNotNull(hdgf);
+
+        VisioTextExtractor textExtractor = new VisioTextExtractor(hdgf);
+        String text = textExtractor.getText().trim();
+
+        assertEquals("text\nView\nTest View\nI am a test view\nSome random text, on a page", text);
+   	}
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org