Modifications to use SysAllocStringLen rather than SysAllocString, since the latter causes problems with embedded nulls in strings.

Issue: 1468
Patch by: jat
Review by: scottb

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1296 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/windows/src/com/google/gwt/dev/shell/ie/SwtOleGlue.java b/dev/windows/src/com/google/gwt/dev/shell/ie/SwtOleGlue.java
index f5a9378..1ed7552 100644
--- a/dev/windows/src/com/google/gwt/dev/shell/ie/SwtOleGlue.java
+++ b/dev/windows/src/com/google/gwt/dev/shell/ie/SwtOleGlue.java
@@ -165,13 +165,13 @@
   }
 
   /**
-   * Wrapper for the OS' SysAllocString().
+   * Convert a Java string to a COM BSTR.
+   * 
+   * Wrapper for the OS' SysAllocStringLen(), since SysAllocString() is not
+   * safe for embedded nulls.
    */
   public static int sysAllocString(String s) {
-    int len = s.length();
-    char[] chars = new char[len + 1];
-    s.getChars(0, len, chars, 0);
-    return COM.SysAllocString(chars);
+    return COM.SysAllocStringLen(s.toCharArray(), s.length());
   }
  
 }
diff --git a/dev/windows/src/org/eclipse/swt/internal/ole/win32/COM.java b/dev/windows/src/org/eclipse/swt/internal/ole/win32/COM.java
index 9a159d5..769cb8a 100644
--- a/dev/windows/src/org/eclipse/swt/internal/ole/win32/COM.java
+++ b/dev/windows/src/org/eclipse/swt/internal/ole/win32/COM.java
@@ -453,6 +453,7 @@
 public static final native int StgOpenStorage(char[] pwcsName, int pstgPriority, int grfMode, int snbExclude, int reserved, int[] ppstgOpen);
 public static final native int StringFromCLSID(GUID rclsid, int[] ppsz); 
 public static final native int SysAllocString(char [] sz);
+public static final native int SysAllocStringLen(char [] sz, int len); // GOOGLE
 public static final native void SysFreeString(int bstr);
 public static final native int SysStringByteLen(int bstr);
 public static final native int VariantChangeType(int pvargDest, int pvarSrc, short wFlags, short vt);
diff --git a/dev/windows/src/org/eclipse/swt/ole/win32/Variant.java b/dev/windows/src/org/eclipse/swt/ole/win32/Variant.java
index eaccdf3..d2ba5c1 100644
--- a/dev/windows/src/org/eclipse/swt/ole/win32/Variant.java
+++ b/dev/windows/src/org/eclipse/swt/ole/win32/Variant.java
@@ -536,8 +536,8 @@
 			break;
 		case COM.VT_BSTR :
 			COM.MoveMemory(pData, new short[] {type}, 2);
-			char[] data = (stringData+"\0").toCharArray();
-			int ptr = COM.SysAllocString(data);
+			int ptr = COM.SysAllocStringLen(stringData.toCharArray(),
+				stringData.length()); // GOOGLE
 			COM.MoveMemory(pData + 8, new int[] {ptr}, 4);
 			break;
 	
diff --git a/user/test/com/google/gwt/dev/jjs/test/HostedTest.java b/user/test/com/google/gwt/dev/jjs/test/HostedTest.java
index 3e8003d..aa080b3 100644
--- a/user/test/com/google/gwt/dev/jjs/test/HostedTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/HostedTest.java
@@ -117,6 +117,10 @@
     return s + "me";
   }-*/;
 
+  private native static int getStringLength(String s) /*-{
+    return s.length;
+  }-*/;
+
   // ok to return JS string from an Object method
   private static native Object getStringAsObject() /*-{
     return "test";
@@ -206,6 +210,12 @@
     assertEquals(-125, byteAsInt(b));
   }
 
+  public void testEmbeddedNullsInStrings() {
+    String s = "Pre\u0000Post";
+    assertEquals(s.length(), getStringLength(s));
+    assertEquals(s + "me", getString(s));
+  }
+
   public void testFloat() {
     storeFloat(Float.MIN_VALUE);
     float f = getFloat();