Exemplo n.º 1
0
//
// Native method DirRename
//
JSBool PR_CALLBACK
InstallFileOpDirRename(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsInstall *nativeThis =
    GetNativeThis(cx, obj, argv);
  if (!nativeThis)
    return JS_FALSE;

  PRInt32 nativeRet;
  nsAutoString b1;
  JSObject *jsObj;
  nsInstallFolder *folder;

  *rval = INT_TO_JSVAL(nsInstall::UNEXPECTED_ERROR);

  if(argc >= 2)
  {
    //  public int DirRename (String aSourceFolder,
    //                        String aTargetFolder);

    ConvertJSValToStr(b1, cx, argv[1]);

// fix: nsFileSpec::Rename() does not accept new name as a
//      nsFileSpec type.  It only accepts a char* type for the new name
//      This is a bug with nsFileSpec.  A char* will be used until
//      nsFileSpec if fixed.
//    nsFileSpec fsB1(b1);
    
    if (argv[0] == JSVAL_NULL || !JSVAL_IS_OBJECT(argv[0])) //argv[0] MUST be a jsval
    {
      *rval = INT_TO_JSVAL(nsInstall::INVALID_ARGUMENTS);
      return JS_TRUE;
    }

    jsObj = JSVAL_TO_OBJECT(argv[0]);

    if (!JS_InstanceOf(cx, jsObj, &FileSpecObjectClass, nsnull))
    {
      *rval = INT_TO_JSVAL(nsInstall::INVALID_ARGUMENTS);
      return JS_TRUE;
    }

    folder = (nsInstallFolder*)JS_GetPrivate(cx, jsObj);

    if(!folder || NS_OK != nativeThis->FileOpDirRename(*folder, b1, &nativeRet))
    {
      return JS_TRUE;
    }

    *rval = INT_TO_JSVAL(nativeRet);
  }
  else
  {
    JS_ReportError(cx, "Function DirRename requires 2 parameters");
    return JS_TRUE;
  }

  return JS_TRUE;
}
Exemplo n.º 2
0
//
// Native method FileExecute
//
JSBool PR_CALLBACK
InstallFileOpFileExecute(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsInstall *nativeThis =
    GetNativeThis(cx, obj, argv);
  if (!nativeThis)
    return JS_FALSE;

  PRInt32 nativeRet;
  nsAutoString b1;
  PRBool blocking = PR_FALSE;
  JSObject *jsObj;
  nsInstallFolder *folder;

  *rval = INT_TO_JSVAL(nsInstall::UNEXPECTED_ERROR);

  if(argc >= 3)
  {
    //  public int FileExecute (nsInstallFolder aSourceFolder,
    //                          String aParameters
    //                          PRBool aBlocking);

    ConvertJSValToStr(b1, cx, argv[1]);
    ConvertJSValToBool(&blocking, cx, argv[2]);
  }
  else if(argc >= 2)
  {
    if(JSVAL_IS_BOOLEAN(argv[1]))
    {
      //  public int FileExecute (nsInstallFolder aSourceFolder,
      //                          PRBool aBlocking);
      ConvertJSValToBool(&blocking, cx, argv[1]);
      b1.SetLength(0);
    }
    else
    {
      //  public int FileExecute (nsInstallFolder aSourceFolder,
      //                          String aParameters);
      ConvertJSValToStr(b1, cx, argv[1]);
    }
  }
  else
    b1.SetLength(0);

  if (argv[0] == JSVAL_NULL || !JSVAL_IS_OBJECT(argv[0])) //argv[0] MUST be a jsval
  {
      *rval = INT_TO_JSVAL(nsInstall::INVALID_ARGUMENTS);
      return JS_TRUE;
  }

  jsObj = JSVAL_TO_OBJECT(argv[0]);

  if (!JS_InstanceOf(cx, jsObj, &FileSpecObjectClass, nsnull))
  {
      *rval = INT_TO_JSVAL(nsInstall::INVALID_ARGUMENTS);
      return JS_TRUE;
  }

  folder = (nsInstallFolder*)JS_GetPrivate(cx, jsObj);

  jsrefcount saveDepth;
  saveDepth = JS_SuspendRequest(cx);//Need to suspend use of thread or deadlock occurs
  nsresult rv = nativeThis->FileOpFileExecute(*folder, b1, blocking, &nativeRet);
  JS_ResumeRequest(cx, saveDepth);
  if(NS_FAILED(rv)) 
     return JS_TRUE;

  *rval = INT_TO_JSVAL(nativeRet);

  return JS_TRUE;
}
Exemplo n.º 3
0
//
// Native method FileMacAlias
//
JSBool PR_CALLBACK
InstallFileOpFileMacAlias(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsInstall *nativeThis =
    GetNativeThis(cx, obj, argv);
  if (!nativeThis)
    return JS_FALSE;

  PRInt32          nativeRet;
  nsAutoString     sourceLeaf, aliasLeaf;
  JSObject         *jsoSourceFolder, *jsoAliasFolder;
  nsInstallFolder  *nsifSourceFolder, *nsifAliasFolder;
  nsresult         rv1 = NS_OK, rv2 = NS_OK;
  
  *rval = JSVAL_NULL;

  if(argc >= 3)
  {
    // public int FileMacAlias( InstallFolder aSourceFolder,
    //                          String        aSourceName,
    //                          InstallFolder aAliasFolder );
    // where
    //      aSourceFolder -- the folder of the installed file from Get*Folder() APIs
    //      aSourceName   -- the installed file's name
    //      aAliasFolder  -- the folder of the new alias from Get*Folder() APIs
    //
    // NOTE: 
    //      The destination alias name is aSourceName + " alias" (Mac-like behavior). 
    //      
    //      returns SUCCESS for successful scheduling of operation
    //              UNEXPECTED_ERROR for failure
    
    if (argv[0] == JSVAL_NULL || !JSVAL_IS_OBJECT(argv[0]) ||  // InstallFolder aSourceFolder
        argv[2] == JSVAL_NULL || !JSVAL_IS_OBJECT(argv[2]))    // InstallFolder aAliasFolder
    {
        *rval = INT_TO_JSVAL(nsInstall::INVALID_ARGUMENTS);
        return JS_TRUE;
    }

    jsoSourceFolder = JSVAL_TO_OBJECT(argv[0]);
    jsoAliasFolder  = JSVAL_TO_OBJECT(argv[2]);
    if ((!JS_InstanceOf(cx, jsoSourceFolder, &FileSpecObjectClass, nsnull)) ||
        (!JS_InstanceOf(cx, jsoAliasFolder,  &FileSpecObjectClass, nsnull)))
    {
        *rval = INT_TO_JSVAL(nsInstall::INVALID_ARGUMENTS);
        return JS_TRUE;
    }

    nsifSourceFolder = (nsInstallFolder *) JS_GetPrivate(cx, jsoSourceFolder);
    nsifAliasFolder  = (nsInstallFolder *) JS_GetPrivate(cx, jsoAliasFolder);
    if (!nsifSourceFolder || !nsifAliasFolder)
    {
        *rval = INT_TO_JSVAL(nsInstall::INVALID_ARGUMENTS);
        return JS_TRUE;
    }

    // make copies of the InstallFolders leaving originals uncontaminated
    nsCOMPtr<nsIFile> iFileSourceOrig = nsifSourceFolder->GetFileSpec(); 
    nsCOMPtr<nsIFile> iFileAliasOrig  = nsifAliasFolder->GetFileSpec();
    nsCOMPtr<nsIFile> iFileSource;
    nsCOMPtr<nsIFile> iFileAlias;
    rv1 = iFileSourceOrig->Clone(getter_AddRefs(iFileSource));
    rv2 = iFileAliasOrig->Clone(getter_AddRefs(iFileAlias));
    if (NS_FAILED(rv1) || NS_FAILED(rv2))
    {
        *rval = INT_TO_JSVAL(nsInstall::UNEXPECTED_ERROR);
        return JS_TRUE;
    }
    
    ConvertJSValToStr(sourceLeaf, cx, argv[1]);
    rv1 = iFileSource->Append(sourceLeaf);
        
    // public int FileMacAlias( InstallFolder aSourceFolder,
    //                          String        aSourceFileName,
    //                          InstallFolder aAliasFolder,
    //                          String        aAliasName );
    // where
    //      aSourceFolder -- the folder of the installed file from Get*Folder() APIs
    //      aSourceName   -- the installed file's name
    //      aAliasFolder  -- the folder of the new alias from Get*Folder() APIs
    //      aAliasName    -- the actual name of the new alias
    //      
    //      returns SUCCESS for successful scheduling of operation
    //              UNEXPECTED_ERROR for failure
    
    if (argc >= 4) 
    {
        ConvertJSValToStr(aliasLeaf, cx, argv[3]);
    }
    else
    {
    	aliasLeaf = sourceLeaf;
        aliasLeaf.AppendLiteral(" alias");   // XXX use GetResourcedString(id)
    }
    
    rv2 = iFileAlias->Append(aliasLeaf);
	if (NS_FAILED(rv1) || NS_FAILED(rv2))
	{
		*rval = INT_TO_JSVAL(nsInstall::UNEXPECTED_ERROR);
		return JS_TRUE;
	}

    if(NS_OK != nativeThis->FileOpFileMacAlias(iFileSource, iFileAlias, &nativeRet))
    {
        *rval = INT_TO_JSVAL(nsInstall::UNEXPECTED_ERROR);
        return JS_TRUE;
    }

    *rval = INT_TO_JSVAL(nativeRet);
  }
  else
  {
    JS_ReportError(cx, "Function FileMacAlias requires 3 or 4 parameters");
    return JS_TRUE;
  }

  return JS_TRUE;
}
Exemplo n.º 4
0
//
// Native method FileWindowsShortcut
//
JSBool PR_CALLBACK
InstallFileOpFileWindowsShortcut(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsInstall *nativeThis =
    GetNativeThis(cx, obj, argv);
  if (!nativeThis)
    return JS_FALSE;

  PRInt32 nativeRet;
  nsAutoString b0;
  nsAutoString b1;
  nsAutoString b2;
  nsAutoString b3;
  nsAutoString b4;
  nsAutoString b5;
  nsCOMPtr<nsILocalFile> nsfsB0;
  nsCOMPtr<nsILocalFile> nsfsB1;
  nsCOMPtr<nsILocalFile> nsfsB3;
  nsCOMPtr<nsILocalFile> nsfsB5;
  PRInt32      b6;

  //JSObject *jsObj;
  //nsInstallFolder *folder;

  *rval = JSVAL_NULL;

  if(argc >= 7)
  {
    //  public int FileWindowsShortcut(String aTarget,
    //                                 String aShortcutPath,
    //                                 String aDescription,
    //                                 String aWorkingPath,
    //                                 String aParams,
    //                                 String aIcon,
    //                                 Number aIconId);


    ConvertJSValToStr(b0, cx, argv[0]);
    NS_NewLocalFile(b0, PR_TRUE, getter_AddRefs(nsfsB0));
    ConvertJSValToStr(b1, cx, argv[1]);
    NS_NewLocalFile(b1, PR_TRUE, getter_AddRefs(nsfsB1));
    ConvertJSValToStr(b2, cx, argv[2]);
    ConvertJSValToStr(b3, cx, argv[3]);
    NS_NewLocalFile(b3, PR_TRUE, getter_AddRefs(nsfsB3));
    ConvertJSValToStr(b4, cx, argv[4]);
    ConvertJSValToStr(b5, cx, argv[5]);
    NS_NewLocalFile(b5, PR_TRUE, getter_AddRefs(nsfsB5));

    if(JSVAL_IS_NULL(argv[6]))
    {
      b6 = 0;
    }
    else
    {
      b6 = JSVAL_TO_INT(argv[6]);
    }

    if(NS_OK != nativeThis->FileOpFileWindowsShortcut(nsfsB0, nsfsB1, b2, nsfsB3, b4, nsfsB5, b6, &nativeRet))
    {
      return JS_TRUE;
    }

    *rval = INT_TO_JSVAL(nativeRet);
  }
  else
  {
    JS_ReportError(cx, "Function FileWindowsShortcut requires 7 parameters");
    return JS_TRUE;
  }

  return JS_TRUE;
}
//
// Native method StartSoftwareUpdate
//
static JSBool
InstallTriggerGlobalStartSoftwareUpdate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj);
  if (!nativeThis)
    return JS_FALSE;

  PRBool       nativeRet;
  PRInt32      flags = 0;

  *rval = JSVAL_FALSE;

  nsIScriptGlobalObject *globalObject = nsnull;
  nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx);
  if (scriptContext)
      globalObject = scriptContext->GetGlobalObject();

  if (!globalObject)
      return JS_TRUE;

  // get window.location to construct relative URLs
  nsCOMPtr<nsIURI> baseURL;
  JSObject* global = JS_GetGlobalObject(cx);
  if (global)
  {
    jsval v;
    if (JS_GetProperty(cx,global,"location",&v))
    {
      nsAutoString location;
      ConvertJSValToStr( location, cx, v );
      NS_NewURI(getter_AddRefs(baseURL), location);
    }
  }


  if ( argc >= 1 )
  {
    nsAutoString xpiURL;
    ConvertJSValToStr(xpiURL, cx, argv[0]);
    if (baseURL)
    {
        nsCAutoString resolvedURL;
        baseURL->Resolve(NS_ConvertUTF16toUTF8(xpiURL), resolvedURL);
        xpiURL = NS_ConvertUTF8toUTF16(resolvedURL);
    }

    // Make sure caller is allowed to load this url.
    nsresult rv = InstallTriggerCheckLoadURIFromScript(cx, xpiURL);
    if (NS_FAILED(rv))
        return JS_FALSE;

    if (argc >= 2 && !JS_ValueToInt32(cx, argv[1], (int32 *)&flags))
    {
        JS_ReportError(cx, "StartSoftwareUpdate() 2nd parameter must be a number");
        return JS_FALSE;
    }

    nsCOMPtr<nsIURI> checkuri;
    rv = nativeThis->GetOriginatingURI(globalObject, getter_AddRefs(checkuri));
    if (NS_SUCCEEDED(rv))
    {
        nsAutoPtr<nsXPITriggerInfo> trigger(new nsXPITriggerInfo());
        nsAutoPtr<nsXPITriggerItem> item(new nsXPITriggerItem(0,
                                                              xpiURL.get(),
                                                              nsnull));
        if (trigger && item)
        {
            // trigger will free item when complete
            trigger->Add(item.forget());
            nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(globalObject));
            nsCOMPtr<nsIXPIInstallInfo> installInfo =
                                new nsXPIInstallInfo(win, checkuri, trigger, 0);
            if (installInfo)
            {
                // From here trigger is owned by installInfo until passed on to nsXPInstallManager
                trigger.forget();
                PRBool enabled = PR_FALSE;
                nativeThis->UpdateEnabled(checkuri, XPI_WHITELIST, &enabled);
                if (!enabled)
                {
                    nsCOMPtr<nsIObserverService> os =
                      mozilla::services::GetObserverService();
                    if (os)
                        os->NotifyObservers(installInfo,
                                            "xpinstall-install-blocked",
                                            nsnull);
                }
                else
                {
                    nativeThis->StartInstall(installInfo, &nativeRet);
                    *rval = BOOLEAN_TO_JSVAL(nativeRet);
                }
            }
        }
    }
  }
  else
  {
    JS_ReportError(cx, "Function StartSoftwareUpdate requires 1 parameters");
    return JS_FALSE;
  }

  return JS_TRUE;
}
//
// Native method InstallChrome
//
static JSBool
InstallTriggerGlobalInstallChrome(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj);
  if (!nativeThis)
    return JS_FALSE;

  uint32       chromeType = NOT_CHROME;
  nsAutoString sourceURL;
  nsAutoString name;

  *rval = JSVAL_FALSE;

  // get chromeType first, the update enabled check for skins skips whitelisting
  if (argc >=1)
  {
      if (!JS_ValueToECMAUint32(cx, argv[0], &chromeType))
          return JS_FALSE;
  }

  // make sure XPInstall is enabled, return if not
  nsIScriptGlobalObject *globalObject = nsnull;
  nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx);
  if (scriptContext)
      globalObject = scriptContext->GetGlobalObject();

  if (!globalObject)
      return JS_TRUE;

  // get window.location to construct relative URLs
  nsCOMPtr<nsIURI> baseURL;
  JSObject* global = JS_GetGlobalObject(cx);
  if (global)
  {
    jsval v;
    if (JS_GetProperty(cx,global,"location",&v))
    {
      nsAutoString location;
      ConvertJSValToStr( location, cx, v );
      NS_NewURI(getter_AddRefs(baseURL), location);
    }
  }


  if ( argc >= 3 )
  {
    ConvertJSValToStr(sourceURL, cx, argv[1]);
    ConvertJSValToStr(name, cx, argv[2]);

    if (baseURL)
    {
        nsCAutoString resolvedURL;
        baseURL->Resolve(NS_ConvertUTF16toUTF8(sourceURL), resolvedURL);
        sourceURL = NS_ConvertUTF8toUTF16(resolvedURL);
    }

    // Make sure caller is allowed to load this url.
    nsresult rv = InstallTriggerCheckLoadURIFromScript(cx, sourceURL);
    if (NS_FAILED(rv))
        return JS_FALSE;

    if ( chromeType & CHROME_ALL )
    {
        // there's at least one known chrome type
        nsCOMPtr<nsIURI> checkuri;
        nsresult rv = nativeThis->GetOriginatingURI(globalObject,
                                                    getter_AddRefs(checkuri));
        if (NS_SUCCEEDED(rv))
        {
            nsAutoPtr<nsXPITriggerInfo> trigger(new nsXPITriggerInfo());
            nsAutoPtr<nsXPITriggerItem> item(new nsXPITriggerItem(name.get(),
                                                                  sourceURL.get(),
                                                                  nsnull));
            if (trigger && item)
            {
                // trigger will free item when complete
                trigger->Add(item.forget());
                nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(globalObject));
                nsCOMPtr<nsIXPIInstallInfo> installInfo =
                    new nsXPIInstallInfo(win, checkuri, trigger, chromeType);
                if (installInfo)
                {
                    // installInfo owns trigger now
                    trigger.forget();
                    PRBool enabled = PR_FALSE;
                    nativeThis->UpdateEnabled(checkuri, XPI_WHITELIST,
                                              &enabled);
                    if (!enabled)
                    {
                        nsCOMPtr<nsIObserverService> os =
                          mozilla::services::GetObserverService();
                        if (os)
                            os->NotifyObservers(installInfo,
                                                "xpinstall-install-blocked",
                                                nsnull);
                    }
                    else
                    {
                        PRBool nativeRet = PR_FALSE;
                        nativeThis->StartInstall(installInfo, &nativeRet);
                        *rval = BOOLEAN_TO_JSVAL(nativeRet);
                    }
                }
            }
        }
    }
  }
  return JS_TRUE;
}
//
// Native method Install
//
static JSBool
InstallTriggerGlobalInstall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj);
  if (!nativeThis)
    return JS_FALSE;

  *rval = JSVAL_FALSE;

  // make sure XPInstall is enabled, return false if not
  nsIScriptGlobalObject *globalObject = nsnull;
  nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx);
  if (scriptContext)
    globalObject = scriptContext->GetGlobalObject();

  if (!globalObject)
      return JS_TRUE;

  nsCOMPtr<nsIScriptSecurityManager> secman(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
  if (!secman)
  {
    JS_ReportError(cx, "Could not the script security manager service.");
    return JS_FALSE;
  }
  // get the principal.  if it doesn't exist, die.
  nsCOMPtr<nsIPrincipal> principal;
  secman->GetSubjectPrincipal(getter_AddRefs(principal));
  if (!principal)
  {
    JS_ReportError(cx, "Could not get the Subject Principal during InstallTrigger.Install()");
    return JS_FALSE;
  }

  // get window.location to construct relative URLs
  nsCOMPtr<nsIURI> baseURL;
  JSObject* global = JS_GetGlobalObject(cx);
  if (global)
  {
    jsval v;
    if (JS_GetProperty(cx,global,"location",&v))
    {
      nsAutoString location;
      ConvertJSValToStr( location, cx, v );
      NS_NewURI(getter_AddRefs(baseURL), location);
    }
  }

  PRBool abortLoad = PR_FALSE;

  // parse associative array of installs
  if ( argc >= 1 && JSVAL_IS_OBJECT(argv[0]) && JSVAL_TO_OBJECT(argv[0]) )
  {
    nsXPITriggerInfo *trigger = new nsXPITriggerInfo();
    if (!trigger)
      return JS_FALSE;

    trigger->SetPrincipal(principal);

    JSIdArray *ida = JS_Enumerate( cx, JSVAL_TO_OBJECT(argv[0]) );
    if ( ida )
    {
      jsval v;
      const PRUnichar *name, *URL;
      const PRUnichar *iconURL = nsnull;

      for (int i = 0; i < ida->length && !abortLoad; i++ )
      {
        JS_IdToValue( cx, ida->vector[i], &v );
        JSString * str = JS_ValueToString( cx, v );
        if (!str)
        {
          abortLoad = PR_TRUE;
          break;
        }

        name = reinterpret_cast<const PRUnichar*>(JS_GetStringChars( str ));

        URL = iconURL = nsnull;
        JSAutoByteString hash;
        JS_GetUCProperty( cx, JSVAL_TO_OBJECT(argv[0]), reinterpret_cast<const jschar*>(name), nsCRT::strlen(name), &v );
        if ( JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) )
        {
          jsval v2;
          if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "URL", &v2 ) && !JSVAL_IS_VOID(v2)) {
            JSString *str = JS_ValueToString(cx, v2);
            if (!str) {
              abortLoad = PR_TRUE;
              break;
            }
            URL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str));
          }

          if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "IconURL", &v2 ) && !JSVAL_IS_VOID(v2)) {
            JSString *str = JS_ValueToString(cx, v2);
            if (!str) {
              abortLoad = PR_TRUE;
              break;
            }
            iconURL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str));
          }

          if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "Hash", &v2) && !JSVAL_IS_VOID(v2)) {
            JSString *str = JS_ValueToString(cx, v2);
            if (!str || !hash.encode(cx, str)) {
              abortLoad = PR_TRUE;
              break;
            }
          }
        }
        else
        {
          JSString *str = JS_ValueToString(cx, v);
          if (!str) {
            abortLoad = PR_TRUE;
            break;
          }
          URL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str));
        }

        if ( URL )
        {
            // Get relative URL to load
            nsAutoString xpiURL(URL);
            if (baseURL)
            {
                nsCAutoString resolvedURL;
                baseURL->Resolve(NS_ConvertUTF16toUTF8(xpiURL), resolvedURL);
                xpiURL = NS_ConvertUTF8toUTF16(resolvedURL);
            }

            nsAutoString icon(iconURL);
            if (iconURL && baseURL)
            {
                nsCAutoString resolvedIcon;
                baseURL->Resolve(NS_ConvertUTF16toUTF8(icon), resolvedIcon);
                icon = NS_ConvertUTF8toUTF16(resolvedIcon);
            }

            // Make sure we're allowed to load this URL and the icon URL
            nsresult rv = InstallTriggerCheckLoadURIFromScript(cx, xpiURL);
            if (NS_FAILED(rv))
                abortLoad = PR_TRUE;

            if (!abortLoad && iconURL)
            {
                rv = InstallTriggerCheckLoadURIFromScript(cx, icon);
                if (NS_FAILED(rv))
                    abortLoad = PR_TRUE;
            }

            if (!abortLoad)
            {
                // Add the install item to the trigger collection
                nsXPITriggerItem *item =
                    new nsXPITriggerItem( name, xpiURL.get(), icon.get(), hash );
                if ( item )
                {
                    trigger->Add( item );
                }
                else
                    abortLoad = PR_TRUE;
            }
        }
        else
            abortLoad = PR_TRUE;
      }
      JS_DestroyIdArray( cx, ida );
    }


    // pass on only if good stuff found
    if (!abortLoad && trigger->Size() > 0)
    {
        nsCOMPtr<nsIURI> checkuri;
        nsresult rv = nativeThis->GetOriginatingURI(globalObject,
                                                    getter_AddRefs(checkuri));
        if (NS_SUCCEEDED(rv))
        {
            nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(globalObject));
            nsCOMPtr<nsIXPIInstallInfo> installInfo =
                new nsXPIInstallInfo(win, checkuri, trigger, 0);
            if (installInfo)
            {
                // installInfo now owns triggers
                PRBool enabled = PR_FALSE;
                nativeThis->UpdateEnabled(checkuri, XPI_WHITELIST, &enabled);
                if (!enabled)
                {
                    nsCOMPtr<nsIObserverService> os =
                      mozilla::services::GetObserverService();
                    if (os)
                        os->NotifyObservers(installInfo,
                                            "xpinstall-install-blocked",
                                            nsnull);
                }
                else
                {
                    // save callback function if any (ignore bad args for now)
                    if ( argc >= 2 && JS_TypeOfValue(cx,argv[1]) == JSTYPE_FUNCTION )
                    {
                        trigger->SaveCallback( cx, argv[1] );
                    }

                    PRBool result;
                    nativeThis->StartInstall(installInfo, &result);
                    *rval = BOOLEAN_TO_JSVAL(result);
                }
                return JS_TRUE;
            }
        }
    }
    // didn't pass it on so we must delete trigger
    delete trigger;
  }

  JS_ReportError(cx, "Incorrect arguments to InstallTrigger.Install()");
  return JS_FALSE;
}