js/jsd/jsd_hook.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /*
     8  * JavaScript Debugging support - Hook support
     9  */
    11 #include "jsd.h"
    13 JSTrapStatus
    14 jsd_InterruptHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
    15                      void *closure)
    16 {
    17     JSDScript*      jsdscript;
    18     JSDContext*     jsdc = (JSDContext*) closure;
    19     JSD_ExecutionHookProc hook;
    20     void*                 hookData;
    22     if( ! jsdc || ! jsdc->inited )
    23         return JSTRAP_CONTINUE;
    25     if( JSD_IS_DANGEROUS_THREAD(jsdc) )
    26         return JSTRAP_CONTINUE;
    28     /* local in case jsdc->interruptHook gets cleared on another thread */
    29     JSD_LOCK();
    30     hook     = jsdc->interruptHook;
    31     hookData = jsdc->interruptHookData;
    32     JSD_UNLOCK();
    34     if (!hook)
    35         return JSTRAP_CONTINUE;
    37     JSD_LOCK_SCRIPTS(jsdc);
    38     jsdscript = jsd_FindOrCreateJSDScript(jsdc, cx, script, JSNullFramePtr());
    39     JSD_UNLOCK_SCRIPTS(jsdc);
    40     if( ! jsdscript )
    41         return JSTRAP_CONTINUE;
    43     return jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_INTERRUPTED,
    44                                  hook, hookData, rval);
    45 }
    47 JSTrapStatus
    48 jsd_DebuggerHandler(JSContext *cx, JSScript *script, jsbytecode *pc,
    49                     jsval *rval, void *closure)
    50 {
    51     JSDScript*      jsdscript;
    52     JSDContext*     jsdc = (JSDContext*) closure;
    53     JSD_ExecutionHookProc hook;
    54     void*                 hookData;
    56     if( ! jsdc || ! jsdc->inited )
    57         return JSTRAP_CONTINUE;
    59     if( JSD_IS_DANGEROUS_THREAD(jsdc) )
    60         return JSTRAP_CONTINUE;
    62     /* local in case jsdc->debuggerHook gets cleared on another thread */
    63     JSD_LOCK();
    64     hook     = jsdc->debuggerHook;
    65     hookData = jsdc->debuggerHookData;
    66     JSD_UNLOCK();
    67     if(!hook)
    68         return JSTRAP_CONTINUE;
    70     JSD_LOCK_SCRIPTS(jsdc);
    71     jsdscript = jsd_FindOrCreateJSDScript(jsdc, cx, script, JSNullFramePtr());
    72     JSD_UNLOCK_SCRIPTS(jsdc);
    73     if( ! jsdscript )
    74         return JSTRAP_CONTINUE;
    76     return jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_DEBUGGER_KEYWORD,
    77                                  hook, hookData, rval);
    78 }
    81 JSTrapStatus
    82 jsd_ThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc,
    83                  jsval *rvalArg, void *closure)
    84 {
    85     JSDScript*      jsdscript;
    86     JSDContext*     jsdc = (JSDContext*) closure;
    87     JSD_ExecutionHookProc hook;
    88     void*                 hookData;
    90     if( ! jsdc || ! jsdc->inited )
    91         return JSTRAP_CONTINUE;
    93     if( JSD_IS_DANGEROUS_THREAD(jsdc) )
    94         return JSTRAP_CONTINUE;
    96     /* local in case jsdc->throwHook gets cleared on another thread */
    97     JSD_LOCK();
    98     hook     = jsdc->throwHook;
    99     hookData = jsdc->throwHookData;
   100     JSD_UNLOCK();
   101     if (!hook)
   102         return JSTRAP_CONTINUE;
   104     JSD_LOCK_SCRIPTS(jsdc);
   105     jsdscript = jsd_FindOrCreateJSDScript(jsdc, cx, script, JSNullFramePtr());
   106     JSD_UNLOCK_SCRIPTS(jsdc);
   107     if( ! jsdscript )
   108         return JSTRAP_CONTINUE;
   110     JS::RootedValue rval(cx);
   111     JS_GetPendingException(cx, &rval);
   113     JSTrapStatus result = jsd_CallExecutionHook(jsdc, cx, JSD_HOOK_THROW,
   114                                                 hook, hookData, rval.address());
   115     *rvalArg = rval;
   116     return result;
   117 }
   119 JSTrapStatus
   120 jsd_CallExecutionHook(JSDContext* jsdc,
   121                       JSContext *cx,
   122                       unsigned type,
   123                       JSD_ExecutionHookProc hook,
   124                       void* hookData,
   125                       jsval* rval)
   126 {
   127     unsigned hookanswer = JSD_HOOK_THROW == type ? 
   128                             JSD_HOOK_RETURN_CONTINUE_THROW :
   129                             JSD_HOOK_RETURN_CONTINUE;
   130     JSDThreadState* jsdthreadstate;
   132     if(hook && nullptr != (jsdthreadstate = jsd_NewThreadState(jsdc, cx)))
   133     {
   134         if ((type != JSD_HOOK_THROW && type != JSD_HOOK_INTERRUPTED) ||
   135             jsdc->flags & JSD_MASK_TOP_FRAME_ONLY ||
   136             !(jsdthreadstate->flags & TS_HAS_DISABLED_FRAME))
   137         {
   138             /*
   139              * if it's not a throw and it's not an interrupt,
   140              * or we're only masking the top frame,
   141              * or there are no disabled frames in this stack,
   142              * then call out.
   143              */
   144              hookanswer = hook(jsdc, jsdthreadstate, type, hookData, rval);
   145              jsd_DestroyThreadState(jsdc, jsdthreadstate);
   146         }
   147     }
   149     switch(hookanswer)
   150     {
   151         case JSD_HOOK_RETURN_ABORT:
   152         case JSD_HOOK_RETURN_HOOK_ERROR:
   153             return JSTRAP_ERROR;
   154         case JSD_HOOK_RETURN_RET_WITH_VAL:
   155             return JSTRAP_RETURN;
   156         case JSD_HOOK_RETURN_THROW_WITH_VAL:
   157             return JSTRAP_THROW;
   158         case JSD_HOOK_RETURN_CONTINUE:
   159             break;
   160         case JSD_HOOK_RETURN_CONTINUE_THROW:
   161             /* only makes sense for jsd_ThrowHandler (which init'd rval) */
   162             MOZ_ASSERT(JSD_HOOK_THROW == type);
   163             return JSTRAP_THROW;
   164         default:
   165             MOZ_ASSERT(0);
   166             break;
   167     }
   168     return JSTRAP_CONTINUE;
   169 }
   171 bool
   172 jsd_CallCallHook (JSDContext* jsdc,
   173                   JSContext *cx,
   174                   unsigned type,
   175                   JSD_CallHookProc hook,
   176                   void* hookData)
   177 {
   178     bool hookanswer;
   179     JSDThreadState*  jsdthreadstate;
   181     hookanswer = false;
   182     if(hook && nullptr != (jsdthreadstate = jsd_NewThreadState(jsdc, cx)))
   183     {
   184         hookanswer = hook(jsdc, jsdthreadstate, type, hookData);
   185         jsd_DestroyThreadState(jsdc, jsdthreadstate);
   186     }
   188     return hookanswer;
   189 }
   191 bool
   192 jsd_SetInterruptHook(JSDContext*           jsdc,
   193                      JSD_ExecutionHookProc hook,
   194                      void*                 callerdata)
   195 {
   196     JSD_LOCK();
   197     jsdc->interruptHookData  = callerdata;
   198     jsdc->interruptHook      = hook;
   199     JS_SetInterrupt(jsdc->jsrt, jsd_InterruptHandler, (void*) jsdc);
   200     JSD_UNLOCK();
   202     return true;
   203 }
   205 bool
   206 jsd_ClearInterruptHook(JSDContext* jsdc)
   207 {
   208     JSD_LOCK();
   209     JS_ClearInterrupt(jsdc->jsrt, nullptr, nullptr);
   210     jsdc->interruptHook      = nullptr;
   211     JSD_UNLOCK();
   213     return true;
   214 }
   216 bool
   217 jsd_SetDebugBreakHook(JSDContext*           jsdc,
   218                       JSD_ExecutionHookProc hook,
   219                       void*                 callerdata)
   220 {
   221     JSD_LOCK();
   222     jsdc->debugBreakHookData  = callerdata;
   223     jsdc->debugBreakHook      = hook;
   224     JSD_UNLOCK();
   226     return true;
   227 }
   229 bool
   230 jsd_ClearDebugBreakHook(JSDContext* jsdc)
   231 {
   232     JSD_LOCK();
   233     jsdc->debugBreakHook      = nullptr;
   234     JSD_UNLOCK();
   236     return true;
   237 }
   239 bool
   240 jsd_SetDebuggerHook(JSDContext*           jsdc,
   241                       JSD_ExecutionHookProc hook,
   242                       void*                 callerdata)
   243 {
   244     JSD_LOCK();
   245     jsdc->debuggerHookData  = callerdata;
   246     jsdc->debuggerHook      = hook;
   247     JSD_UNLOCK();
   249     return true;
   250 }
   252 bool
   253 jsd_ClearDebuggerHook(JSDContext* jsdc)
   254 {
   255     JSD_LOCK();
   256     jsdc->debuggerHook      = nullptr;
   257     JSD_UNLOCK();
   259     return true;
   260 }
   262 bool
   263 jsd_SetThrowHook(JSDContext*           jsdc,
   264                  JSD_ExecutionHookProc hook,
   265                  void*                 callerdata)
   266 {
   267     JSD_LOCK();
   268     jsdc->throwHookData  = callerdata;
   269     jsdc->throwHook      = hook;
   270     JSD_UNLOCK();
   272     return true;
   273 }
   275 bool
   276 jsd_ClearThrowHook(JSDContext* jsdc)
   277 {
   278     JSD_LOCK();
   279     jsdc->throwHook      = nullptr;
   280     JSD_UNLOCK();
   282     return true;
   283 }
   285 bool
   286 jsd_SetFunctionHook(JSDContext*      jsdc,
   287                     JSD_CallHookProc hook,
   288                     void*            callerdata)
   289 {
   290     JSD_LOCK();
   291     jsdc->functionHookData  = callerdata;
   292     jsdc->functionHook      = hook;
   293     JSD_UNLOCK();
   295     return true;
   296 }
   298 bool
   299 jsd_ClearFunctionHook(JSDContext* jsdc)
   300 {
   301     JSD_LOCK();
   302     jsdc->functionHook      = nullptr;
   303     JSD_UNLOCK();
   305     return true;
   306 }
   308 bool
   309 jsd_SetTopLevelHook(JSDContext*      jsdc,
   310                     JSD_CallHookProc hook,
   311                     void*            callerdata)
   312 {
   313     JSD_LOCK();
   314     jsdc->toplevelHookData  = callerdata;
   315     jsdc->toplevelHook      = hook;
   316     JSD_UNLOCK();
   318     return true;
   319 }
   321 bool
   322 jsd_ClearTopLevelHook(JSDContext* jsdc)
   323 {
   324     JSD_LOCK();
   325     jsdc->toplevelHook      = nullptr;
   326     JSD_UNLOCK();
   328     return true;
   329 }

mercurial