Bug 522360 - [js-ctypes] Support opening of DLLs without full path using the system PATH. r=dwitte
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Sun, 18 Oct 2009 20:11:52 +0900
changeset 34006 e00dfdccc27015ed2a325b29212b8880e0561f69
parent 34005 a176eb500f882f5033e2609f07dff91f9edfe5d4
child 34007 ba0ca9a1c14c9a16fe9ac4ba30880a2240148652
push idunknown
push userunknown
push dateunknown
reviewersdwitte
bugs522360
milestone1.9.3a1pre
Bug 522360 - [js-ctypes] Support opening of DLLs without full path using the system PATH. r=dwitte
js/ctypes/Library.cpp
js/ctypes/tests/unit/test_jsctypes.js.in
--- a/js/ctypes/Library.cpp
+++ b/js/ctypes/Library.cpp
@@ -39,16 +39,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "Library.h"
 #include "Function.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 #include "nsIXPConnect.h"
 #include "nsILocalFile.h"
+#include "nsNativeCharsetUtils.h"
 
 namespace mozilla {
 namespace ctypes {
 
 /*******************************************************************************
 ** JSObject implementation
 *******************************************************************************/
 
@@ -81,51 +82,60 @@ Library::Create(JSContext* cx, jsval aPa
   if (!JS_SetReservedSlot(cx, libraryObj, 1, PRIVATE_TO_JSVAL(NULL)))
     return NULL;
 
   // attach API functions
   if (!JS_DefineFunctions(cx, libraryObj, sLibraryFunctions))
     return NULL;
 
   nsresult rv;
-  nsCOMPtr<nsILocalFile> localFile;
+  PRLibrary* library;
 
   // get the path argument. we accept either an nsILocalFile or a string path.
   // determine which we have...
   if (JSVAL_IS_STRING(aPath)) {
     const jschar* path = JS_GetStringChars(JSVAL_TO_STRING(aPath));
     if (!path)
       return NULL;
 
-    localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
-    if (!localFile)
-      return NULL;
-
-    rv = localFile->InitWithPath(nsDependentString(reinterpret_cast<const PRUnichar*>(path)));
-    if (NS_FAILED(rv))
+    // We don't use nsILocalFile.
+    // Because this interface doesn't resolve library path to use system search rule.
+    PRLibSpec libSpec;
+#ifdef XP_WIN
+    // On Windows, converting to native charset may corrupt path string.
+    // So, we have to use Unicode path directly.
+    libSpec.value.pathname_u = reinterpret_cast<const PRUnichar*>(path);
+    libSpec.type = PR_LibSpec_PathnameU;
+#else
+    nsCAutoString nativePath;
+    NS_CopyUnicodeToNative(nsDependentString(reinterpret_cast<const PRUnichar*>(path)), nativePath);
+    libSpec.value.pathname = nativePath.get();
+    libSpec.type = PR_LibSpec_Pathname;
+#endif
+    library = PR_LoadLibraryWithFlags(libSpec, 0);
+    if (!library)
       return NULL;
 
   } else if (JSVAL_IS_OBJECT(aPath)) {
     nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
 
     nsISupports* file = xpc->GetNativeOfWrapper(cx, JSVAL_TO_OBJECT(aPath));
-    localFile = do_QueryInterface(file);
+    nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file);
     if (!localFile)
       return NULL;
 
+    rv = localFile->Load(&library);
+    if (NS_FAILED(rv))
+      return NULL;
+
   } else {
     // don't convert the argument
     return NULL;
   }
 
-  PRLibrary* library;
-  rv = localFile->Load(&library);
-  if (NS_FAILED(rv))
-    return NULL;
-
   // stash the library
   if (!JS_SetReservedSlot(cx, libraryObj, 0, PRIVATE_TO_JSVAL(library)))
     return NULL;
 
   return libraryObj;
 }
 
 PRLibrary*
--- a/js/ctypes/tests/unit/test_jsctypes.js.in
+++ b/js/ctypes/tests/unit/test_jsctypes.js.in
@@ -107,16 +107,19 @@ function run_test()
   var test_i8 = library.declare("test_i8", ctypes.default_abi, ctypes.int8_t);
   do_check_eq(test_i8(), 123);
   obj.t = test_i8;
   do_check_eq(test_i8(), 123);
   do_check_eq(obj.t(), 123);
 
   // bug 521937
   do_check_throws(function () { var nolib = ctypes.open("notfoundlibrary.dll"); nolib.close(); }, Error);
+
+  // bug 522360
+  do_check_eq(run_load_system_library(), true);
 }
 
 function run_void_tests(library) {
   var test_v = library.declare("test_v", ctypes.default_abi, ctypes.void_t);
   do_check_eq(test_v(), undefined);
 }
 
 function run_int8_tests(library) {
@@ -325,8 +328,23 @@ function run_string_tests(library) {
 }
 
 function run_mixed_tests(library) {
   var test_floor = library.declare("test_floor", ctypes.default_abi, ctypes.int32_t, ctypes.int32_t, ctypes.float);
   do_check_eq(test_floor(5, 5.5), 10);
   do_check_throws(function() { test_floor(5.5, 5); }, TypeError);
 }
 
+// bug 522360 - try loading system library without full path
+function run_load_system_library()
+{
+#ifdef XP_WIN
+  var syslib = ctypes.open("user32.dll");
+#elifdef XP_MACOSX
+  var syslib = ctypes.open("libm.dylib");
+#elifdef XP_UNIX
+  var syslib = ctypes.open("libm.so");
+#else
+  // nothing run this test
+#endif
+  syslib.close();
+  return true;
+}