Advertisement
Guest User

Untitled

a guest
Jul 28th, 2017
462
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 4.13 KB | None | 0 0
  1. commit 7f1f9b827b77b53e4df63db75b126c62ed126b99
  2. Author: Kent Hansen <kent.hansen@nokia.com>
  3. Date:   Fri Feb 25 13:23:07 2011 +0100
  4.  
  5.     Don't crash when marking arguments object of native context
  6.    
  7.     JSC assumes that the callee is always valid, since JSC::Arguments
  8.     is used for JS frames, which must have a callee.
  9.     But we use JSC::Arguments for arguments object of
  10.     pushContext()-created contexts, and then there is no callee.
  11.     But the callee member can't be null, so now we put a fake callee
  12.     there and make sure it doesn't bleed up to the public API.
  13.    
  14.     Alternative solution: Add "if (d->callee)" to
  15.     JSC::Arguments::markChildren(), then no other changes would be
  16.     needed. But we don't want to patch JSC any more.
  17.    
  18.     Non-solution: Subclass JSC::Arguments and reimplement
  19.     markChildren() to temporarily set a dummy callee during marking.
  20.     Can't be done, as JSC::Arguments::d is private (again, we don't
  21.     want to patch JSC).
  22.    
  23.     Task-number: QTBUG-17788
  24.     Reviewed-by: pending
  25.  
  26. diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp
  27. index 2468a46..5454df5 100644
  28. --- a/src/script/api/qscriptcontext.cpp
  29. +++ b/src/script/api/qscriptcontext.cpp
  30. @@ -268,8 +268,14 @@ QScriptValue QScriptContext::argument(int index) const
  31.  QScriptValue QScriptContext::callee() const
  32.  {
  33.      const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this);
  34. -    QScript::APIShim shim(QScript::scriptEngineFromExec(frame));
  35. -    return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(frame->callee());
  36. +    QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(frame);
  37. +    QScript::APIShim shim(eng);
  38. +    if (frame->callee() == eng->originalGlobalObject()) {
  39. +        // This is a pushContext()-created context; the callee is a lie.
  40. +        Q_ASSERT(QScriptEnginePrivate::contextFlags(const_cast<JSC::CallFrame*>(frame)) & QScriptEnginePrivate::NativeContext);
  41. +        return QScriptValue();
  42. +    }
  43. +    return eng->scriptValueFromJSCValue(frame->callee());
  44.  }
  45.  
  46.  /*!
  47. diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
  48. index 478fdaa..32deae8 100644
  49. --- a/src/script/api/qscriptengine.cpp
  50. +++ b/src/script/api/qscriptengine.cpp
  51. @@ -2727,6 +2727,14 @@ JSC::CallFrame *QScriptEnginePrivate::pushContext(JSC::CallFrame *exec, JSC::JSV
  52.                                                    bool clearScopeChain)
  53.  {
  54.      JSC::JSValue thisObject = _thisObject;
  55. +    if (!callee) {
  56. +        // callee can't be zero, as this can cause JSC to crash during GC
  57. +        // marking phase if the context's Arguments object has been created.
  58. +        // Fake it by using the global object. Note that this is also handled
  59. +        // in QScriptContext::callee(), as that function should still return
  60. +        // an invalid value.
  61. +        callee = originalGlobalObject();
  62. +    }
  63.      if (calledAsConstructor) {
  64.          //JSC doesn't create default created object for native functions. so we do it
  65.          JSC::JSValue prototype = callee->get(exec, exec->propertyNames().prototype);
  66. diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp
  67. index 8de6fbc..7672403 100644
  68. --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp
  69. +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp
  70. @@ -169,6 +169,7 @@ private slots:
  71.      void nativeFunctionScopes();
  72.      void evaluateProgram();
  73.      void collectGarbageAfterConnect();
  74. +    void collectGarbageAfterNativeArguments();
  75.      void promoteThisObjectToQObjectInConstructor();
  76.  
  77.      void qRegExpInport_data();
  78. @@ -5040,6 +5041,16 @@ void tst_QScriptEngine::collectGarbageAfterConnect()
  79.      QVERIFY(widget == 0);
  80.  }
  81.  
  82. +void tst_QScriptEngine::collectGarbageAfterNativeArguments()
  83. +{
  84. +    // QTBUG-17788
  85. +    QScriptEngine eng;
  86. +    QScriptContext *ctx = eng.pushContext();
  87. +    ctx->argumentsObject();
  88. +    // Shouldn't crash when marking the arguments object.
  89. +    eng.collectGarbage();
  90. +}
  91. +
  92.  static QScriptValue constructQObjectFromThisObject(QScriptContext *ctx, QScriptEngine *eng)
  93.  {
  94.      Q_ASSERT(ctx->isCalledAsConstructor());
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement