Bug 589413 - Failure to open libnss3.so when Firefox path contains UTF-8 characters. Part 2: consumers. r=bsmedberg, a=final+
authorDan Witte <dwitte@mozilla.com>
Mon, 13 Sep 2010 10:54:02 -0700
changeset 53706 00835152707247a21e7c7dc623eb4eb920a25a3d
parent 53705 313342d1b5a962f7430f63e183df6c3d7018f58c
child 53707 7b0f220344a94efba84f7415cdc3295adcd175e8
push idunknown
push userunknown
push dateunknown
reviewersbsmedberg, final
bugs589413
milestone2.0b6pre
Bug 589413 - Failure to open libnss3.so when Firefox path contains UTF-8 characters. Part 2: consumers. r=bsmedberg, a=final+
dom/src/threads/nsDOMWorker.cpp
js/jetpack/JetpackChild.cpp
toolkit/components/ctypes/ctypes.cpp
--- a/dom/src/threads/nsDOMWorker.cpp
+++ b/dom/src/threads/nsDOMWorker.cpp
@@ -53,16 +53,17 @@
 #include "nsAXPCNativeCallContext.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfoID.h"
 #include "nsGlobalWindow.h"
 #include "nsJSON.h"
 #include "nsJSUtils.h"
 #include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
+#include "nsNativeCharsetUtils.h"
 
 #include "nsDOMThreadService.h"
 #include "nsDOMWorkerEvents.h"
 #include "nsDOMWorkerLocation.h"
 #include "nsDOMWorkerNavigator.h"
 #include "nsDOMWorkerPool.h"
 #include "nsDOMWorkerScriptLoader.h"
 #include "nsDOMWorkerTimeout.h"
@@ -420,16 +421,39 @@ nsDOMWorkerFunctions::MakeNewWorker(JSCo
     return JS_FALSE;
   }
 
   JS_SET_RVAL(aCx, aVp, v);
   return JS_TRUE;
 }
 
 #ifdef BUILD_CTYPES
+static char*
+UnicodeToNative(JSContext *cx, const jschar *source, size_t slen)
+{
+  nsCAutoString native;
+  nsDependentString unicode(reinterpret_cast<const PRUnichar*>(source), slen);
+  nsresult rv = NS_CopyUnicodeToNative(unicode, native);
+  if (NS_FAILED(rv)) {
+    JS_ReportError(cx, "could not convert string to native charset");
+    return NULL;
+  }
+
+  char* result = static_cast<char*>(JS_malloc(cx, native.Length() + 1));
+  if (!result)
+    return NULL;
+
+  memcpy(result, native.get(), native.Length() + 1);
+  return result;
+}
+
+static JSCTypesCallbacks sCallbacks = {
+  UnicodeToNative
+};
+
 JSBool
 nsDOMWorkerFunctions::CTypesLazyGetter(JSContext* aCx,
                                        JSObject* aObj,
                                        jsid aId,
                                        jsval* aVp)
 {
 #ifdef DEBUG
   {
@@ -442,18 +466,21 @@ nsDOMWorkerFunctions::CTypesLazyGetter(J
   nsDOMWorker* worker = static_cast<nsDOMWorker*>(JS_GetContextPrivate(aCx));
   NS_ASSERTION(worker, "This should be set by the DOM thread service!");
   NS_ASSERTION(worker->IsPrivileged(), "This shouldn't be possible!");
 
   if (worker->IsCanceled()) {
     return JS_FALSE;
   }
 
+  jsval ctypes;
   return JS_DeletePropertyById(aCx, aObj, aId) &&
          JS_InitCTypesClass(aCx, aObj) &&
+         JS_GetProperty(aCx, aObj, "ctypes", &ctypes) &&
+         JS_SetCTypesCallbacks(aCx, JSVAL_TO_OBJECT(ctypes), &sCallbacks) &&
          JS_GetPropertyById(aCx, aObj, aId, aVp);
 }
 #endif
 
 JSFunctionSpec gDOMWorkerFunctions[] = {
   { "dump",                nsDOMWorkerFunctions::Dump,                1, 0 },
   { "setTimeout",          nsDOMWorkerFunctions::SetTimeout,          1, 0 },
   { "clearTimeout",        nsDOMWorkerFunctions::KillTimeout,         1, 0 },
--- a/js/jetpack/JetpackChild.cpp
+++ b/js/jetpack/JetpackChild.cpp
@@ -33,16 +33,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "base/basictypes.h"
 #include "jscntxt.h"
 #include "nsXULAppAPI.h"
+#include "nsNativeCharsetUtils.h"
 
 #include "mozilla/jetpack/JetpackChild.h"
 #include "mozilla/jetpack/Handle.h"
 
 #include "jsarray.h"
 
 #include <stdio.h>
 
@@ -82,16 +83,41 @@ JetpackChild::sImplMethods[] = {
 const JSClass
 JetpackChild::sGlobalClass = {
   "JetpackChild::sGlobalClass", JSCLASS_GLOBAL_FLAGS,
   JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
   JS_EnumerateStub, JS_ResolveStub,  JS_ConvertStub,  JS_FinalizeStub,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
+#ifdef BUILD_CTYPES
+static char*
+UnicodeToNative(JSContext *cx, const jschar *source, size_t slen)
+{
+  nsCAutoString native;
+  nsDependentString unicode(reinterpret_cast<const PRUnichar*>(source), slen);
+  nsresult rv = NS_CopyUnicodeToNative(unicode, native);
+  if (NS_FAILED(rv)) {
+    JS_ReportError(cx, "could not convert string to native charset");
+    return NULL;
+  }
+
+  char* result = static_cast<char*>(JS_malloc(cx, native.Length() + 1));
+  if (!result)
+    return NULL;
+
+  memcpy(result, native.get(), native.Length() + 1);
+  return result;
+}
+
+static JSCTypesCallbacks sCallbacks = {
+  UnicodeToNative
+};
+#endif
+
 bool
 JetpackChild::Init(base::ProcessHandle aParentProcessHandle,
                    MessageLoop* aIOLoop,
                    IPC::Channel* aChannel)
 {
   if (!Open(aChannel, aParentProcessHandle, aIOLoop))
     return false;
 
@@ -106,20 +132,23 @@ JetpackChild::Init(base::ProcessHandle a
                 JSOPTION_JIT);
   JS_SetErrorReporter(mCx, ReportError);
 
   {
     JSAutoRequest request(mCx);
     JS_SetContextPrivate(mCx, this);
     JSObject* implGlobal =
       JS_NewCompartmentAndGlobalObject(mCx, const_cast<JSClass*>(&sGlobalClass), NULL);
+    jsval ctypes;
     if (!implGlobal ||
         !JS_InitStandardClasses(mCx, implGlobal) ||
 #ifdef BUILD_CTYPES
         !JS_InitCTypesClass(mCx, implGlobal) ||
+        !JS_GetProperty(mCx, implGlobal, "ctypes", &ctypes) ||
+        !JS_SetCTypesCallbacks(mCx, JSVAL_TO_OBJECT(ctypes), &sCallbacks) ||
 #endif
         !JS_DefineFunctions(mCx, implGlobal,
                             const_cast<JSFunctionSpec*>(sImplMethods)))
       return false;
   }
 
   return true;
 }
--- a/toolkit/components/ctypes/ctypes.cpp
+++ b/toolkit/components/ctypes/ctypes.cpp
@@ -36,26 +36,52 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ctypes.h"
 #include "jsapi.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsMemory.h"
+#include "nsString.h"
+#include "nsNativeCharsetUtils.h"
 
 #define JSCTYPES_CONTRACTID \
   "@mozilla.org/jsctypes;1"
 
+
 #define JSCTYPES_CID \
 { 0xc797702, 0x1c60, 0x4051, { 0x9d, 0xd7, 0x4d, 0x74, 0x5, 0x60, 0x56, 0x42 } }
 
 namespace mozilla {
 namespace ctypes {
 
+static char*
+UnicodeToNative(JSContext *cx, const jschar *source, size_t slen)
+{
+  nsCAutoString native;
+  nsDependentString unicode(reinterpret_cast<const PRUnichar*>(source), slen);
+  nsresult rv = NS_CopyUnicodeToNative(unicode, native);
+  if (NS_FAILED(rv)) {
+    JS_ReportError(cx, "could not convert string to native charset");
+    return NULL;
+  }
+
+  char* result = static_cast<char*>(JS_malloc(cx, native.Length() + 1));
+  if (!result)
+    return NULL;
+
+  memcpy(result, native.get(), native.Length() + 1);
+  return result;
+}
+
+static JSCTypesCallbacks sCallbacks = {
+  UnicodeToNative
+};
+
 NS_GENERIC_FACTORY_CONSTRUCTOR(Module)
 
 NS_IMPL_ISUPPORTS1(Module, nsIXPCScriptable)
 
 Module::Module()
 {
 }
 
@@ -87,16 +113,22 @@ SealObjectAndPrototype(JSContext* cx, JS
 
 static JSBool
 InitAndSealCTypesClass(JSContext* cx, JSObject* global)
 {
   // Init the ctypes object.
   if (!JS_InitCTypesClass(cx, global))
     return false;
 
+  // Set callbacks for charset conversion and such.
+  jsval ctypes;
+  if (!JS_GetProperty(cx, global, "ctypes", &ctypes) ||
+      !JS_SetCTypesCallbacks(cx, JSVAL_TO_OBJECT(ctypes), &sCallbacks))
+    return false;
+
   // Seal up Object, Function, and Array and their prototypes.  (This single
   // object instance is shared amongst everyone who imports the ctypes module.)
   if (!SealObjectAndPrototype(cx, global, "Object") ||
       !SealObjectAndPrototype(cx, global, "Function") ||
       !SealObjectAndPrototype(cx, global, "Array"))
     return false;
 
   // Finally, seal the global object, for good measure. (But not recursively;