tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

NoExecute.cpp (3175B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      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/. */
      6 
      7 #include "debugger/NoExecute.h"
      8 
      9 #include "mozilla/Sprintf.h"  // for SprintfLiteral
     10 
     11 #include <stdio.h>  // for fprintf, stdout
     12 
     13 #include "debugger/Debugger.h"        // for Debugger
     14 #include "js/friend/DumpFunctions.h"  // for DumpBacktrace
     15 #include "js/friend/ErrorMessages.h"  // for GetErrorMessage, JSMSG_DEBUGGEE_WOULD_RUN
     16 #include "js/Promise.h"               // for AutoDebuggerJobQueueInterruption
     17 #include "js/RootingAPI.h"            // for Handle
     18 #include "vm/JSContext.h"             // for ProtectedDataContextArg, JSContext
     19 #include "vm/JSScript.h"              // for JSScript
     20 #include "vm/Realm.h"                 // for AutoRealm, Realm
     21 #include "vm/Warnings.h"              // for WarnNumberUTF8
     22 
     23 #include "gc/StableCellHasher-inl.h"
     24 #include "vm/Realm-inl.h"  // for AutoRealm::AutoRealm
     25 
     26 using namespace js;
     27 
     28 EnterDebuggeeNoExecute::EnterDebuggeeNoExecute(
     29    JSContext* cx, Debugger& dbg,
     30    const JS::AutoDebuggerJobQueueInterruption& adjqiProof)
     31    : dbg_(dbg), unlocked_(nullptr), reported_(false) {
     32  MOZ_ASSERT(adjqiProof.initialized());
     33  stack_ = &cx->noExecuteDebuggerTop.ref();
     34  prev_ = *stack_;
     35  *stack_ = this;
     36 }
     37 
     38 #ifdef DEBUG
     39 /* static */
     40 bool EnterDebuggeeNoExecute::isLockedInStack(JSContext* cx, Debugger& dbg) {
     41  for (EnterDebuggeeNoExecute* it = cx->noExecuteDebuggerTop; it;
     42       it = it->prev_) {
     43    if (&it->debugger() == &dbg) {
     44      return !it->unlocked_;
     45    }
     46  }
     47  return false;
     48 }
     49 #endif
     50 
     51 /* static */
     52 EnterDebuggeeNoExecute* EnterDebuggeeNoExecute::findInStack(JSContext* cx) {
     53  Realm* debuggee = cx->realm();
     54  for (EnterDebuggeeNoExecute* it = cx->noExecuteDebuggerTop; it;
     55       it = it->prev_) {
     56    Debugger& dbg = it->debugger();
     57    if (!it->unlocked_ && dbg.observesGlobal(debuggee->maybeGlobal())) {
     58      return it;
     59    }
     60  }
     61  return nullptr;
     62 }
     63 
     64 /* static */
     65 bool EnterDebuggeeNoExecute::reportIfFoundInStack(JSContext* cx,
     66                                                  HandleScript script) {
     67  if (EnterDebuggeeNoExecute* nx = findInStack(cx)) {
     68    bool warning = !cx->options().throwOnDebuggeeWouldRun();
     69    if (!warning || !nx->reported_) {
     70      AutoRealm ar(cx, nx->debugger().toJSObject());
     71      nx->reported_ = true;
     72      if (cx->options().dumpStackOnDebuggeeWouldRun()) {
     73        fprintf(stdout, "Dumping stack for DebuggeeWouldRun:\n");
     74        DumpBacktrace(cx);
     75      }
     76      const char* filename = script->filename() ? script->filename() : "(none)";
     77      char linenoStr[15];
     78      SprintfLiteral(linenoStr, "%u", script->lineno());
     79      if (warning) {
     80        return WarnNumberUTF8(cx, JSMSG_DEBUGGEE_WOULD_RUN, filename,
     81                              linenoStr);
     82      }
     83 
     84      JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
     85                               JSMSG_DEBUGGEE_WOULD_RUN, filename, linenoStr);
     86      return false;
     87    }
     88  }
     89  return true;
     90 }