Esempio n. 1
0
bool CThreadDebugger::CurrentFrameIsChildOf(JSStackFrame* pParentFrame)
{
	JSStackFrame* iter = NULL;
	JSStackFrame* fp = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);
	// Get the first parent Frame
	fp = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);
	while (fp)
	{
		if (fp == pParentFrame) 
			return true;
		fp = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);
	}
	return false;
}
Esempio n. 2
0
nsresult
XPCJSStackFrame::CreateStack(JSContext* cx, JSStackFrame* fp,
                             XPCJSStackFrame** stack)
{
    static const unsigned MAX_FRAMES = 100;
    unsigned numFrames = 0;

    nsRefPtr<XPCJSStackFrame> first = new XPCJSStackFrame();
    nsRefPtr<XPCJSStackFrame> self = first;
    while (fp && self) {
        if (!JS_IsScriptFrame(cx, fp)) {
            self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS;
        } else {
            self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT;
            JSScript* script = JS_GetFrameScript(cx, fp);
            jsbytecode* pc = JS_GetFramePC(cx, fp);
            if (script && pc) {
                JS::AutoEnterFrameCompartment ac;
                if (ac.enter(cx, fp)) {
                    const char* filename = JS_GetScriptFilename(cx, script);
                    if (filename) {
                        self->mFilename = (char*)
                            nsMemory::Clone(filename,
                                            sizeof(char)*(strlen(filename)+1));
                    }

                    self->mLineno = (int32_t) JS_PCToLineNumber(cx, script, pc);

                    JSFunction* fun = JS_GetFrameFunction(cx, fp);
                    if (fun) {
                        JSString *funid = JS_GetFunctionId(fun);
                        if (funid) {
                            size_t length = JS_GetStringEncodingLength(cx, funid);
                            if (length != size_t(-1)) {
                                self->mFunname = static_cast<char *>(nsMemory::Alloc(length + 1));
                                if (self->mFunname) {
                                    JS_EncodeStringToBuffer(funid, self->mFunname, length);
                                    self->mFunname[length] = '\0';
                                }
                            }
                        }
                    }
                }
            } else {
                self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS;
            }
        }

        if (++numFrames > MAX_FRAMES) {
            fp = NULL;
        } else if (JS_FrameIterator(cx, &fp)) {
            XPCJSStackFrame* frame = new XPCJSStackFrame();
            self->mCaller = frame;
            self = frame;
        }
    }

    *stack = first.forget().get();
    return NS_OK;
}
Esempio n. 3
0
void
gjs_context_print_stack_to_buffer(GjsContext* context, void *initial, GString *buf)
{
    JSContext *js_context = (JSContext*)gjs_context_get_native_context(context);
    JSStackFrame *fp = initial;
    int num = 0;

    if (fp == NULL)
        JS_FrameIterator(js_context, &fp);

    while (fp) {
        format_frame(js_context, fp, buf, num);
        num++;

	JS_FrameIterator(js_context, &fp);
    }
}
Esempio n. 4
0
void CThreadDebugger::SaveStackFrameData(STACK_INFO stackInfo, uint nestingLevel)
{
	ENSURE(GetIsInBreak());
	
	CScopeLock lock(m->m_Mutex);
	JSStackFrame *fp;
	JSStackFrame *iter = 0;
	uint counter = 0;
	jsval val;
	
	if (stackInfo == STACK_INFO_GLOBALOBJECT)
	{
		JSObject* obj;
		obj = JS_GetGlobalForScopeChain(m->m_pScriptInterface->GetContext());
		m->m_StackFrameData[stackInfo][nestingLevel] = StringifyCyclicJSON(OBJECT_TO_JSVAL(obj), false);
	}
	else
	{
		fp = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);
		while (fp)
		{
			if (counter == nestingLevel)
			{
				if (stackInfo == STACK_INFO_LOCALS)
				{
					JSObject* obj;
					obj = JS_GetFrameCallObject(m->m_pScriptInterface->GetContext(), fp);
					//obj = JS_GetFrameScopeChain(m->m_pScriptInterface->GetContext(), fp);
					m->m_StackFrameData[stackInfo][nestingLevel] = StringifyCyclicJSON(OBJECT_TO_JSVAL(obj), false);
				}
				else if (stackInfo == STACK_INFO_THIS)
				{
					if (JS_GetFrameThis(m->m_pScriptInterface->GetContext(), fp, &val))
						m->m_StackFrameData[stackInfo][nestingLevel] = StringifyCyclicJSON(val, false);
					else
						m->m_StackFrameData[stackInfo][nestingLevel] = "";
				}
			}
			
			counter++;
			fp = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);
		}
	}
}
Esempio n. 5
0
nsresult
XPCJSStack::CreateStack(JSContext* cx, nsIStackFrame** stack)
{
    if (!cx)
        return NS_ERROR_FAILURE;

    JSStackFrame *fp = NULL;
    if (!JS_FrameIterator(cx, &fp))
        return NS_ERROR_FAILURE;
    return XPCJSStackFrame::CreateStack(cx, fp, (XPCJSStackFrame**) stack);
}
Esempio n. 6
0
void CThreadDebugger::SaveCallstack()
{
	ENSURE(GetIsInBreak());
	
	CScopeLock lock(m->m_Mutex);
	
	JSStackFrame *fp;
	JSStackFrame *iter = 0;
	std::string functionName;
	jsint counter = 0;
	
	JSObject* jsArray;
	jsArray = JS_NewArrayObject(m->m_pScriptInterface->GetContext(), 0, 0);
	JSString* functionID;

	fp = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);

	while (fp)
	{
		JSFunction* fun = 0;
		fun = JS_GetFrameFunction(m->m_pScriptInterface->GetContext(), fp);
		if (NULL == fun)
			functionID = JS_NewStringCopyZ(m->m_pScriptInterface->GetContext(), "null");
		else
		{
			functionID = JS_GetFunctionId(fun);
			if (NULL == functionID)
				functionID = JS_NewStringCopyZ(m->m_pScriptInterface->GetContext(), "anonymous");
		}

		JSBool ret = JS_DefineElement(m->m_pScriptInterface->GetContext(), jsArray, counter, STRING_TO_JSVAL(functionID), NULL, NULL, 0);
		ENSURE(ret);
		fp = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);
		counter++;
	}
	
	m->m_Callstack = "";
	m->m_Callstack = m->m_pScriptInterface->StringifyJSON(OBJECT_TO_JSVAL(jsArray), false).c_str();
}
Esempio n. 7
0
const char*
__Core_getScriptName (JSContext* cx)
{
    JSStackFrame* fp     = NULL;
    JSScript*     script = NULL;

    do {
        fp     = JS_FrameIterator(cx, &fp);
        script = JS_GetFrameScript(cx, fp);
    } while (!script && fp);

    return JS_GetScriptFilename(cx, script);
}
Esempio n. 8
0
JSTrapStatus CThreadDebugger::StepOutHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, void* UNUSED(closure))
{
	// We break when we are in a different Frame and m_pLastBreakFrame is not a parent of the current frame 
	// (because we stepped out of the function)
	JSStackFrame* iter = NULL;
	JSStackFrame* pStackFrame;
	pStackFrame = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);
	if (pStackFrame != *m->m_pLastBreakFrame && !CurrentFrameIsChildOf(*m->m_pLastBreakFrame))
	{
		jsval val = JSVAL_VOID;
		return BreakHandler(cx, script, pc, rval, val, BREAK_SRC_INTERRUP);
	}
	else
		return JSTRAP_CONTINUE;
}
Esempio n. 9
0
JSBool
xpc_DumpEvalInJSStackFrame(JSContext* cx, JSUint32 frameno, const char* text)
{
    JSStackFrame* fp;
    JSStackFrame* iter = nsnull;
    JSUint32 num = 0;

    if(!cx || !text)
    {
        puts("invalid params passed to xpc_DumpEvalInJSStackFrame!");
        return JS_FALSE;
    }

    printf("js[%d]> %s\n", frameno, text);

    while(nsnull != (fp = JS_FrameIterator(cx, &iter)))
    {
        if(num == frameno)
            break;
        num++;
    }

    if(!fp)
    {
        puts("invalid frame number!");
        return JS_FALSE;
    }

    JSAutoRequest ar(cx);

    JSExceptionState* exceptionState = JS_SaveExceptionState(cx);
    JSErrorReporter older = JS_SetErrorReporter(cx, xpcDumpEvalErrorReporter);

    jsval rval;
    JSString* str;
    JSAutoByteString bytes;
    if(JS_EvaluateInStackFrame(cx, fp, text, strlen(text), "eval", 1, &rval) &&
       nsnull != (str = JS_ValueToString(cx, rval)) &&
       bytes.encode(cx, str))
    {
        printf("%s\n", bytes.ptr());
    }
    else
        puts("eval failed!");
    JS_SetErrorReporter(cx, older);
    JS_RestoreExceptionState(cx, exceptionState);
    return JS_TRUE;
}
Esempio n. 10
0
JSTrapStatus CThreadDebugger::StepIntoHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, void* UNUSED(closure))
{
	// We break when we are on the same stack frame but not on the same line 
	// or when we are on another stack frame.
	uint line = JS_PCToLineNumber(cx, script, pc);
	JSStackFrame* iter = NULL;
	JSStackFrame* pStackFrame;
	pStackFrame = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);
	uint lastBreakLine = GetLastBreakLine();
	
	jsval val = JSVAL_VOID;
	if ((*m->m_pLastBreakFrame == pStackFrame && lastBreakLine != line) || *m->m_pLastBreakFrame != pStackFrame)
		return BreakHandler(cx, script, pc, rval, val, BREAK_SRC_INTERRUP);
	else
		return JSTRAP_CONTINUE;
}
Esempio n. 11
0
File: gerror.c Progetto: Cobinja/cjs
/* define properties that JS Error() expose, such as
   fileName, lineNumber and stack
*/
static void
define_error_properties(JSContext *context,
                        JSObject  *obj)
{
    JSStackFrame *frame;
    JSScript *script;
    jsbytecode *pc;
    jsval v;
    GString *stack;
    const char *filename;
    GjsContext *gjs_context;

    /* find the JS frame that triggered the error */
    frame = NULL;
    while (JS_FrameIterator(context, &frame)) {
        if (JS_IsScriptFrame(context, frame))
            break;
    }

    /* someone called gjs_throw at top of the stack?
       well, no stack in that case
    */
    if (!frame)
        return;

    script = JS_GetFrameScript(context, frame);
    pc = JS_GetFramePC(context, frame);

    stack = g_string_new(NULL);
    gjs_context = JS_GetContextPrivate(context);
    gjs_context_print_stack_to_buffer(gjs_context, frame, stack);

    if (gjs_string_from_utf8(context, stack->str, stack->len, &v))
        JS_DefineProperty(context, obj, "stack", v,
                          NULL, NULL, JSPROP_ENUMERATE);

    filename = JS_GetScriptFilename(context, script);
    if (gjs_string_from_filename(context, filename, -1, &v))
        JS_DefineProperty(context, obj, "fileName", v,
                          NULL, NULL, JSPROP_ENUMERATE);

    v = INT_TO_JSVAL(JS_PCToLineNumber(context, script, pc));
    JS_DefineProperty(context, obj, "lineNumber", v,
                      NULL, NULL, JSPROP_ENUMERATE);

    g_string_free(stack, TRUE);
}
Esempio n. 12
0
static JSDObject*
_createJSDObject(JSDContext* jsdc, JSContext *cx, JSObject *obj)
{
    JSDObject* jsdobj;
    JSStackFrame* fp;
    JSStackFrame* iter = NULL;
    const char* newURL;
    jsbytecode* pc;

    JS_ASSERT(JSD_OBJECTS_LOCKED(jsdc));

    jsdobj = (JSDObject*) calloc(1, sizeof(JSDObject));
    if (jsdobj)
    {
        JS_INIT_CLIST(&jsdobj->links);
        JS_APPEND_LINK(&jsdobj->links, &jsdc->objectsList);
        jsdobj->obj = obj;
        JS_HashTableAdd(jsdc->objectsTable, obj, jsdobj);

        if (jsdc->flags & JSD_DISABLE_OBJECT_TRACE)
            return jsdobj;

        /* walk the stack to find js frame (if any) causing creation */
        while (NULL != (fp = JS_FrameIterator(cx, &iter)))
        {
            if( !JS_IsNativeFrame(cx, fp) )
            {
                JSScript* script = JS_GetFrameScript(cx, fp);
                if( !script )
                    continue;

                newURL = JS_GetScriptFilename(cx, script);
                if( newURL )
                    jsdobj->newURL = jsd_AddAtom(jsdc, newURL);

                pc = JS_GetFramePC(cx, fp);
                if( pc )
                    jsdobj->newLineno = JS_PCToLineNumber(cx, script, pc);

                break;
            }
        }
    }
    return jsdobj;
}
Esempio n. 13
0
static char* FormatJSStackDump(JSContext* cx, char* buf,
                               JSBool showArgs, JSBool showLocals,
                               JSBool showThisProps)
{
    JSStackFrame* fp;
    JSStackFrame* iter = nsnull;
    int num = 0;

    while (nsnull != (fp = JS_FrameIterator(cx, &iter))) {
        buf = FormatJSFrame(cx, fp, buf, num, showArgs, showLocals, showThisProps);
        num++;
    }

    if (!num)
        buf = JS_sprintf_append(buf, "JavaScript stack is empty\n");

    return buf;
}
Esempio n. 14
0
JSTrapStatus CThreadDebugger::StepHandler(JSContext* cx, JSScript* script, jsbytecode* pc, jsval* rval, void* UNUSED(closure))
{
	// We break in two conditions
	// 1. We are in the same frame but on a different line
	//	  Note: On loops for example, we can go a few lines up again without leaving the current stack frame, so it's not necessarily 
	//          a higher line number.
	// 2. We are in a different Frame and m_pLastBreakFrame is not a parent of the current frame (because we stepped out of the function)
	uint line = JS_PCToLineNumber(cx, script, pc);
	JSStackFrame* iter = NULL;
	JSStackFrame* pStackFrame;
	pStackFrame = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);
	uint lastBreakLine = GetLastBreakLine() ;
	jsval val = JSVAL_VOID;
	if ((*m->m_pLastBreakFrame == pStackFrame && lastBreakLine != line) || 
		(*m->m_pLastBreakFrame != pStackFrame && !CurrentFrameIsChildOf(*m->m_pLastBreakFrame)))
		return BreakHandler(cx, script, pc, rval, val, BREAK_SRC_INTERRUP);
	else
		return JSTRAP_CONTINUE;
}
Esempio n. 15
0
NS_IMETHODIMP
nsJSON::EncodeFromJSVal(JS::Value *value, JSContext *cx, nsAString &result)
{
  result.Truncate();

  // Begin a new request
  JSAutoRequest ar(cx);

  JSAutoEnterCompartment ac;
  nsIScriptSecurityManager *ssm = nsnull;
  if (value->isObject()) {
    JSObject *obj = &value->toObject();
    if (!ac.enter(cx, obj)) {
      return NS_ERROR_FAILURE;
    }

    nsCOMPtr<nsIPrincipal> principal;
    ssm = nsContentUtils::GetSecurityManager();
    nsresult rv = ssm->GetObjectPrincipal(cx, obj, getter_AddRefs(principal));
    NS_ENSURE_SUCCESS(rv, rv);

    JSStackFrame *fp = nsnull;
    rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp), principal);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  nsJSONWriter writer;
  JSBool ok = JS_Stringify(cx, value, NULL, JSVAL_NULL,
                           WriteCallback, &writer);

  if (ssm) {
    ssm->PopContextPrincipal(cx);
  }

  if (!ok) {
    return NS_ERROR_XPC_BAD_CONVERT_JS;
  }

  NS_ENSURE_TRUE(writer.DidWrite(), NS_ERROR_UNEXPECTED);
  writer.FlushBuffer();
  result.Assign(writer.mOutputString);
  return NS_OK;
}
Esempio n. 16
0
JSDScript *
jsd_FindOrCreateJSDScript(JSDContext    *jsdc,
                          JSContext     *cx,
                          JSScript      *script,
                          JSStackFrame  *fp)
{
    JSDScript *jsdscript;
    JS_ASSERT(JSD_SCRIPTS_LOCKED(jsdc));

    jsdscript = jsd_FindJSDScript(jsdc, script);
    if (jsdscript)
        return jsdscript;

    /* Fallback for unknown scripts: create a new script. */
    if (!fp)
        JS_FrameIterator(cx, &fp);
    if (fp)
        jsdscript = _newJSDScript(jsdc, cx, script);

    return jsdscript;
}
static inline
JSBool
EnsureLegalActivity(JSContext *cx, JSObject *obj)
{
  jsval flags;

  ::JS_GetReservedSlot(cx, obj, 0, &flags);
  if (HAS_FLAGS(flags, FLAG_EXPLICIT)) {
    // Can't make any assertions about the owner of this wrapper.
    return JS_TRUE;
  }

  JSStackFrame *frame = nsnull;
  uint32 fileFlags = JS_GetTopScriptFilenameFlags(cx, NULL);
  if (!JS_FrameIterator(cx, &frame) ||
      fileFlags == JSFILENAME_NULL ||
      (fileFlags & JSFILENAME_SYSTEM)) {
    // We expect implicit native wrappers in system files.
    return JS_TRUE;
  }

  nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
  if (!ssm) {
    // If there's no security manager, then we're not running in a browser
    // context: allow access.
    return JS_TRUE;
  }

  // A last ditch effort to allow access: if the currently-running code
  // has UniversalXPConnect privileges, then allow access.
  PRBool isPrivileged;
  nsresult rv = ssm->IsCapabilityEnabled("UniversalXPConnect", &isPrivileged);
  if (NS_SUCCEEDED(rv) && isPrivileged) {
    return JS_TRUE;
  }

  // Otherwise, we're looking at a non-system file with a handle on an
  // implicit wrapper. This is a bug! Deny access.
  return ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx);
}
bool
NoWaiverWrapper::enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp)
{
    *bp = true; // always allowed
    nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
    if (!ssm) {
        return true;
    }

    // Note: By the time enter is called here, JSCrossCompartmentWrapper has
    // already pushed the fake stack frame onto cx. Because of this, the frame
    // that we're clamping is the one that we want (the one in our compartment).
    JSStackFrame *fp = NULL;
    nsIPrincipal *principal = GetCompartmentPrincipal(wrappedObject(wrapper)->compartment());
    nsresult rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp), principal);
    if (NS_FAILED(rv)) {
        NS_WARNING("Not allowing call because we're out of memory");
        JS_ReportOutOfMemory(cx);
        return false;
    }
    return true;
}
Esempio n. 19
0
JSTrapStatus CThreadDebugger::BreakHandler(JSContext* cx, JSScript* script, jsbytecode* pc, jsval* UNUSED(rval), jsval UNUSED(closure), BREAK_SRC breakSrc) 
{
	uint line = JS_PCToLineNumber(cx, script, pc);
	std::string filename(JS_GetScriptFilename(cx, script));

	SetIsInBreak(true);
	SaveCallstack();
	SetLastBreakLine(line);
	SetBreakFileName(filename);
	*m->m_pLastBreakFrame = NULL;
	
	if (breakSrc == BREAK_SRC_INTERRUP)
	{
		JS_ClearInterrupt(m->m_pScriptInterface->GetRuntime(), NULL, NULL);
		JS_SetSingleStepMode(cx, script, false);
	}
	
	if (m->m_pDebuggingServer->GetSettingSimultaneousThreadBreak())
	{
		m->m_pDebuggingServer->SetBreakRequestedByThread(true);
	}
	
	// Wait until the user continues the execution
	while (1)
	{
		DBGCMD nextDbgCmd = GetNextDbgCmd();
		
		while (!m->m_StackInfoRequests.empty())
		{
			StackInfoRequest request = m->m_StackInfoRequests.front();
			SaveStackFrameData(request.requestType, request.nestingLevel);
			SDL_SemPost(request.semaphore);
			m->m_StackInfoRequests.pop();
		}
		
		if (nextDbgCmd == DBG_CMD_NONE)
		{
			// Wait a while before checking for new m_NextDbgCmd again.
			// We don't want this loop to take 100% of a CPU core for each thread that is in break mode.
			// On the other hande we don't want the debugger to become unresponsive.
			SDL_Delay(100);
		}
		else if (nextDbgCmd == DBG_CMD_SINGLESTEP || nextDbgCmd == DBG_CMD_STEPINTO || nextDbgCmd == DBG_CMD_STEPOUT)
		{
			JSStackFrame* iter = NULL;
			*m->m_pLastBreakFrame = JS_FrameIterator(m->m_pScriptInterface->GetContext(), &iter);
			
			if (!JS_SetSingleStepMode(cx, script, true))
				LOGERROR(L"JS_SetSingleStepMode returned false!"); // TODO: When can this happen?
			else
			{
				if (nextDbgCmd == DBG_CMD_SINGLESTEP)
				{
					JS_SetInterrupt(m->m_pScriptInterface->GetRuntime(), StepHandler_, this);
					break;
				}
				else if (nextDbgCmd == DBG_CMD_STEPINTO)
				{
					JS_SetInterrupt(m->m_pScriptInterface->GetRuntime(), StepIntoHandler_, this);
					break;
				}
				else if (nextDbgCmd == DBG_CMD_STEPOUT)
				{
					JS_SetInterrupt(m->m_pScriptInterface->GetRuntime(), StepOutHandler_, this);
					break;
				}
			}
		}
		else if (nextDbgCmd == DBG_CMD_CONTINUE)
		{
			if (!JS_SetSingleStepMode(cx, script, true))
				LOGERROR(L"JS_SetSingleStepMode returned false!"); // TODO: When can this happen?
			else
			{
				// Setup a handler to check for break-requests from the DebuggingServer regularly
				JS_SetInterrupt(m->m_pScriptInterface->GetRuntime(), CheckForBreakRequestHandler_, this);
			}
			break;
		}
		else 
			debug_warn("Invalid DBGCMD found in CThreadDebugger::BreakHandler!");
	}
	ClearTrapsToRemove();
	SetAllNewTraps();
	SetNextDbgCmd(DBG_CMD_NONE);
	SetIsInBreak(false);
	SetBreakFileName("");
	
	// All saved stack data becomes invalid
	{
		CScopeLock lock(m->m_Mutex);
		m->m_StackFrameData.clear();
	}
	
	return JSTRAP_CONTINUE;
}
Esempio n. 20
0
// If you change this code, change also nsContentUtils::CanAccessNativeAnon()!
JSBool
AllowedToAct(JSContext *cx, jsid id)
{
  // TODO bug 508928: Refactor this with the XOW security checking code.
  nsIScriptSecurityManager *ssm = GetSecurityManager();
  if (!ssm) {
    return JS_TRUE;
  }

  JSStackFrame *fp;
  nsIPrincipal *principal = ssm->GetCxSubjectPrincipalAndFrame(cx, &fp);
  if (!principal) {
    return ThrowException(NS_ERROR_UNEXPECTED, cx);
  }

  if (!fp) {
    if (!JS_FrameIterator(cx, &fp)) {
      // No code at all is running. So we must be arriving here as the result
      // of C++ code asking us to do something. Allow access.
      return JS_TRUE;
    }

    // Some code is running, we can't make the assumption, as above, but we
    // can't use a native frame, so clear fp.
    fp = nsnull;
  } else if (!fp->hasScript()) {
    fp = nsnull;
  }

  PRBool privileged;
  if (NS_SUCCEEDED(ssm->IsSystemPrincipal(principal, &privileged)) &&
      privileged) {
    // Chrome things are allowed to touch us.
    return JS_TRUE;
  }

  // XXX HACK EWW! Allow chrome://global/ access to these things, even
  // if they've been cloned into less privileged contexts.
  const char *filename;
  if (fp &&
      (filename = fp->getScript()->filename) &&
      !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
    return JS_TRUE;
  }

  // Before we throw, check for UniversalXPConnect.
  nsresult rv = ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged);
  if (NS_SUCCEEDED(rv) && privileged) {
    return JS_TRUE;
  }

  if (JSID_IS_VOID(id)) {
    ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx);
  } else {
    // TODO Localize me?
    jsval idval;
    JSString *str;
    if (JS_IdToValue(cx, id, &idval) && (str = JS_ValueToString(cx, idval))) {
      JS_ReportError(cx, "Permission denied to access property '%hs' from a non-chrome context",
                     JS_GetStringChars(str));
    }
  }

  return JS_FALSE;
}
Esempio n. 21
0
JSBool
XPC_SJOW_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
                   jsval *rval)
{
  if (argc < 1) {
    return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx);
  }

  // |obj| almost always has the wrong proto and parent so we have to create
  // our own object anyway.  Set |obj| to null so we don't use it by accident.
  obj = nsnull;

  if (JSVAL_IS_PRIMITIVE(argv[0])) {
    JSStackFrame *fp = nsnull;
    if (JS_FrameIterator(cx, &fp) && JS_IsConstructorFrame(cx, fp)) {
      return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx);
    }

    *rval = argv[0];
    return JS_TRUE;
  }

  JSObject *objToWrap = JSVAL_TO_OBJECT(argv[0]);

  // Prevent script created Script objects from ever being wrapped
  // with XPCSafeJSObjectWrapper, and never let the eval function
  // object be directly wrapped.

  if (STOBJ_GET_CLASS(objToWrap) == &js_ScriptClass ||
      (::JS_ObjectIsFunction(cx, objToWrap) &&
       ::JS_GetFunctionNative(cx, ::JS_ValueToFunction(cx, argv[0])) ==
       XPCWrapper::sEvalNative)) {
    return ThrowException(NS_ERROR_INVALID_ARG, cx);
  }

  SLIM_LOG_WILL_MORPH(cx, objToWrap);
  if(IS_SLIM_WRAPPER(objToWrap) && !MorphSlimWrapper(cx, objToWrap)) {
    return ThrowException(NS_ERROR_FAILURE, cx);
  }

  // Check that the caller can access the unsafe object.
  if (!CanCallerAccess(cx, objToWrap)) {
    // CanCallerAccess() already threw for us.
    return JS_FALSE;
  }

  JSObject *unsafeObj = GetUnsafeObject(objToWrap);

  if (unsafeObj) {
    // We're asked to wrap an already wrapped object. Re-wrap the
    // object wrapped by the given wrapper.

    objToWrap = unsafeObj;
  }

  // Don't use the object the JS engine created for us, it is in most
  // cases incorectly parented and has a proto from the wrong scope.
  JSObject *wrapperObj =
    ::JS_NewObjectWithGivenProto(cx, &sXPC_SJOW_JSClass.base, nsnull,
                                 objToWrap);

  if (!wrapperObj) {
    // JS_NewObjectWithGivenProto already threw.
    return JS_FALSE;
  }

  if (!::JS_SetReservedSlot(cx, wrapperObj, XPC_SJOW_SLOT_IS_RESOLVING,
                            JSVAL_ZERO)) {
    return JS_FALSE;
  }

  *rval = OBJECT_TO_JSVAL(wrapperObj);

  return JS_TRUE;
}
Esempio n. 22
0
JSDThreadState*
jsd_NewThreadState(JSDContext* jsdc, JSContext *cx )
{
    JSDThreadState* jsdthreadstate;
    JSStackFrame *  iter = NULL;
    JSStackFrame *  fp;

    jsdthreadstate = (JSDThreadState*)calloc(1, sizeof(JSDThreadState));
    if( ! jsdthreadstate )
        return NULL;

    jsdthreadstate->context = cx;
    jsdthreadstate->thread = JSD_CURRENT_THREAD();
    JS_INIT_CLIST(&jsdthreadstate->stack);
    jsdthreadstate->stackDepth = 0;

    JS_BeginRequest(jsdthreadstate->context);
    while( NULL != (fp = JS_FrameIterator(cx, &iter)) )
    {
        JSScript* script = JS_GetFrameScript(cx, fp);
        jsuword  pc = (jsuword) JS_GetFramePC(cx, fp);

        /*
         * don't construct a JSDStackFrame for dummy frames (those without a
         * |this| object, or native frames, if JSD_INCLUDE_NATIVE_FRAMES
         * isn't set.
         */
        if (JS_GetFrameThis(cx, fp) &&
            ((jsdc->flags & JSD_INCLUDE_NATIVE_FRAMES) ||
             !JS_IsNativeFrame(cx, fp)))
        {
            JSDStackFrameInfo *frame;

            frame = _addNewFrame( jsdc, jsdthreadstate, script, pc, fp );

            if ((jsdthreadstate->stackDepth == 0 && !frame) ||
                (jsdthreadstate->stackDepth == 1 && frame &&
                 frame->jsdscript && !JSD_IS_DEBUG_ENABLED(jsdc, frame->jsdscript)))
            {
                /*
                 * if we failed to create the first frame, or the top frame
                 * is not enabled for debugging, fail the entire thread state.
                 */
                JS_INIT_CLIST(&jsdthreadstate->links);
                JS_EndRequest(jsdthreadstate->context);
                jsd_DestroyThreadState(jsdc, jsdthreadstate);
                return NULL;
            }
        }
    }
    JS_EndRequest(jsdthreadstate->context);

    if (jsdthreadstate->stackDepth == 0)
    {
        free(jsdthreadstate);
        return NULL;
    }
    
    JSD_LOCK_THREADSTATES(jsdc);
    JS_APPEND_LINK(&jsdthreadstate->links, &jsdc->threadsStates);
    JSD_UNLOCK_THREADSTATES(jsdc);

    return jsdthreadstate;
}
Esempio n. 23
0
JSTrapStatus doi_check_sc_hs(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,void *closure)
{
    JSOp opcode = 0;
    JSStackFrame * fp = NULL;
    jsval r_val = 0;
    size_t l_val = 0;
    const JSCodeSpec *cs;
    char *updatetype = "R";
    
    opcode = (JSOp)*pc;//JS_GetTrapOpcode(cx, script, pc);//in 1.8.0, use this
    cs = &js_CodeSpec[opcode];
    //fprintf(stderr, "DEBUG:now  %s\n", cs->name);

    fp = NULL;
    JS_FrameIterator(cx,&fp);
    r_val = l_val = 0;
    switch(opcode)
    {
        case JSOP_SETNAME:
        case JSOP_SETPROP:
        {
            r_val = FETCH_OPND(-1);
            l_val = get_opcode_arg(cx,script,pc);
            updatetype = "R";
            break;
        }
        case JSOP_SETGVAR:
        {
            r_val = FETCH_OPND(-1);
            l_val = (size_t)&(fp->vars[GET_VARNO(pc)]); // TODO: FIXIT this is not l_val, setgvar is more than that
            updatetype = "R";
            break;
        }
        case JSOP_SETELEM:
        {
            r_val = FETCH_OPND(-1);
            l_val = FETCH_OPND(-3);
            updatetype = "A";
            break;
        }
        case JSOP_SETVAR:
        {
            r_val = FETCH_OPND(-1);
            l_val = (size_t)&(fp->vars[GET_VARNO(pc)]); // TODO: FIXIT
            updatetype = "R";
            break;
        }
        case JSOP_SETLOCALPOP:
        case JSOP_SETLOCAL:
        {
            r_val = FETCH_OPND(-1);
            l_val = (size_t)&(fp->spbase[GET_UINT16(pc)]);
            updatetype = "R";
            break;
        }
        case JSOP_SETARG:
        {
            r_val = FETCH_OPND(-1);
            l_val = (size_t)&(fp->argv[GET_ARGNO(pc)]); // TODO: FIXIT
            updatetype = "R";
            break;
        }
        case JSOP_SETCONST:
        {
            // Errr.... actually i don't know what's the meaning of setconst etc,
            // if you know, please email me :)
            fprintf(stderr, "DEBUG: found %s\n", cs->name);
            r_val = FETCH_OPND(-1);
            l_val = 0;
            updatetype = "R";
            break;
        }
        case JSOP_ENUMELEM:
        case JSOP_ENUMCONSTELEM:
        {
            fprintf(stderr, "DEBUG: found %s\n", cs->name);
            r_val = FETCH_OPND(-3);
            l_val = FETCH_OPND(-2);
            updatetype = "A";
            break;
        }
        case JSOP_SETXMLNAME:
        case JSOP_SETMETHOD:
        {
            l_val = FETCH_OPND(-2);
            r_val = FETCH_OPND(-1);
            updatetype = "R";
            break;
        }
        default:
            if(0&&cs->format & JOF_SET){
                fprintf(stderr, "DEBUG: %s interpreted but not checked\n", cs->name);
            }
            break;
    }
    if(r_val != 0 &&
       JSVAL_IS_STRING(r_val))
    {
        uint32_t length = 0;
        length = JS_GetStringLength(JSVAL_TO_STRING(r_val)) * sizeof(jschar);
        if(length < MIN_STR_LEN_TO_CHECK){
            goto end;
        }
        int r = 0;
        unsigned char *bytes = NULL;
        jschar *jschars = NULL;
        jschars = JS_GetStringChars(JSVAL_TO_STRING(r_val));
        bytes = (unsigned char *)jschars;
        if(length > 65535){
            //Heapspray DETECTED!
            /* fprintf(stderr,"\nDEBUG: HEAPSPRAY DETECTED!\n"); */

            heapspray_info hsinfo;
            hsinfo = check_heapspray(bytes,length);
            PyObject* alert = NULL;
            PyObject* param = NULL;
            Context* pycx = NULL;
            pycx = (Context*) JS_GetContextPrivate(cx);

            size_t uniqueid = (size_t)pycx + (size_t)l_val;
            
            PyObject *str = PyString_FromString("alert_by_uid");
            PyObject *alert_by_uid = NULL;
            if (str == NULL) goto error;
            alert_by_uid = PyObject_GetAttr((PyObject *)HeapsprayAlertType,str);
            Py_DECREF(str);
            str = NULL;
            if (alert_by_uid == NULL) goto error;

            PyObject *pyuid = Py_BuildValue("i",uniqueid);
            if (PyDict_Contains(alert_by_uid,pyuid)){
                alert = PyDict_GetItem(alert_by_uid,pyuid);
                if(alert == NULL) goto error;

                PyObject *raiseret = PyObject_CallMethod(alert,
                                                         "reraise",
                                                         "sdi{s:s#,s:i,s:s#,s:i}",
                                                         "Previous",
                                                         hsinfo.entropy,
                                                         length,
                                                         "sledge_char",
                                                         &(hsinfo.most_char),
                                                         1,
                                                         "sledge_cnt",
                                                         hsinfo.most_char_cnt,
                                                         "sec_char",
                                                         &(hsinfo.sec_char),
                                                         1,
                                                         "sec_char_cnt",
                                                         hsinfo.sec_char_cnt);
                if(raiseret == NULL) goto error;
                Py_DECREF(raiseret);
                raiseret = NULL;                                                         
            }else{            
                param = Py_BuildValue("isdii{s:s#,s:i,s:s#,s:i}s",
                                      -1,
                                      "Heapspray Detected!",
                                      hsinfo.entropy,
                                      length,
                                      uniqueid,
                                      "sledge_char",
                                      &(hsinfo.most_char),
                                      1,
                                      "sledge_cnt",
                                      hsinfo.most_char_cnt,
                                      "sec_char",
                                      &(hsinfo.sec_char),
                                      1,
                                      "sec_char_cnt",
                                      hsinfo.sec_char_cnt,
                                      updatetype);
                if(param == NULL) goto error;
            
                alert = PyObject_CallObject((PyObject*)HeapsprayAlertType,param);
                Py_DECREF(param);
                param = NULL;
                if(alert == NULL) goto error;
                if(PyList_Append(pycx->alertlist,alert) != 0)
                {
                    goto error;
                }
                Py_DECREF(alert);
                alert = NULL;
            }
            Py_DECREF(pyuid);
            pyuid = NULL;
        }else{
            /* FILE *f; */
            /* char path[100]; */
            /* sprintf(path,"debug/%d.sc",l_val); */
            /* f = fopen(path,"wb"); */
            /* fwrite(bytes,length,1,f); */
            /* fclose(f); */
            
            r = check_buffer(bytes,length);
            if(r >= 0)
            {
                //Shellcode DETECTED!
                /* fprintf(stderr,"\nDEBUG: SHELLCODE DETECTED!\n"); */
                PyObject* alert = NULL;
                PyObject* param = NULL;
                Context* pycx = NULL;
                
                param = Py_BuildValue("iss#i",
                                      -1,
                                      "Shellcode Detected!",
                                      bytes,
                                      length,
                                      r);
                if(param == NULL) goto error;
                
                alert = PyObject_CallObject((PyObject*)ShellcodeAlertType,param);
                Py_DECREF(param);
                param = NULL;
                if(alert == NULL) goto error;
                pycx = (Context*) JS_GetContextPrivate(cx);
                
                if(PyList_Append(pycx->alertlist,alert) != 0)
                {
                    goto error;
                }
                Py_DECREF(alert);
                alert = NULL;
                //TODO: FIXME: is it necesary to DECREF alert?
                
                /*         if rt.malvariables.has_key(l_val): */
                /*             alert = rt.malvariables[l_val] */
                /*         else: */
                /*             alert = Alert(0,l_val,"Shellcode Detected",{"hit":0}) */
                /*             rt.malvariables[l_val]=alert */
                /*             rt.alerts.append(alert) */
                /*         alert.misc["hit"]+=1 */
                
                /*         jschars = JS_GetStringChars(JSVAL_TO_STRING(r_val)) */
                /*         bytes = <char *>jschars */
                /*         length = JS_GetStringLength(JSVAL_TO_STRING(r_val)) */
                /*         s = PyString_FromStringAndSize(bytes, length*2)#sizeof(jschar)) */
                /*         alert.misc["contents"] = s */
                /*         alert.misc["offset"] = r */
                /*         #f = open("shellcodes/"+str(l_val)+".sc","w") */
                /*         #f.write(s) */
                /*         #f.close() */
                /*         #print "DEBUG: !!!SC DETECTED at "+str(l_val)+"="+str(r_val)+"size:"+str(length*2) */
            }
        }
    }
end:
    return JSTRAP_CONTINUE;
error:
    return  JSTRAP_ERROR;
}