LCOV - code coverage report
Current view: directory - ipc/testshell - XPCShellEnvironment.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 519 0 0.0 %
Date: 2012-06-02 Functions: 68 0 0.0 %

       1                 : /* ***** BEGIN LICENSE BLOCK *****
       2                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       3                 :  *
       4                 :  * The contents of this file are subject to the Mozilla Public License Version
       5                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       6                 :  * the License. You may obtain a copy of the License at
       7                 :  * http://www.mozilla.org/MPL/
       8                 :  *
       9                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      10                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      11                 :  * for the specific language governing rights and limitations under the
      12                 :  * License.
      13                 :  *
      14                 :  * The Original Code is Mozilla IPCShell.
      15                 :  *
      16                 :  * The Initial Developer of the Original Code is
      17                 :  *   Ben Turner <bent.mozilla@gmail.com>.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2009
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *
      23                 :  * Alternatively, the contents of this file may be used under the terms of
      24                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      25                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      26                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      27                 :  * of those above. If you wish to allow use of your version of this file only
      28                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      29                 :  * use your version of this file under the terms of the MPL, indicate your
      30                 :  * decision by deleting the provisions above and replace them with the notice
      31                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      32                 :  * the provisions above, a recipient may use your version of this file under
      33                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      34                 :  *
      35                 :  * ***** END LICENSE BLOCK ***** */
      36                 : 
      37                 : #include <stdlib.h>
      38                 : #include <errno.h>
      39                 : #ifdef HAVE_IO_H
      40                 : #include <io.h>     /* for isatty() */
      41                 : #endif
      42                 : #ifdef HAVE_UNISTD_H
      43                 : #include <unistd.h>     /* for isatty() */
      44                 : #endif
      45                 : 
      46                 : #include "base/basictypes.h"
      47                 : 
      48                 : #include "jsapi.h"
      49                 : #include "jsdbgapi.h"
      50                 : #include "jsprf.h"
      51                 : 
      52                 : #include "xpcpublic.h"
      53                 : 
      54                 : #include "XPCShellEnvironment.h"
      55                 : 
      56                 : #include "mozilla/XPCOM.h"
      57                 : 
      58                 : #include "nsIChannel.h"
      59                 : #include "nsIClassInfo.h"
      60                 : #include "nsIDirectoryService.h"
      61                 : #include "nsIJSContextStack.h"
      62                 : #include "nsIJSRuntimeService.h"
      63                 : #include "nsIPrincipal.h"
      64                 : #include "nsIScriptSecurityManager.h"
      65                 : #include "nsIURI.h"
      66                 : #include "nsIXPConnect.h"
      67                 : #include "nsIXPCScriptable.h"
      68                 : 
      69                 : #include "nsJSUtils.h"
      70                 : #include "nsJSPrincipals.h"
      71                 : #include "nsThreadUtils.h"
      72                 : #include "nsXULAppAPI.h"
      73                 : 
      74                 : #include "TestShellChild.h"
      75                 : #include "TestShellParent.h"
      76                 : 
      77                 : #define EXITCODE_RUNTIME_ERROR 3
      78                 : #define EXITCODE_FILE_NOT_FOUND 4
      79                 : 
      80                 : using mozilla::ipc::XPCShellEnvironment;
      81                 : using mozilla::ipc::TestShellChild;
      82                 : using mozilla::ipc::TestShellParent;
      83                 : 
      84                 : namespace {
      85                 : 
      86                 : static const char kDefaultRuntimeScriptFilename[] = "xpcshell.js";
      87                 : 
      88                 : class FullTrustSecMan : public nsIScriptSecurityManager
      89                 : {
      90                 : public:
      91                 :     NS_DECL_ISUPPORTS
      92                 :     NS_DECL_NSIXPCSECURITYMANAGER
      93                 :     NS_DECL_NSISCRIPTSECURITYMANAGER
      94                 : 
      95               0 :     FullTrustSecMan() { }
      96               0 :     virtual ~FullTrustSecMan() { }
      97                 : 
      98               0 :     void SetSystemPrincipal(nsIPrincipal *aPrincipal) {
      99               0 :         mSystemPrincipal = aPrincipal;
     100               0 :     }
     101                 : 
     102                 : private:
     103                 :     nsCOMPtr<nsIPrincipal> mSystemPrincipal;
     104                 : };
     105                 : 
     106                 : class XPCShellDirProvider : public nsIDirectoryServiceProvider
     107                 : {
     108                 : public:
     109                 :     NS_DECL_ISUPPORTS
     110                 :     NS_DECL_NSIDIRECTORYSERVICEPROVIDER
     111                 : 
     112                 :     XPCShellDirProvider() { }
     113                 :     ~XPCShellDirProvider() { }
     114                 : 
     115                 :     bool SetGREDir(const char *dir);
     116                 :     void ClearGREDir() { mGREDir = nsnull; }
     117                 : 
     118                 : private:
     119                 :     nsCOMPtr<nsILocalFile> mGREDir;
     120                 : };
     121                 : 
     122                 : inline XPCShellEnvironment*
     123               0 : Environment(JSContext* cx)
     124                 : {
     125                 :     XPCShellEnvironment* env = 
     126               0 :         static_cast<XPCShellEnvironment*>(JS_GetContextPrivate(cx));
     127               0 :     NS_ASSERTION(env, "Should never be null!");
     128               0 :     return env;
     129                 : }
     130                 : 
     131                 : static void
     132               0 : ScriptErrorReporter(JSContext *cx,
     133                 :                     const char *message,
     134                 :                     JSErrorReport *report)
     135                 : {
     136                 :     int i, j, k, n;
     137               0 :     char *prefix = NULL, *tmp;
     138                 :     const char *ctmp;
     139               0 :     JSStackFrame * fp = nsnull;
     140               0 :     nsCOMPtr<nsIXPConnect> xpc;
     141                 : 
     142                 :     // Don't report an exception from inner JS frames as the callers may intend
     143                 :     // to handle it.
     144               0 :     while ((fp = JS_FrameIterator(cx, &fp))) {
     145               0 :         if (JS_IsScriptFrame(cx, fp)) {
     146                 :             return;
     147                 :         }
     148                 :     }
     149                 : 
     150                 :     // In some cases cx->fp is null here so use XPConnect to tell us about inner
     151                 :     // frames.
     152               0 :     if ((xpc = do_GetService(nsIXPConnect::GetCID()))) {
     153               0 :         nsAXPCNativeCallContext *cc = nsnull;
     154               0 :         xpc->GetCurrentNativeCallContext(&cc);
     155               0 :         if (cc) {
     156               0 :             nsAXPCNativeCallContext *prev = cc;
     157               0 :             while (NS_SUCCEEDED(prev->GetPreviousCallContext(&prev)) && prev) {
     158                 :                 PRUint16 lang;
     159               0 :                 if (NS_SUCCEEDED(prev->GetLanguage(&lang)) &&
     160                 :                     lang == nsAXPCNativeCallContext::LANG_JS) {
     161                 :                     return;
     162                 :                 }
     163                 :             }
     164                 :         }
     165                 :     }
     166                 : 
     167               0 :     if (!report) {
     168               0 :         fprintf(stderr, "%s\n", message);
     169                 :         return;
     170                 :     }
     171                 : 
     172                 :     /* Conditionally ignore reported warnings. */
     173               0 :     if (JSREPORT_IS_WARNING(report->flags) &&
     174               0 :         !Environment(cx)->ShouldReportWarnings()) {
     175                 :         return;
     176                 :     }
     177                 : 
     178               0 :     if (report->filename)
     179               0 :         prefix = JS_smprintf("%s:", report->filename);
     180               0 :     if (report->lineno) {
     181               0 :         tmp = prefix;
     182               0 :         prefix = JS_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
     183               0 :         JS_free(cx, tmp);
     184                 :     }
     185               0 :     if (JSREPORT_IS_WARNING(report->flags)) {
     186               0 :         tmp = prefix;
     187                 :         prefix = JS_smprintf("%s%swarning: ",
     188                 :                              tmp ? tmp : "",
     189               0 :                              JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
     190               0 :         JS_free(cx, tmp);
     191                 :     }
     192                 : 
     193                 :     /* embedded newlines -- argh! */
     194               0 :     while ((ctmp = strchr(message, '\n')) != 0) {
     195               0 :         ctmp++;
     196               0 :         if (prefix) fputs(prefix, stderr);
     197               0 :         fwrite(message, 1, ctmp - message, stderr);
     198               0 :         message = ctmp;
     199                 :     }
     200                 :     /* If there were no filename or lineno, the prefix might be empty */
     201               0 :     if (prefix)
     202               0 :         fputs(prefix, stderr);
     203               0 :     fputs(message, stderr);
     204                 : 
     205               0 :     if (!report->linebuf) {
     206               0 :         fputc('\n', stderr);
     207               0 :         goto out;
     208                 :     }
     209                 : 
     210               0 :     fprintf(stderr, ":\n%s%s\n%s", prefix, report->linebuf, prefix);
     211               0 :     n = report->tokenptr - report->linebuf;
     212               0 :     for (i = j = 0; i < n; i++) {
     213               0 :         if (report->linebuf[i] == '\t') {
     214               0 :             for (k = (j + 8) & ~7; j < k; j++) {
     215               0 :                 fputc('.', stderr);
     216                 :             }
     217               0 :             continue;
     218                 :         }
     219               0 :         fputc('.', stderr);
     220               0 :         j++;
     221                 :     }
     222               0 :     fputs("^\n", stderr);
     223                 :  out:
     224               0 :     if (!JSREPORT_IS_WARNING(report->flags)) {
     225               0 :         Environment(cx)->SetExitCode(EXITCODE_RUNTIME_ERROR);
     226                 :     }
     227               0 :     JS_free(cx, prefix);
     228                 : }
     229                 : 
     230                 : JSContextCallback gOldContextCallback = NULL;
     231                 : 
     232                 : static JSBool
     233               0 : ContextCallback(JSContext *cx,
     234                 :                 unsigned contextOp)
     235                 : {
     236               0 :     if (gOldContextCallback && !gOldContextCallback(cx, contextOp))
     237               0 :         return JS_FALSE;
     238                 : 
     239               0 :     if (contextOp == JSCONTEXT_NEW) {
     240               0 :         JS_SetErrorReporter(cx, ScriptErrorReporter);
     241               0 :         JS_SetVersion(cx, JSVERSION_LATEST);
     242                 :     }
     243               0 :     return JS_TRUE;
     244                 : }
     245                 : 
     246                 : static JSBool
     247               0 : Print(JSContext *cx,
     248                 :       unsigned argc,
     249                 :       jsval *vp)
     250                 : {
     251                 :     unsigned i, n;
     252                 :     JSString *str;
     253                 : 
     254               0 :     jsval *argv = JS_ARGV(cx, vp);
     255               0 :     for (i = n = 0; i < argc; i++) {
     256               0 :         str = JS_ValueToString(cx, argv[i]);
     257               0 :         if (!str)
     258               0 :             return JS_FALSE;
     259               0 :         JSAutoByteString bytes(cx, str);
     260               0 :         if (!bytes)
     261               0 :             return JS_FALSE;
     262               0 :         fprintf(stdout, "%s%s", i ? " " : "", bytes.ptr());
     263               0 :         fflush(stdout);
     264                 :     }
     265               0 :     n++;
     266               0 :     if (n)
     267               0 :         fputc('\n', stdout);
     268               0 :     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     269               0 :     return JS_TRUE;
     270                 : }
     271                 : 
     272                 : static JSBool
     273               0 : GetLine(char *bufp,
     274                 :         FILE *file,
     275                 :         const char *prompt)
     276                 : {
     277                 :     char line[256];
     278               0 :     fputs(prompt, stdout);
     279               0 :     fflush(stdout);
     280               0 :     if (!fgets(line, sizeof line, file))
     281               0 :         return JS_FALSE;
     282               0 :     strcpy(bufp, line);
     283               0 :     return JS_TRUE;
     284                 : }
     285                 : 
     286                 : static JSBool
     287               0 : Dump(JSContext *cx,
     288                 :      unsigned argc,
     289                 :      jsval *vp)
     290                 : {
     291               0 :     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     292                 : 
     293                 :     JSString *str;
     294               0 :     if (!argc)
     295               0 :         return JS_TRUE;
     296                 : 
     297               0 :     str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
     298               0 :     if (!str)
     299               0 :         return JS_FALSE;
     300               0 :     JSAutoByteString bytes(cx, str);
     301               0 :     if (!bytes)
     302               0 :       return JS_FALSE;
     303                 : 
     304               0 :     fputs(bytes.ptr(), stdout);
     305               0 :     fflush(stdout);
     306               0 :     return JS_TRUE;
     307                 : }
     308                 : 
     309                 : static JSBool
     310               0 : Load(JSContext *cx,
     311                 :      unsigned argc,
     312                 :      jsval *vp)
     313                 : {
     314                 :     unsigned i;
     315                 :     JSString *str;
     316                 :     JSScript *script;
     317                 :     jsval result;
     318                 :     FILE *file;
     319                 : 
     320               0 :     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     321               0 :     if (!obj)
     322               0 :         return JS_FALSE;
     323                 : 
     324               0 :     jsval *argv = JS_ARGV(cx, vp);
     325               0 :     for (i = 0; i < argc; i++) {
     326               0 :         str = JS_ValueToString(cx, argv[i]);
     327               0 :         if (!str)
     328               0 :             return JS_FALSE;
     329               0 :         argv[i] = STRING_TO_JSVAL(str);
     330               0 :         JSAutoByteString filename(cx, str);
     331               0 :         if (!filename)
     332               0 :             return JS_FALSE;
     333               0 :         file = fopen(filename.ptr(), "r");
     334               0 :         if (!file) {
     335               0 :             JS_ReportError(cx, "cannot open file '%s' for reading", filename.ptr());
     336               0 :             return JS_FALSE;
     337                 :         }
     338               0 :         script = JS_CompileUTF8FileHandleForPrincipals(cx, obj, filename.ptr(), file,
     339               0 :                                                        Environment(cx)->GetPrincipal());
     340               0 :         fclose(file);
     341               0 :         if (!script)
     342               0 :             return JS_FALSE;
     343                 : 
     344               0 :         if (!Environment(cx)->ShouldCompileOnly() &&
     345               0 :             !JS_ExecuteScript(cx, obj, script, &result)) {
     346               0 :             return JS_FALSE;
     347                 :         }
     348                 :     }
     349               0 :     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     350               0 :     return JS_TRUE;
     351                 : }
     352                 : 
     353                 : static JSBool
     354               0 : Version(JSContext *cx,
     355                 :         unsigned argc,
     356                 :         jsval *vp)
     357                 : {
     358               0 :     jsval *argv = JS_ARGV(cx, vp);
     359               0 :     if (argc > 0 && JSVAL_IS_INT(argv[0]))
     360               0 :         JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_SetVersion(cx, JSVersion(JSVAL_TO_INT(argv[0])))));
     361                 :     else
     362               0 :         JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_GetVersion(cx)));
     363               0 :     return JS_TRUE;
     364                 : }
     365                 : 
     366                 : static JSBool
     367               0 : BuildDate(JSContext *cx, unsigned argc, jsval *vp)
     368                 : {
     369               0 :     fprintf(stdout, "built on %s at %s\n", __DATE__, __TIME__);
     370               0 :     return JS_TRUE;
     371                 : }
     372                 : 
     373                 : static JSBool
     374               0 : Quit(JSContext *cx,
     375                 :      unsigned argc,
     376                 :      jsval *vp)
     377                 : {
     378               0 :     int exitCode = 0;
     379               0 :     JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/ i", &exitCode);
     380                 : 
     381               0 :     XPCShellEnvironment* env = Environment(cx);
     382               0 :     env->SetExitCode(exitCode);
     383               0 :     env->SetIsQuitting();
     384                 : 
     385               0 :     return JS_FALSE;
     386                 : }
     387                 : 
     388                 : static JSBool
     389               0 : DumpXPC(JSContext *cx,
     390                 :         unsigned argc,
     391                 :         jsval *vp)
     392                 : {
     393               0 :     int32_t depth = 2;
     394                 : 
     395               0 :     if (argc > 0) {
     396               0 :         if (!JS_ValueToInt32(cx, JS_ARGV(cx, vp)[0], &depth))
     397               0 :             return JS_FALSE;
     398                 :     }
     399                 : 
     400               0 :     nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
     401               0 :     if(xpc)
     402               0 :         xpc->DebugDump(int16_t(depth));
     403               0 :     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     404               0 :     return JS_TRUE;
     405                 : }
     406                 : 
     407                 : static JSBool
     408               0 : GC(JSContext *cx,
     409                 :    unsigned argc,
     410                 :    jsval *vp)
     411                 : {
     412               0 :     JS_GC(cx);
     413                 : #ifdef JS_GCMETER
     414                 :     JSRuntime *rt = JS_GetRuntime(cx);
     415                 :     js_DumpGCStats(rt, stdout);
     416                 : #endif
     417               0 :     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     418               0 :     return JS_TRUE;
     419                 : }
     420                 : 
     421                 : #ifdef JS_GC_ZEAL
     422                 : static JSBool
     423               0 : GCZeal(JSContext *cx, 
     424                 :        unsigned argc,
     425                 :        jsval *vp)
     426                 : {
     427               0 :   jsval* argv = JS_ARGV(cx, vp);
     428                 : 
     429                 :   uint32_t zeal;
     430               0 :   if (!JS_ValueToECMAUint32(cx, argv[0], &zeal))
     431               0 :     return JS_FALSE;
     432                 : 
     433               0 :   JS_SetGCZeal(cx, PRUint8(zeal), JS_DEFAULT_ZEAL_FREQ, JS_FALSE);
     434               0 :   return JS_TRUE;
     435                 : }
     436                 : #endif
     437                 : 
     438                 : #ifdef DEBUG
     439                 : 
     440                 : static JSBool
     441               0 : DumpHeap(JSContext *cx,
     442                 :          unsigned argc,
     443                 :          jsval *vp)
     444                 : {
     445               0 :     JSAutoByteString fileName;
     446               0 :     void* startThing = NULL;
     447               0 :     JSGCTraceKind startTraceKind = JSTRACE_OBJECT;
     448               0 :     void *thingToFind = NULL;
     449               0 :     size_t maxDepth = (size_t)-1;
     450               0 :     void *thingToIgnore = NULL;
     451                 :     FILE *dumpFile;
     452                 :     JSBool ok;
     453                 : 
     454               0 :     jsval *argv = JS_ARGV(cx, vp);
     455               0 :     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     456                 : 
     457               0 :     vp = argv + 0;
     458               0 :     if (argc > 0 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
     459                 :         JSString *str;
     460                 : 
     461               0 :         str = JS_ValueToString(cx, *vp);
     462               0 :         if (!str)
     463               0 :             return JS_FALSE;
     464               0 :         *vp = STRING_TO_JSVAL(str);
     465               0 :         if (!fileName.encode(cx, str))
     466               0 :             return JS_FALSE;
     467                 :     }
     468                 : 
     469               0 :     vp = argv + 1;
     470               0 :     if (argc > 1 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
     471               0 :         if (!JSVAL_IS_TRACEABLE(*vp))
     472               0 :             goto not_traceable_arg;
     473               0 :         startThing = JSVAL_TO_TRACEABLE(*vp);
     474               0 :         startTraceKind = JSVAL_TRACE_KIND(*vp);
     475                 :     }
     476                 : 
     477               0 :     vp = argv + 2;
     478               0 :     if (argc > 2 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
     479               0 :         if (!JSVAL_IS_TRACEABLE(*vp))
     480               0 :             goto not_traceable_arg;
     481               0 :         thingToFind = JSVAL_TO_TRACEABLE(*vp);
     482                 :     }
     483                 : 
     484               0 :     vp = argv + 3;
     485               0 :     if (argc > 3 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
     486                 :         uint32_t depth;
     487                 : 
     488               0 :         if (!JS_ValueToECMAUint32(cx, *vp, &depth))
     489               0 :             return JS_FALSE;
     490               0 :         maxDepth = depth;
     491                 :     }
     492                 : 
     493               0 :     vp = argv + 4;
     494               0 :     if (argc > 4 && *vp != JSVAL_NULL && *vp != JSVAL_VOID) {
     495               0 :         if (!JSVAL_IS_TRACEABLE(*vp))
     496               0 :             goto not_traceable_arg;
     497               0 :         thingToIgnore = JSVAL_TO_TRACEABLE(*vp);
     498                 :     }
     499                 : 
     500               0 :     if (!fileName) {
     501               0 :         dumpFile = stdout;
     502                 :     } else {
     503               0 :         dumpFile = fopen(fileName.ptr(), "w");
     504               0 :         if (!dumpFile) {
     505                 :             fprintf(stderr, "dumpHeap: can't open %s: %s\n",
     506               0 :                     fileName.ptr(), strerror(errno));
     507               0 :             return JS_FALSE;
     508                 :         }
     509                 :     }
     510                 : 
     511                 :     ok = JS_DumpHeap(JS_GetRuntime(cx), dumpFile, startThing, startTraceKind, thingToFind,
     512               0 :                      maxDepth, thingToIgnore);
     513               0 :     if (dumpFile != stdout)
     514               0 :         fclose(dumpFile);
     515               0 :     if (!ok)
     516               0 :         JS_ReportOutOfMemory(cx);
     517               0 :     return ok;
     518                 : 
     519                 :   not_traceable_arg:
     520                 :     fprintf(stderr,
     521                 :             "dumpHeap: argument %u is not null or a heap-allocated thing\n",
     522               0 :             (unsigned)(vp - argv));
     523               0 :     return JS_FALSE;
     524                 : }
     525                 : 
     526                 : #endif /* DEBUG */
     527                 : 
     528                 : static JSBool
     529               0 : Clear(JSContext *cx,
     530                 :       unsigned argc,
     531                 :       jsval *vp)
     532                 : {
     533               0 :     jsval *argv = JS_ARGV(cx, vp);
     534               0 :     if (argc > 0 && !JSVAL_IS_PRIMITIVE(argv[0])) {
     535               0 :         JS_ClearScope(cx, JSVAL_TO_OBJECT(argv[0]));
     536                 :     } else {
     537               0 :         JS_ReportError(cx, "'clear' requires an object");
     538               0 :         return JS_FALSE;
     539                 :     }
     540               0 :     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     541               0 :     return JS_TRUE;
     542                 : }
     543                 : 
     544                 : JSFunctionSpec gGlobalFunctions[] =
     545                 : {
     546                 :     {"print",           Print,          0,0},
     547                 :     {"load",            Load,           1,0},
     548                 :     {"quit",            Quit,           0,0},
     549                 :     {"version",         Version,        1,0},
     550                 :     {"build",           BuildDate,      0,0},
     551                 :     {"dumpXPC",         DumpXPC,        1,0},
     552                 :     {"dump",            Dump,           1,0},
     553                 :     {"gc",              GC,             0,0},
     554                 : #ifdef JS_GC_ZEAL
     555                 :     {"gczeal",          GCZeal,         1,0},
     556                 : #endif
     557                 :     {"clear",           Clear,          1,0},
     558                 : #ifdef DEBUG
     559                 :     {"dumpHeap",        DumpHeap,       5,0},
     560                 : #endif
     561                 :     {nsnull,nsnull,0,0}
     562                 : };
     563                 : 
     564                 : typedef enum JSShellErrNum
     565                 : {
     566                 : #define MSG_DEF(name, number, count, exception, format) \
     567                 :     name = number,
     568                 : #include "jsshell.msg"
     569                 : #undef MSG_DEF
     570                 :     JSShellErr_Limit
     571                 : #undef MSGDEF
     572                 : } JSShellErrNum;
     573                 : 
     574                 : static void
     575               0 : ProcessFile(JSContext *cx,
     576                 :             JSObject *obj,
     577                 :             const char *filename,
     578                 :             FILE *file,
     579                 :             JSBool forceTTY)
     580                 : {
     581               0 :     XPCShellEnvironment* env = Environment(cx);
     582               0 :     XPCShellEnvironment::AutoContextPusher pusher(env);
     583                 : 
     584                 :     JSScript *script;
     585                 :     jsval result;
     586                 :     int lineno, startline;
     587                 :     JSBool ok, hitEOF;
     588                 :     char *bufp, buffer[4096];
     589                 :     JSString *str;
     590                 : 
     591               0 :     if (forceTTY) {
     592               0 :         file = stdin;
     593                 :     }
     594                 :     else
     595                 : #ifdef HAVE_ISATTY
     596               0 :     if (!isatty(fileno(file)))
     597                 : #endif
     598                 :     {
     599                 :         /*
     600                 :          * It's not interactive - just execute it.
     601                 :          *
     602                 :          * Support the UNIX #! shell hack; gobble the first line if it starts
     603                 :          * with '#'.  TODO - this isn't quite compatible with sharp variables,
     604                 :          * as a legal js program (using sharp variables) might start with '#'.
     605                 :          * But that would require multi-character lookahead.
     606                 :          */
     607               0 :         int ch = fgetc(file);
     608               0 :         if (ch == '#') {
     609               0 :             while((ch = fgetc(file)) != EOF) {
     610               0 :                 if(ch == '\n' || ch == '\r')
     611               0 :                     break;
     612                 :             }
     613                 :         }
     614               0 :         ungetc(ch, file);
     615                 : 
     616               0 :         JSAutoRequest ar(cx);
     617                 : 
     618               0 :         JSAutoEnterCompartment ac;
     619               0 :         if (!ac.enter(cx, obj)) {
     620               0 :             NS_ERROR("Failed to enter compartment!");
     621                 :             return;
     622                 :         }
     623                 : 
     624                 :         JSScript* script =
     625                 :             JS_CompileUTF8FileHandleForPrincipals(cx, obj, filename, file,
     626               0 :                                                   env->GetPrincipal());
     627               0 :         if (script && !env->ShouldCompileOnly())
     628               0 :             (void)JS_ExecuteScript(cx, obj, script, &result);
     629                 : 
     630                 :         return;
     631                 :     }
     632                 : 
     633                 :     /* It's an interactive filehandle; drop into read-eval-print loop. */
     634               0 :     lineno = 1;
     635               0 :     hitEOF = JS_FALSE;
     636               0 :     do {
     637               0 :         bufp = buffer;
     638               0 :         *bufp = '\0';
     639                 : 
     640               0 :         JSAutoRequest ar(cx);
     641                 : 
     642               0 :         JSAutoEnterCompartment ac;
     643               0 :         if (!ac.enter(cx, obj)) {
     644               0 :             NS_ERROR("Failed to enter compartment!");
     645                 :             return;
     646                 :         }
     647                 : 
     648                 :         /*
     649                 :          * Accumulate lines until we get a 'compilable unit' - one that either
     650                 :          * generates an error (before running out of source) or that compiles
     651                 :          * cleanly.  This should be whenever we get a complete statement that
     652                 :          * coincides with the end of a line.
     653                 :          */
     654               0 :         startline = lineno;
     655               0 :         do {
     656               0 :             if (!GetLine(bufp, file, startline == lineno ? "js> " : "")) {
     657               0 :                 hitEOF = JS_TRUE;
     658               0 :                 break;
     659                 :             }
     660               0 :             bufp += strlen(bufp);
     661               0 :             lineno++;
     662               0 :         } while (!JS_BufferIsCompilableUnit(cx, JS_FALSE, obj, buffer, strlen(buffer)));
     663                 : 
     664                 :         /* Clear any pending exception from previous failed compiles.  */
     665               0 :         JS_ClearPendingException(cx);
     666                 :         script =
     667                 :             JS_CompileScriptForPrincipals(cx, obj, env->GetPrincipal(), buffer,
     668               0 :                                           strlen(buffer), "typein", startline);
     669               0 :         if (script) {
     670                 :             JSErrorReporter older;
     671                 : 
     672               0 :             if (!env->ShouldCompileOnly()) {
     673               0 :                 ok = JS_ExecuteScript(cx, obj, script, &result);
     674               0 :                 if (ok && result != JSVAL_VOID) {
     675                 :                     /* Suppress error reports from JS_ValueToString(). */
     676               0 :                     older = JS_SetErrorReporter(cx, NULL);
     677               0 :                     str = JS_ValueToString(cx, result);
     678               0 :                     JSAutoByteString bytes;
     679               0 :                     if (str)
     680               0 :                         bytes.encode(cx, str);
     681               0 :                     JS_SetErrorReporter(cx, older);
     682                 : 
     683               0 :                     if (!!bytes)
     684               0 :                         fprintf(stdout, "%s\n", bytes.ptr());
     685                 :                     else
     686               0 :                         ok = JS_FALSE;
     687                 :                 }
     688                 :             }
     689                 :         }
     690               0 :     } while (!hitEOF && !env->IsQuitting());
     691                 : 
     692               0 :     fprintf(stdout, "\n");
     693                 : }
     694                 : 
     695                 : } /* anonymous namespace */
     696                 : 
     697               0 : NS_INTERFACE_MAP_BEGIN(FullTrustSecMan)
     698               0 :     NS_INTERFACE_MAP_ENTRY(nsIXPCSecurityManager)
     699               0 :     NS_INTERFACE_MAP_ENTRY(nsIScriptSecurityManager)
     700               0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCSecurityManager)
     701               0 : NS_INTERFACE_MAP_END
     702                 : 
     703               0 : NS_IMPL_ADDREF(FullTrustSecMan)
     704               0 : NS_IMPL_RELEASE(FullTrustSecMan)
     705                 : 
     706                 : NS_IMETHODIMP
     707               0 : FullTrustSecMan::CanCreateWrapper(JSContext * aJSContext,
     708                 :                                   const nsIID & aIID,
     709                 :                                   nsISupports *aObj,
     710                 :                                   nsIClassInfo *aClassInfo,
     711                 :                                   void * *aPolicy)
     712                 : {
     713               0 :     return NS_OK;
     714                 : }
     715                 : 
     716                 : NS_IMETHODIMP
     717               0 : FullTrustSecMan::CanCreateInstance(JSContext * aJSContext,
     718                 :                                    const nsCID & aCID)
     719                 : {
     720               0 :     return NS_OK;
     721                 : }
     722                 : 
     723                 : NS_IMETHODIMP
     724               0 : FullTrustSecMan::CanGetService(JSContext * aJSContext,
     725                 :                                const nsCID & aCID)
     726                 : {
     727               0 :     return NS_OK;
     728                 : }
     729                 : 
     730                 : NS_IMETHODIMP
     731               0 : FullTrustSecMan::CanAccess(PRUint32 aAction,
     732                 :                            nsAXPCNativeCallContext *aCallContext,
     733                 :                            JSContext * aJSContext,
     734                 :                            JSObject * aJSObject,
     735                 :                            nsISupports *aObj,
     736                 :                            nsIClassInfo *aClassInfo,
     737                 :                            jsid aName,
     738                 :                            void * *aPolicy)
     739                 : {
     740               0 :     return NS_OK;
     741                 : }
     742                 : 
     743                 : NS_IMETHODIMP
     744               0 : FullTrustSecMan::CheckPropertyAccess(JSContext * aJSContext,
     745                 :                                      JSObject * aJSObject,
     746                 :                                      const char *aClassName,
     747                 :                                      jsid aProperty,
     748                 :                                      PRUint32 aAction)
     749                 : {
     750               0 :     return NS_OK;
     751                 : }
     752                 : 
     753                 : NS_IMETHODIMP
     754               0 : FullTrustSecMan::CheckLoadURIFromScript(JSContext * cx,
     755                 :                                         nsIURI *uri)
     756                 : {
     757               0 :     return NS_OK;
     758                 : }
     759                 : 
     760                 : NS_IMETHODIMP
     761               0 : FullTrustSecMan::CheckLoadURIWithPrincipal(nsIPrincipal *aPrincipal,
     762                 :                                            nsIURI *uri,
     763                 :                                            PRUint32 flags)
     764                 : {
     765               0 :     return NS_OK;
     766                 : }
     767                 : 
     768                 : NS_IMETHODIMP
     769               0 : FullTrustSecMan::CheckLoadURI(nsIURI *from,
     770                 :                               nsIURI *uri,
     771                 :                               PRUint32 flags)
     772                 : {
     773               0 :     return NS_OK;
     774                 : }
     775                 : 
     776                 : NS_IMETHODIMP
     777               0 : FullTrustSecMan::CheckLoadURIStrWithPrincipal(nsIPrincipal *aPrincipal,
     778                 :                                               const nsACString & uri,
     779                 :                                               PRUint32 flags)
     780                 : {
     781               0 :     return NS_OK;
     782                 : }
     783                 : 
     784                 : NS_IMETHODIMP
     785               0 : FullTrustSecMan::CheckLoadURIStr(const nsACString & from,
     786                 :                                  const nsACString & uri,
     787                 :                                  PRUint32 flags)
     788                 : {
     789               0 :     return NS_OK;
     790                 : }
     791                 : 
     792                 : NS_IMETHODIMP
     793               0 : FullTrustSecMan::CheckFunctionAccess(JSContext * cx,
     794                 :                                      void * funObj,
     795                 :                                      void * targetObj)
     796                 : {
     797               0 :     return NS_OK;
     798                 : }
     799                 : 
     800                 : NS_IMETHODIMP
     801               0 : FullTrustSecMan::CanExecuteScripts(JSContext * cx,
     802                 :                                    nsIPrincipal *principal,
     803                 :                                    bool *_retval)
     804                 : {
     805               0 :     *_retval = true;
     806               0 :     return NS_OK;
     807                 : }
     808                 : 
     809                 : NS_IMETHODIMP
     810               0 : FullTrustSecMan::GetSubjectPrincipal(nsIPrincipal **_retval)
     811                 : {
     812               0 :     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     813               0 :     return *_retval ? NS_OK : NS_ERROR_FAILURE;
     814                 : }
     815                 : 
     816                 : NS_IMETHODIMP
     817               0 : FullTrustSecMan::GetSystemPrincipal(nsIPrincipal **_retval)
     818                 : {
     819               0 :     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     820               0 :     return *_retval ? NS_OK : NS_ERROR_FAILURE;
     821                 : }
     822                 : 
     823                 : NS_IMETHODIMP
     824               0 : FullTrustSecMan::GetCertificatePrincipal(const nsACString & aCertFingerprint,
     825                 :                                          const nsACString & aSubjectName,
     826                 :                                          const nsACString & aPrettyName,
     827                 :                                          nsISupports *aCert,
     828                 :                                          nsIURI *aURI,
     829                 :                                          nsIPrincipal **_retval)
     830                 : {
     831               0 :     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     832               0 :     return *_retval ? NS_OK : NS_ERROR_FAILURE;
     833                 : }
     834                 : 
     835                 : NS_IMETHODIMP
     836               0 : FullTrustSecMan::GetCodebasePrincipal(nsIURI *aURI,
     837                 :                                       nsIPrincipal **_retval)
     838                 : {
     839               0 :     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     840               0 :     return *_retval ? NS_OK : NS_ERROR_FAILURE;
     841                 : }
     842                 : 
     843                 : NS_IMETHODIMP
     844               0 : FullTrustSecMan::RequestCapability(nsIPrincipal *principal,
     845                 :                                    const char *capability,
     846                 :                                    PRInt16 *_retval)
     847                 : {
     848               0 :     *_retval = nsIPrincipal::ENABLE_GRANTED;
     849               0 :     return NS_OK;
     850                 : }
     851                 : 
     852                 : NS_IMETHODIMP
     853               0 : FullTrustSecMan::IsCapabilityEnabled(const char *capability,
     854                 :                                      bool *_retval)
     855                 : {
     856               0 :     *_retval = true;
     857               0 :     return NS_OK;
     858                 : }
     859                 : 
     860                 : NS_IMETHODIMP
     861               0 : FullTrustSecMan::EnableCapability(const char *capability)
     862                 : {
     863               0 :     return NS_OK;;
     864                 : }
     865                 : 
     866                 : NS_IMETHODIMP
     867               0 : FullTrustSecMan::RevertCapability(const char *capability)
     868                 : {
     869               0 :     return NS_OK;
     870                 : }
     871                 : 
     872                 : NS_IMETHODIMP
     873               0 : FullTrustSecMan::DisableCapability(const char *capability)
     874                 : {
     875               0 :     return NS_OK;
     876                 : }
     877                 : 
     878                 : NS_IMETHODIMP
     879               0 : FullTrustSecMan::SetCanEnableCapability(const nsACString & certificateFingerprint,
     880                 :                                         const char *capability,
     881                 :                                         PRInt16 canEnable)
     882                 : {
     883               0 :     return NS_OK;
     884                 : }
     885                 : 
     886                 : NS_IMETHODIMP
     887               0 : FullTrustSecMan::GetObjectPrincipal(JSContext * cx,
     888                 :                                     JSObject * obj,
     889                 :                                     nsIPrincipal **_retval)
     890                 : {
     891               0 :     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     892               0 :     return *_retval ? NS_OK : NS_ERROR_FAILURE;
     893                 : }
     894                 : 
     895                 : NS_IMETHODIMP
     896               0 : FullTrustSecMan::SubjectPrincipalIsSystem(bool *_retval)
     897                 : {
     898               0 :     *_retval = true;
     899               0 :     return NS_OK;
     900                 : }
     901                 : 
     902                 : NS_IMETHODIMP
     903               0 : FullTrustSecMan::CheckSameOrigin(JSContext * aJSContext,
     904                 :                                  nsIURI *aTargetURI)
     905                 : {
     906               0 :     return NS_OK;
     907                 : }
     908                 : 
     909                 : NS_IMETHODIMP
     910               0 : FullTrustSecMan::CheckSameOriginURI(nsIURI *aSourceURI,
     911                 :                                     nsIURI *aTargetURI,
     912                 :                                     bool reportError)
     913                 : {
     914               0 :     return NS_OK;
     915                 : }
     916                 : 
     917                 : NS_IMETHODIMP
     918               0 : FullTrustSecMan::GetPrincipalFromContext(JSContext * cx,
     919                 :                                          nsIPrincipal **_retval)
     920                 : {
     921               0 :     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     922               0 :     return *_retval ? NS_OK : NS_ERROR_FAILURE;
     923                 : }
     924                 : 
     925                 : NS_IMETHODIMP
     926               0 : FullTrustSecMan::GetChannelPrincipal(nsIChannel *aChannel,
     927                 :                                      nsIPrincipal **_retval)
     928                 : {
     929               0 :     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     930               0 :     return *_retval ? NS_OK : NS_ERROR_FAILURE;
     931                 : }
     932                 : 
     933                 : NS_IMETHODIMP
     934               0 : FullTrustSecMan::IsSystemPrincipal(nsIPrincipal *aPrincipal,
     935                 :                                    bool *_retval)
     936                 : {
     937               0 :     *_retval = aPrincipal == mSystemPrincipal;
     938               0 :     return NS_OK;
     939                 : }
     940                 : 
     941                 : NS_IMETHODIMP_(nsIPrincipal *)
     942               0 : FullTrustSecMan::GetCxSubjectPrincipal(JSContext *cx)
     943                 : {
     944               0 :     return mSystemPrincipal;
     945                 : }
     946                 : 
     947                 : NS_IMETHODIMP_(nsIPrincipal *)
     948               0 : FullTrustSecMan::GetCxSubjectPrincipalAndFrame(JSContext *cx,
     949                 :                                                JSStackFrame **fp)
     950                 : {
     951               0 :     *fp = nsnull;
     952               0 :     return mSystemPrincipal;
     953                 : }
     954                 : 
     955                 : NS_IMETHODIMP
     956               0 : FullTrustSecMan::PushContextPrincipal(JSContext *cx,
     957                 :                                       JSStackFrame *fp,
     958                 :                                       nsIPrincipal *principal)
     959                 : {
     960               0 :     return NS_OK;
     961                 : }
     962                 : 
     963                 : NS_IMETHODIMP
     964               0 : FullTrustSecMan::PopContextPrincipal(JSContext *cx)
     965                 : {
     966               0 :     return NS_OK;
     967                 : }
     968                 : 
     969                 : NS_IMETHODIMP_(nsrefcnt)
     970               0 : XPCShellDirProvider::AddRef()
     971                 : {
     972               0 :     return 2;
     973                 : }
     974                 : 
     975                 : NS_IMETHODIMP_(nsrefcnt)
     976               0 : XPCShellDirProvider::Release()
     977                 : {
     978               0 :     return 1;
     979                 : }
     980                 : 
     981               0 : NS_IMPL_QUERY_INTERFACE1(XPCShellDirProvider, nsIDirectoryServiceProvider)
     982                 : 
     983                 : bool
     984               0 : XPCShellDirProvider::SetGREDir(const char *dir)
     985                 : {
     986               0 :     nsresult rv = XRE_GetFileFromPath(dir, getter_AddRefs(mGREDir));
     987               0 :     return NS_SUCCEEDED(rv);
     988                 : }
     989                 : 
     990                 : NS_IMETHODIMP
     991               0 : XPCShellDirProvider::GetFile(const char *prop,
     992                 :                              bool *persistent,
     993                 :                              nsIFile* *result)
     994                 : {
     995               0 :     if (mGREDir && !strcmp(prop, NS_GRE_DIR)) {
     996               0 :         *persistent = true;
     997               0 :         NS_ADDREF(*result = mGREDir);
     998               0 :         return NS_OK;
     999                 :     }
    1000                 : 
    1001               0 :     return NS_ERROR_FAILURE;
    1002                 : }
    1003                 : 
    1004               0 : XPCShellEnvironment::
    1005                 : AutoContextPusher::AutoContextPusher(XPCShellEnvironment* aEnv)
    1006                 : {
    1007               0 :     NS_ASSERTION(aEnv->mCx, "Null context?!");
    1008                 : 
    1009               0 :     if (NS_SUCCEEDED(aEnv->mCxStack->Push(aEnv->mCx))) {
    1010               0 :         mEnv = aEnv;
    1011                 :     }
    1012               0 : }
    1013                 : 
    1014               0 : XPCShellEnvironment::
    1015                 : AutoContextPusher::~AutoContextPusher()
    1016                 : {
    1017               0 :     if (mEnv) {
    1018                 :         JSContext* cx;
    1019               0 :         mEnv->mCxStack->Pop(&cx);
    1020               0 :         NS_ASSERTION(cx == mEnv->mCx, "Wrong context on the stack!");
    1021                 :     }
    1022               0 : }
    1023                 : 
    1024                 : // static
    1025                 : XPCShellEnvironment*
    1026               0 : XPCShellEnvironment::CreateEnvironment()
    1027                 : {
    1028               0 :     XPCShellEnvironment* env = new XPCShellEnvironment();
    1029               0 :     if (env && !env->Init()) {
    1030               0 :         delete env;
    1031               0 :         env = nsnull;
    1032                 :     }
    1033               0 :     return env;
    1034                 : }
    1035                 : 
    1036               0 : XPCShellEnvironment::XPCShellEnvironment()
    1037                 : :   mCx(NULL),
    1038                 :     mJSPrincipals(NULL),
    1039                 :     mExitCode(0),
    1040                 :     mQuitting(JS_FALSE),
    1041                 :     mReportWarnings(JS_TRUE),
    1042               0 :     mCompileOnly(JS_FALSE)
    1043                 : {
    1044               0 : }
    1045                 : 
    1046               0 : XPCShellEnvironment::~XPCShellEnvironment()
    1047                 : {
    1048               0 :     if (mCx) {
    1049               0 :         JS_BeginRequest(mCx);
    1050                 : 
    1051               0 :         JSObject* global = GetGlobalObject();
    1052               0 :         if (global) {
    1053               0 :             JS_ClearScope(mCx, global);
    1054                 :         }
    1055               0 :         mGlobalHolder.Release();
    1056                 : 
    1057               0 :         JS_GC(mCx);
    1058                 : 
    1059               0 :         mCxStack = nsnull;
    1060                 : 
    1061               0 :         if (mJSPrincipals) {
    1062               0 :             JS_DropPrincipals(JS_GetRuntime(mCx), mJSPrincipals);
    1063                 :         }
    1064                 : 
    1065               0 :         JSRuntime* rt = gOldContextCallback ? JS_GetRuntime(mCx) : NULL;
    1066                 : 
    1067               0 :         JS_EndRequest(mCx);
    1068               0 :         JS_DestroyContext(mCx);
    1069                 : 
    1070               0 :         if (gOldContextCallback) {
    1071               0 :             NS_ASSERTION(rt, "Should never be null!");
    1072               0 :             JS_SetContextCallback(rt, gOldContextCallback);
    1073               0 :             gOldContextCallback = NULL;
    1074                 :         }
    1075                 :     }
    1076               0 : }
    1077                 : 
    1078                 : bool
    1079               0 : XPCShellEnvironment::Init()
    1080                 : {
    1081                 :     nsresult rv;
    1082                 : 
    1083                 : #ifdef HAVE_SETBUF
    1084                 :     // unbuffer stdout so that output is in the correct order; note that stderr
    1085                 :     // is unbuffered by default
    1086               0 :     setbuf(stdout, 0);
    1087                 : #endif
    1088                 : 
    1089                 :     nsCOMPtr<nsIJSRuntimeService> rtsvc =
    1090               0 :         do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
    1091               0 :     if (!rtsvc) {
    1092               0 :         NS_ERROR("failed to get nsJSRuntimeService!");
    1093               0 :         return false;
    1094                 :     }
    1095                 : 
    1096                 :     JSRuntime *rt;
    1097               0 :     if (NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt) {
    1098               0 :         NS_ERROR("failed to get JSRuntime from nsJSRuntimeService!");
    1099               0 :         return false;
    1100                 :     }
    1101                 : 
    1102               0 :     if (!mGlobalHolder.Hold(rt)) {
    1103               0 :         NS_ERROR("Can't protect global object!");
    1104               0 :         return false;
    1105                 :     }
    1106                 : 
    1107               0 :     gOldContextCallback = JS_SetContextCallback(rt, ContextCallback);
    1108                 : 
    1109               0 :     JSContext *cx = JS_NewContext(rt, 8192);
    1110               0 :     if (!cx) {
    1111               0 :         NS_ERROR("JS_NewContext failed!");
    1112                 : 
    1113               0 :         JS_SetContextCallback(rt, gOldContextCallback);
    1114               0 :         gOldContextCallback = NULL;
    1115                 : 
    1116               0 :         return false;
    1117                 :     }
    1118               0 :     mCx = cx;
    1119                 : 
    1120               0 :     JS_SetContextPrivate(cx, this);
    1121                 : 
    1122                 :     nsCOMPtr<nsIXPConnect> xpc =
    1123               0 :       do_GetService(nsIXPConnect::GetCID());
    1124               0 :     if (!xpc) {
    1125               0 :         NS_ERROR("failed to get nsXPConnect service!");
    1126               0 :         return false;
    1127                 :     }
    1128                 : 
    1129               0 :     xpc_LocalizeContext(cx);
    1130                 : 
    1131               0 :     nsRefPtr<FullTrustSecMan> secman(new FullTrustSecMan());
    1132               0 :     xpc->SetSecurityManagerForJSContext(cx, secman, 0xFFFF);
    1133                 : 
    1134               0 :     nsCOMPtr<nsIPrincipal> principal;
    1135                 : 
    1136                 :     nsCOMPtr<nsIScriptSecurityManager> securityManager =
    1137               0 :         do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
    1138               0 :     if (NS_SUCCEEDED(rv) && securityManager) {
    1139               0 :         rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal));
    1140               0 :         if (NS_FAILED(rv)) {
    1141               0 :             fprintf(stderr, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n");
    1142                 :         } else {
    1143                 :             // fetch the JS principals and stick in a global
    1144               0 :             mJSPrincipals = nsJSPrincipals::get(principal);
    1145               0 :             JS_HoldPrincipals(mJSPrincipals);
    1146               0 :             secman->SetSystemPrincipal(principal);
    1147                 :         }
    1148                 :     } else {
    1149               0 :         fprintf(stderr, "+++ Failed to get ScriptSecurityManager service, running without principals");
    1150                 :     }
    1151                 : 
    1152                 :     nsCOMPtr<nsIJSContextStack> cxStack =
    1153               0 :         do_GetService("@mozilla.org/js/xpc/ContextStack;1");
    1154               0 :     if (!cxStack) {
    1155               0 :         NS_ERROR("failed to get the nsThreadJSContextStack service!");
    1156               0 :         return false;
    1157                 :     }
    1158               0 :     mCxStack = cxStack;
    1159                 : 
    1160               0 :     AutoContextPusher pusher(this);
    1161                 : 
    1162               0 :     nsCOMPtr<nsIXPCScriptable> backstagePass;
    1163               0 :     rv = rtsvc->GetBackstagePass(getter_AddRefs(backstagePass));
    1164               0 :     if (NS_FAILED(rv)) {
    1165               0 :         NS_ERROR("Failed to get backstage pass from rtsvc!");
    1166               0 :         return false;
    1167                 :     }
    1168                 : 
    1169               0 :     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
    1170               0 :     rv = xpc->InitClassesWithNewWrappedGlobal(cx, backstagePass,
    1171                 :                                               principal,
    1172                 :                                               nsIXPConnect::
    1173                 :                                                   FLAG_SYSTEM_GLOBAL_OBJECT,
    1174               0 :                                               getter_AddRefs(holder));
    1175               0 :     if (NS_FAILED(rv)) {
    1176               0 :         NS_ERROR("InitClassesWithNewWrappedGlobal failed!");
    1177               0 :         return false;
    1178                 :     }
    1179                 : 
    1180                 :     JSObject *globalObj;
    1181               0 :     rv = holder->GetJSObject(&globalObj);
    1182               0 :     if (NS_FAILED(rv)) {
    1183               0 :         NS_ERROR("Failed to get global JSObject!");
    1184               0 :         return false;
    1185                 :     }
    1186                 : 
    1187                 : 
    1188                 :     {
    1189               0 :         JSAutoRequest ar(cx);
    1190                 : 
    1191               0 :         JSAutoEnterCompartment ac;
    1192               0 :         if (!ac.enter(cx, globalObj)) {
    1193               0 :             NS_ERROR("Failed to enter compartment!");
    1194               0 :             return false;
    1195                 :         }
    1196                 : 
    1197               0 :         if (!JS_DefineFunctions(cx, globalObj, gGlobalFunctions) ||
    1198               0 :             !JS_DefineProfilingFunctions(cx, globalObj)) {
    1199               0 :             NS_ERROR("JS_DefineFunctions failed!");
    1200               0 :             return false;
    1201                 :         }
    1202                 :     }
    1203                 : 
    1204               0 :     mGlobalHolder = globalObj;
    1205                 : 
    1206               0 :     FILE* runtimeScriptFile = fopen(kDefaultRuntimeScriptFilename, "r");
    1207               0 :     if (runtimeScriptFile) {
    1208               0 :         fprintf(stdout, "[loading '%s'...]\n", kDefaultRuntimeScriptFilename);
    1209                 :         ProcessFile(cx, globalObj, kDefaultRuntimeScriptFilename,
    1210               0 :                     runtimeScriptFile, JS_FALSE);
    1211               0 :         fclose(runtimeScriptFile);
    1212                 :     }
    1213                 : 
    1214               0 :     return true;
    1215                 : }
    1216                 : 
    1217                 : bool
    1218               0 : XPCShellEnvironment::EvaluateString(const nsString& aString,
    1219                 :                                     nsString* aResult)
    1220                 : {
    1221               0 :   XPCShellEnvironment* env = Environment(mCx);
    1222               0 :   XPCShellEnvironment::AutoContextPusher pusher(env);
    1223                 : 
    1224               0 :   JSAutoRequest ar(mCx);
    1225                 : 
    1226               0 :   JS_ClearPendingException(mCx);
    1227                 : 
    1228               0 :   JSObject* global = GetGlobalObject();
    1229                 : 
    1230               0 :   JSAutoEnterCompartment ac;
    1231               0 :   if (!ac.enter(mCx, global)) {
    1232               0 :       NS_ERROR("Failed to enter compartment!");
    1233               0 :       return false;
    1234                 :   }
    1235                 : 
    1236                 :   JSScript* script =
    1237                 :       JS_CompileUCScriptForPrincipals(mCx, global, GetPrincipal(),
    1238                 :                                       aString.get(), aString.Length(),
    1239               0 :                                       "typein", 0);
    1240               0 :   if (!script) {
    1241               0 :      return false;
    1242                 :   }
    1243                 : 
    1244               0 :   if (!ShouldCompileOnly()) {
    1245               0 :       if (aResult) {
    1246               0 :           aResult->Truncate();
    1247                 :       }
    1248                 : 
    1249                 :       jsval result;
    1250               0 :       JSBool ok = JS_ExecuteScript(mCx, global, script, &result);
    1251               0 :       if (ok && result != JSVAL_VOID) {
    1252               0 :           JSErrorReporter old = JS_SetErrorReporter(mCx, NULL);
    1253               0 :           JSString* str = JS_ValueToString(mCx, result);
    1254               0 :           nsDependentJSString depStr;
    1255               0 :           if (str)
    1256               0 :               depStr.init(mCx, str);
    1257               0 :           JS_SetErrorReporter(mCx, old);
    1258                 : 
    1259               0 :           if (!depStr.IsEmpty() && aResult) {
    1260               0 :               aResult->Assign(depStr);
    1261                 :           }
    1262                 :       }
    1263                 :   }
    1264                 : 
    1265               0 :   return true;
    1266                 : }

Generated by: LCOV version 1.7