LCOV - code coverage report
Current view: directory - js/src/jsapi-tests - testXDR.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 136 124 91.2 %
Date: 2012-06-02 Functions: 30 25 83.3 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: set ts=8 sw=4 et tw=99:
       3                 :  */
       4                 : 
       5                 : #include "tests.h"
       6                 : #include "jsscript.h"
       7                 : #include "jsxdrapi.h"
       8                 : 
       9                 : static JSScript *
      10              18 : CompileScriptForPrincipalsVersionOrigin(JSContext *cx, JSObject *obj,
      11                 :                                         JSPrincipals *principals, JSPrincipals *originPrincipals,
      12                 :                                         const char *bytes, size_t nbytes,
      13                 :                                         const char *filename, unsigned lineno,
      14                 :                                         JSVersion version)
      15                 : {
      16                 :     size_t nchars;
      17              18 :     if (!JS_DecodeBytes(cx, bytes, nbytes, NULL, &nchars))
      18               0 :         return NULL;
      19              18 :     jschar *chars = static_cast<jschar *>(JS_malloc(cx, nchars * sizeof(jschar)));
      20              18 :     if (!chars)
      21               0 :         return NULL;
      22              18 :     JS_ALWAYS_TRUE(JS_DecodeBytes(cx, bytes, nbytes, chars, &nchars));
      23                 :     JSScript *script = JS_CompileUCScriptForPrincipalsVersionOrigin(cx, obj,
      24                 :                                                                     principals, originPrincipals,
      25                 :                                                                     chars, nchars,
      26              18 :                                                                     filename, lineno, version);
      27              18 :     free(chars);
      28              18 :     return script;
      29                 : }
      30                 : 
      31                 : template<typename T>
      32                 : T *
      33              21 : FreezeThawImpl(JSContext *cx, T *thing, JSBool (*xdrAction)(JSXDRState *xdr, T **))
      34                 : {
      35                 :     // freeze
      36              21 :     JSXDRState *w = JS_XDRNewMem(cx, JSXDR_ENCODE);
      37              21 :     if (!w)
      38               0 :         return NULL;
      39                 : 
      40              21 :     void *memory = NULL;
      41                 :     uint32_t nbytes;
      42              21 :     if (xdrAction(w, &thing)) {
      43              21 :         void *p = JS_XDRMemGetData(w, &nbytes);
      44              21 :         if (p) {
      45              21 :             memory = JS_malloc(cx, nbytes);
      46              21 :             if (memory)
      47              21 :                 memcpy(memory, p, nbytes);
      48                 :         }
      49                 :     }
      50              21 :     JS_XDRDestroy(w);
      51              21 :     if (!memory)
      52               0 :         return NULL;
      53                 : 
      54                 :     // thaw
      55              21 :     JSXDRState *r = JS_XDRNewMem(cx, JSXDR_DECODE);
      56              21 :     JS_XDRMemSetData(r, memory, nbytes);
      57              21 :     if (!xdrAction(r, &thing))
      58               0 :         thing = NULL;
      59              21 :     JS_XDRDestroy(r);  // this frees `memory
      60              21 :     return thing;
      61                 : }
      62                 : 
      63                 : static JSScript *
      64              15 : FreezeThaw(JSContext *cx, JSScript *script)
      65                 : {
      66              15 :     return FreezeThawImpl(cx, script, JS_XDRScript);
      67                 : }
      68                 : 
      69                 : static JSObject *
      70               6 : FreezeThaw(JSContext *cx, JSObject *funobj)
      71                 : {
      72               6 :     return FreezeThawImpl(cx, funobj, JS_XDRFunctionObject);
      73                 : }
      74                 : 
      75                 : static JSPrincipals testPrincipals[] = {
      76                 :     { 1 },
      77                 :     { 1 },
      78                 : };
      79                 : 
      80                 : static JSBool
      81              30 : TranscodePrincipals(JSXDRState *xdr, JSPrincipals **principalsp)
      82                 : {
      83                 :     uint32_t index;
      84              30 :     if (xdr->mode == JSXDR_ENCODE) {
      85              15 :         JSPrincipals *p = *principalsp;
      86              21 :         for (index = 0; ; ++index) {
      87              21 :             if (index == mozilla::ArrayLength(testPrincipals))
      88               0 :                 return false;
      89              21 :             if (p == &testPrincipals[index])
      90                 :                 break;
      91                 :         }
      92                 :     }
      93                 : 
      94              30 :     if (!JS_XDRUint32(xdr, &index))
      95               0 :         return false;
      96                 : 
      97              30 :     if (xdr->mode == JSXDR_DECODE) {
      98              15 :         if (index >= mozilla::ArrayLength(testPrincipals))
      99               0 :             return false;
     100              15 :         *principalsp = &testPrincipals[index];
     101              15 :         JS_HoldPrincipals(*principalsp);
     102                 :     }
     103                 : 
     104              30 :     return true;
     105                 : }
     106                 : 
     107               4 : BEGIN_TEST(testXDR_principals)
     108                 : {
     109                 :     static const JSSecurityCallbacks seccb = {
     110                 :         NULL,
     111                 :         NULL,
     112                 :         TranscodePrincipals,
     113                 :         NULL,
     114                 :         NULL
     115                 :     };
     116                 : 
     117               1 :     JS_SetSecurityCallbacks(rt, &seccb);
     118                 : 
     119                 :     JSScript *script;
     120               4 :     for (int i = TEST_FIRST; i != TEST_END; ++i) {
     121               3 :         script = createScriptViaXDR(NULL, NULL, i);
     122               3 :         CHECK(script);
     123               3 :         CHECK(!JS_GetScriptPrincipals(cx, script));
     124               3 :         CHECK(!JS_GetScriptOriginPrincipals(cx, script));
     125                 :     
     126               3 :         script = createScriptViaXDR(NULL, NULL, i);
     127               3 :         CHECK(script);
     128               3 :         CHECK(!JS_GetScriptPrincipals(cx, script));
     129               3 :         CHECK(!JS_GetScriptOriginPrincipals(cx, script));
     130                 :         
     131               3 :         script = createScriptViaXDR(&testPrincipals[0], NULL, i);
     132               3 :         CHECK(script);
     133               3 :         CHECK(JS_GetScriptPrincipals(cx, script) == &testPrincipals[0]);
     134               3 :         CHECK(JS_GetScriptOriginPrincipals(cx, script) == &testPrincipals[0]);
     135                 :         
     136               3 :         script = createScriptViaXDR(&testPrincipals[0], &testPrincipals[0], i);
     137               3 :         CHECK(script);
     138               3 :         CHECK(JS_GetScriptPrincipals(cx, script) == &testPrincipals[0]);
     139               3 :         CHECK(JS_GetScriptOriginPrincipals(cx, script) == &testPrincipals[0]);
     140                 :         
     141               3 :         script = createScriptViaXDR(&testPrincipals[0], &testPrincipals[1], i);
     142               3 :         CHECK(script);
     143               3 :         CHECK(JS_GetScriptPrincipals(cx, script) == &testPrincipals[0]);
     144               3 :         CHECK(JS_GetScriptOriginPrincipals(cx, script) == &testPrincipals[1]);
     145                 :         
     146               3 :         script = createScriptViaXDR(NULL, &testPrincipals[1], i);
     147               3 :         CHECK(script);
     148               3 :         CHECK(!JS_GetScriptPrincipals(cx, script));
     149               3 :         CHECK(JS_GetScriptOriginPrincipals(cx, script) == &testPrincipals[1]);
     150                 :     }
     151                 : 
     152               1 :     return true;
     153                 : }
     154                 : 
     155                 : enum TestCase {
     156                 :     TEST_FIRST,
     157                 :     TEST_SCRIPT = TEST_FIRST,
     158                 :     TEST_FUNCTION,
     159                 :     TEST_SERIALIZED_FUNCTION,
     160                 :     TEST_END
     161                 : };
     162                 : 
     163              18 : JSScript *createScriptViaXDR(JSPrincipals *prin, JSPrincipals *orig, int testCase)
     164                 : {
     165                 :     const char src[] =
     166                 :         "function f() { return 1; }\n"
     167              18 :         "f;\n";
     168                 : 
     169                 :     JSScript *script = CompileScriptForPrincipalsVersionOrigin(cx, global, prin, orig,
     170                 :                                                                src, strlen(src), "test", 1,
     171              18 :                                                                JSVERSION_DEFAULT);
     172              18 :     if (!script)
     173               0 :         return NULL;
     174                 : 
     175              18 :     if (testCase == TEST_SCRIPT || testCase == TEST_SERIALIZED_FUNCTION) {
     176              12 :         script = FreezeThaw(cx, script);
     177              12 :         if (!script)
     178               0 :             return NULL;
     179              12 :         if (testCase == TEST_SCRIPT)
     180               6 :             return script;
     181                 :     }
     182                 : 
     183                 :     JS::Value v;
     184              12 :     JSBool ok = JS_ExecuteScript(cx, global, script, &v);
     185              12 :     if (!ok || !v.isObject())
     186               0 :         return NULL;
     187              12 :     JSObject *funobj = &v.toObject();
     188              12 :     if (testCase == TEST_FUNCTION) {
     189               6 :         funobj = FreezeThaw(cx, funobj);
     190               6 :         if (!funobj)
     191               0 :             return NULL;
     192                 :     }
     193              12 :     return JS_GetFunctionScript(cx, JS_GetObjectFunction(funobj));
     194                 : }
     195                 : 
     196               1 : END_TEST(testXDR_principals)
     197                 : 
     198               4 : BEGIN_TEST(testXDR_atline)
     199                 : {
     200               1 :     JS_ToggleOptions(cx, JSOPTION_ATLINE);
     201               1 :     CHECK(JS_GetOptions(cx) & JSOPTION_ATLINE);
     202                 : 
     203                 :     const char src[] =
     204                 : "//@line 100 \"foo\"\n"
     205                 : "function nested() { }\n"
     206                 : "//@line 200 \"bar\"\n"
     207               1 : "nested;\n";
     208                 : 
     209               1 :     JSScript *script = JS_CompileScript(cx, global, src, strlen(src), "internal", 1);
     210               1 :     CHECK(script);
     211               1 :     CHECK(script = FreezeThaw(cx, script));
     212               1 :     CHECK(!strcmp("bar", JS_GetScriptFilename(cx, script)));
     213                 :     
     214                 :     JS::Value v;
     215               1 :     JSBool ok = JS_ExecuteScript(cx, global, script, &v);
     216               1 :     CHECK(ok);
     217               1 :     CHECK(v.isObject());
     218                 : 
     219               1 :     JSObject *funobj = &v.toObject();
     220               1 :     script = JS_GetFunctionScript(cx, JS_GetObjectFunction(funobj));
     221               1 :     CHECK(!strcmp("foo", JS_GetScriptFilename(cx, script)));
     222                 : 
     223               1 :     return true;
     224                 : }
     225                 : 
     226               1 : END_TEST(testXDR_atline)
     227                 : 
     228               4 : BEGIN_TEST(testXDR_bug506491)
     229                 : {
     230                 :     const char *s =
     231                 :         "function makeClosure(s, name, value) {\n"
     232                 :         "    eval(s);\n"
     233                 :         "    return let (n = name, v = value) function () { return String(v); };\n"
     234                 :         "}\n"
     235               1 :         "var f = makeClosure('0;', 'status', 'ok');\n";
     236                 : 
     237                 :     // compile
     238               1 :     JSScript *script = JS_CompileScript(cx, global, s, strlen(s), __FILE__, __LINE__);
     239               1 :     CHECK(script);
     240                 : 
     241               1 :     script = FreezeThaw(cx, script);
     242               1 :     CHECK(script);
     243                 : 
     244                 :     // execute
     245               2 :     jsvalRoot v2(cx);
     246               1 :     CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
     247                 : 
     248                 :     // try to break the Block object that is the parent of f
     249               1 :     JS_GC(cx);
     250                 : 
     251                 :     // confirm
     252               1 :     EVAL("f() === 'ok';\n", v2.addr());
     253               2 :     jsvalRoot trueval(cx, JSVAL_TRUE);
     254               1 :     CHECK_SAME(v2, trueval);
     255               1 :     return true;
     256                 : }
     257               1 : END_TEST(testXDR_bug506491)
     258                 : 
     259               4 : BEGIN_TEST(testXDR_bug516827)
     260                 : {
     261                 :     // compile an empty script
     262               1 :     JSScript *script = JS_CompileScript(cx, global, "", 0, __FILE__, __LINE__);
     263               1 :     CHECK(script);
     264                 : 
     265               1 :     script = FreezeThaw(cx, script);
     266               1 :     CHECK(script);
     267                 : 
     268                 :     // execute with null result meaning no result wanted
     269               1 :     CHECK(JS_ExecuteScript(cx, global, script, NULL));
     270               1 :     return true;
     271                 : }
     272               3 : END_TEST(testXDR_bug516827)

Generated by: LCOV version 1.7