Changeset 92122 in webkit


Ignore:
Timestamp:
Aug 1, 2011 4:42:43 AM (13 years ago)
Author:
yurys@chromium.org
Message:

Web Inspector: typing an expression in an iframe leads to multiple "Unsafe JavaScript attempt to access frame..." errors
https://bugs.webkit.org/show_bug.cgi?id=65457

Source/WebCore:

Console completions are now done using evaluation which returns a JSON object with all property names rather than a remote
object. Also Runtime.evaluate and Runtime.callFunctionOn commands were extended with an optional parameter that allows to
get result as JSON value.

Reviewed by Pavel Feldman.

Test: http/tests/inspector/console-cd-completions.html

  • inspector/InjectedScript.cpp:

(WebCore::InjectedScript::evaluate):
(WebCore::InjectedScript::callFunctionOn):

  • inspector/InjectedScript.h:
  • inspector/InjectedScriptSource.js:

(.):
():

  • inspector/Inspector.json:
  • inspector/InspectorRuntimeAgent.cpp:

(WebCore::asBool):
(WebCore::InspectorRuntimeAgent::evaluate):
(WebCore::InspectorRuntimeAgent::callFunctionOn):

  • inspector/InspectorRuntimeAgent.h:
  • inspector/front-end/ConsoleView.js:

(WebInspector.ConsoleView.prototype._completions.evaluated.getCompletions):
(WebInspector.ConsoleView.prototype._completions.evaluated):
(WebInspector.ConsoleView.prototype._completions.receivedPropertySet):
(WebInspector.ConsoleView.prototype._completions):
(WebInspector.ConsoleView.prototype.evalInInspectedWindow):

  • inspector/front-end/RemoteObject.js:

(WebInspector.RemoteObject):
(WebInspector.RemoteObject.prototype.callFunction):
(WebInspector.RemoteObject.prototype.callFunctionJSON):

  • inspector/front-end/WatchExpressionsSidebarPane.js:

(WebInspector.WatchExpressionsSection.prototype.update):

LayoutTests:

Reviewed by Pavel Feldman.

  • http/tests/inspector/console-cd-completions-expected.txt: Added.
  • http/tests/inspector/console-cd-completions.html: Added.
  • http/tests/inspector/resources/console-cd-completions-iframe.html: Added.
Location:
trunk
Files:
3 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r92121 r92122  
     12011-08-01  Yury Semikhatsky  <yurys@chromium.org>
     2
     3        Web Inspector: typing an expression in an iframe leads to multiple "Unsafe JavaScript attempt to access frame..." errors
     4        https://bugs.webkit.org/show_bug.cgi?id=65457
     5
     6        Reviewed by Pavel Feldman.
     7
     8        * http/tests/inspector/console-cd-completions-expected.txt: Added.
     9        * http/tests/inspector/console-cd-completions.html: Added.
     10        * http/tests/inspector/resources/console-cd-completions-iframe.html: Added.
     11
    1122011-08-01  Tony Gentilcore  <tonyg@chromium.org>
    213
  • trunk/Source/WebCore/ChangeLog

    r92118 r92122  
     12011-08-01  Yury Semikhatsky  <yurys@chromium.org>
     2
     3        Web Inspector: typing an expression in an iframe leads to multiple "Unsafe JavaScript attempt to access frame..." errors
     4        https://bugs.webkit.org/show_bug.cgi?id=65457
     5
     6        Console completions are now done using evaluation which returns a JSON object with all property names rather than a remote
     7        object. Also Runtime.evaluate and Runtime.callFunctionOn commands were extended with an optional parameter that allows to
     8        get result as JSON value.
     9
     10        Reviewed by Pavel Feldman.
     11
     12        Test: http/tests/inspector/console-cd-completions.html
     13
     14        * inspector/InjectedScript.cpp:
     15        (WebCore::InjectedScript::evaluate):
     16        (WebCore::InjectedScript::callFunctionOn):
     17        * inspector/InjectedScript.h:
     18        * inspector/InjectedScriptSource.js:
     19        (.):
     20        ():
     21        * inspector/Inspector.json:
     22        * inspector/InspectorRuntimeAgent.cpp:
     23        (WebCore::asBool):
     24        (WebCore::InspectorRuntimeAgent::evaluate):
     25        (WebCore::InspectorRuntimeAgent::callFunctionOn):
     26        * inspector/InspectorRuntimeAgent.h:
     27        * inspector/front-end/ConsoleView.js:
     28        (WebInspector.ConsoleView.prototype._completions.evaluated.getCompletions):
     29        (WebInspector.ConsoleView.prototype._completions.evaluated):
     30        (WebInspector.ConsoleView.prototype._completions.receivedPropertySet):
     31        (WebInspector.ConsoleView.prototype._completions):
     32        (WebInspector.ConsoleView.prototype.evalInInspectedWindow):
     33        * inspector/front-end/RemoteObject.js:
     34        (WebInspector.RemoteObject):
     35        (WebInspector.RemoteObject.prototype.callFunction):
     36        (WebInspector.RemoteObject.prototype.callFunctionJSON):
     37        * inspector/front-end/WatchExpressionsSidebarPane.js:
     38        (WebInspector.WatchExpressionsSection.prototype.update):
     39
    1402011-08-01  Mihnea Ovidenie  <mihnea@adobe.com>
    241
  • trunk/Source/WebCore/inspector/InjectedScript.cpp

    r91750 r92122  
    5555}
    5656
    57 void InjectedScript::evaluate(ErrorString* errorString, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result, bool* wasThrown)
     57void InjectedScript::evaluate(ErrorString* errorString, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool sendResultByValue, RefPtr<InspectorObject>* result, bool* wasThrown)
    5858{
    5959    ScriptFunctionCall function(m_injectedScriptObject, "evaluate");
     
    6161    function.appendArgument(objectGroup);
    6262    function.appendArgument(includeCommandLineAPI);
     63    function.appendArgument(sendResultByValue);
    6364    makeEvalCall(errorString, function, result, wasThrown);
    6465}
    6566
    66 void InjectedScript::callFunctionOn(ErrorString* errorString, const String& objectId, const String& expression, const String& arguments, RefPtr<InspectorObject>* result, bool* wasThrown)
     67void InjectedScript::callFunctionOn(ErrorString* errorString, const String& objectId, const String& expression, const String& arguments, bool sendResultByValue, RefPtr<InspectorObject>* result, bool* wasThrown)
    6768{
    6869    ScriptFunctionCall function(m_injectedScriptObject, "callFunctionOn");
     
    7071    function.appendArgument(expression);
    7172    function.appendArgument(arguments);
     73    function.appendArgument(sendResultByValue);
    7274    makeEvalCall(errorString, function, result, wasThrown);
    7375}
  • trunk/Source/WebCore/inspector/InjectedScript.h

    r91750 r92122  
    5656    bool hasNoValue() const { return m_injectedScriptObject.hasNoValue(); }
    5757
    58     void evaluate(ErrorString*, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result, bool* wasThrown);
    59     void callFunctionOn(ErrorString*, const String& objectId, const String& expression, const String& arguments, RefPtr<InspectorObject>* result, bool* wasThrown);
     58    void evaluate(ErrorString*,
     59                  const String& expression,
     60                  const String& objectGroup,
     61                  bool includeCommandLineAPI,
     62                  bool sendResultByValue,
     63                  RefPtr<InspectorObject>* result,
     64                  bool* wasThrown);
     65    void callFunctionOn(ErrorString*,
     66                        const String& objectId,
     67                        const String& expression,
     68                        const String& arguments,
     69                        bool sendResultByValue,
     70                        RefPtr<InspectorObject>* result,
     71                        bool* wasThrown);
    6072    void evaluateOnCallFrame(ErrorString*, const ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result, bool* wasThrown);
    6173    void getProperties(ErrorString*, const String& objectId, bool ignoreHasOwnProperty, RefPtr<InspectorArray>* result);
  • trunk/Source/WebCore/inspector/InjectedScriptSource.js

    r91754 r92122  
    109109
    110110    // This method cannot throw.
    111     _wrapObject: function(object, objectGroupName)
     111    _wrapObject: function(object, objectGroupName, forceValueType)
    112112    {
    113113        try {
    114             return new InjectedScript.RemoteObject(object, objectGroupName);
     114            return new InjectedScript.RemoteObject(object, objectGroupName, forceValueType);
    115115        } catch (e) {
    116116            try {
     
    184184            var propertyName = propertyNames[i];
    185185
    186             var getter = object["__lookupGetter__"] && object.__lookupGetter__(propertyName);
    187             var setter = object["__lookupSetter__"] && object.__lookupSetter__(propertyName);
     186            var getter = (typeof object["__lookupGetter__"] === "function") && object.__lookupGetter__(propertyName);
     187            var setter = (typeof object["__lookupSetter__"] === "function") && object.__lookupSetter__(propertyName);
    188188            if (getter || setter) {
    189189                if (getter) {
     
    247247    },
    248248
    249     evaluate: function(expression, objectGroup, injectCommandLineAPI)
    250     {
    251         return this._evaluateAndWrap(InjectedScriptHost.evaluate, InjectedScriptHost, expression, objectGroup, false, injectCommandLineAPI);
    252     },
    253 
    254     callFunctionOn: function(objectId, expression, args)
     249    evaluate: function(expression, objectGroup, injectCommandLineAPI, sendResultByValue)
     250    {
     251        return this._evaluateAndWrap(InjectedScriptHost.evaluate, InjectedScriptHost, expression, objectGroup, false, injectCommandLineAPI, sendResultByValue);
     252    },
     253
     254    callFunctionOn: function(objectId, expression, args, sendResultByValue)
    255255    {
    256256        var parsedObjectId = this._parseObjectId(objectId);
     
    288288
    289289            return { wasThrown: false,
    290                      result: this._wrapObject(func.apply(object, resolvedArgs), objectGroup) };
     290                     result: this._wrapObject(func.apply(object, resolvedArgs), objectGroup, sendResultByValue) };
    291291        } catch (e) {
    292292            return { wasThrown: true,
     
    295295    },
    296296
    297     _evaluateAndWrap: function(evalFunction, object, expression, objectGroup, isEvalOnCallFrame, injectCommandLineAPI)
     297    _evaluateAndWrap: function(evalFunction, object, expression, objectGroup, isEvalOnCallFrame, injectCommandLineAPI, sendResultByValue)
    298298    {
    299299        try {
    300300            return { wasThrown: false,
    301                      result: this._wrapObject(this._evaluateOn(evalFunction, object, expression, isEvalOnCallFrame, injectCommandLineAPI), objectGroup) };
     301                     result: this._wrapObject(this._evaluateOn(evalFunction, object, expression, isEvalOnCallFrame, injectCommandLineAPI), objectGroup, sendResultByValue) };
    302302        } catch (e) {
    303303            return { wasThrown: true,
     
    451451var injectedScript = new InjectedScript();
    452452
    453 InjectedScript.RemoteObject = function(object, objectGroupName)
     453InjectedScript.RemoteObject = function(object, objectGroupName, forceValueType)
    454454{
    455455    this.type = typeof object;
    456     if (injectedScript.isPrimitiveValue(object) || object === null) {
     456    if (injectedScript.isPrimitiveValue(object) || object === null || forceValueType) {
    457457
    458458        // We don't send undefined values over JSON.
  • trunk/Source/WebCore/inspector/Inspector.json

    r91928 r92122  
    231231                    { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date"], "description": "Object subtype hint. Specified for <code>object</code> type values only." },
    232232                    { "name": "className", "type": "string", "optional": true, "description": "Object class (constructor) name. Specified for <code>object</code> type values only." },
    233                     { "name": "value", "type": "any", "optional": true, "description": "Remote object value (in case of primitive values)." },
     233                    { "name": "value", "type": "any", "optional": true, "description": "Remote object value (in case of primitive values or JSON values if it was requested)." },
    234234                    { "name": "description", "type": "string", "optional": true, "description": "String representation of the object." },
    235235                    { "name": "objectId", "$ref": "RemoteObjectId", "optional": true, "description": "Unique object identifier (for non-primitive values)." }
     
    264264                    { "name": "includeCommandLineAPI", "type": "boolean", "optional": true, "description": "Determines whether Command Line API should be available during the evaluation." },
    265265                    { "name": "doNotPauseOnExceptions", "type": "boolean", "optional": true, "description": "Specifies whether evaluation should stop on exceptions. Overrides setPauseOnException state." },
    266                     { "name": "frameId", "type": "string", "optional": true, "description": "Specifies in which frame to perform evaluation." }
     266                    { "name": "frameId", "type": "string", "optional": true, "description": "Specifies in which frame to perform evaluation." },
     267                    { "name": "sendResultByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object which should be sent by value." }
    267268                ],
    268269                "returns": [
     
    277278                    { "name": "objectId", "$ref": "RemoteObjectId", "description": "Identifier of the object to call function on." },
    278279                    { "name": "functionDeclaration", "type": "string", "description": "Declaration of the function to call." },
    279                     { "name": "arguments", "type": "array", "items": { "$ref": "CallArgument", "description": "Call argument." }, "optional": true, "description": "Call arguments. All call arguments must belong to the same JavaScript world as the target object." }
     280                    { "name": "arguments", "type": "array", "items": { "$ref": "CallArgument", "description": "Call argument." }, "optional": true, "description": "Call arguments. All call arguments must belong to the same JavaScript world as the target object." },
     281                    { "name": "sendResultByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object which should be sent by value." }
    280282                ],
    281283                "returns": [
  • trunk/Source/WebCore/inspector/InspectorRuntimeAgent.cpp

    r91956 r92122  
    4646namespace WebCore {
    4747
     48static bool asBool(const bool* const b)
     49{
     50    return b ? *b : false;
     51}
     52
    4853InspectorRuntimeAgent::InspectorRuntimeAgent(InjectedScriptManager* injectedScriptManager)
    4954    : m_injectedScriptManager(injectedScriptManager)
     
    5863}
    5964
    60 void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptions, const String* const frameId, RefPtr<InspectorObject>* result, bool* wasThrown)
     65void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptions, const String* const frameId, const bool* const sendResultByValue, RefPtr<InspectorObject>* result, bool* wasThrown)
    6166{
    6267    ScriptState* scriptState = 0;
     
    7883    bool pauseStateChanged = false;
    7984    ScriptDebugServer::PauseOnExceptionsState presentState = m_scriptDebugServer->pauseOnExceptionsState();
    80     if (doNotPauseOnExceptions && *doNotPauseOnExceptions && presentState != ScriptDebugServer::DontPauseOnExceptions) {
     85    if (asBool(doNotPauseOnExceptions) && presentState != ScriptDebugServer::DontPauseOnExceptions) {
    8186        m_scriptDebugServer->setPauseOnExceptionsState(ScriptDebugServer::DontPauseOnExceptions);
    8287        pauseStateChanged = true;
     
    8489#endif
    8590
    86     injectedScript.evaluate(errorString, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, result, wasThrown);
     91    injectedScript.evaluate(errorString, expression, objectGroup ? *objectGroup : "", asBool(includeCommandLineAPI), asBool(sendResultByValue), result, wasThrown);
    8792
    8893#if ENABLE(JAVASCRIPT_DEBUGGER)
     
    9297}
    9398
    94 void InspectorRuntimeAgent::callFunctionOn(ErrorString* errorString, const String& objectId, const String& expression, const RefPtr<InspectorArray>* const optionalArguments, RefPtr<InspectorObject>* result, bool* wasThrown)
     99void InspectorRuntimeAgent::callFunctionOn(ErrorString* errorString, const String& objectId, const String& expression, const RefPtr<InspectorArray>* const optionalArguments, const bool* const sendResultByValue, RefPtr<InspectorObject>* result, bool* wasThrown)
    95100{
    96101    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
     
    102107    if (optionalArguments)
    103108        arguments = (*optionalArguments)->toJSONString();
    104     injectedScript.callFunctionOn(errorString, objectId, expression, arguments, result, wasThrown);
     109    injectedScript.callFunctionOn(errorString, objectId, expression, arguments, asBool(sendResultByValue), result, wasThrown);
    105110}
    106111
  • trunk/Source/WebCore/inspector/InspectorRuntimeAgent.h

    r91956 r92122  
    5454
    5555    // Part of the protocol.
    56     void evaluate(ErrorString*, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptions, const String* const frameId, RefPtr<InspectorObject>* result, bool* wasThrown);
    57     void callFunctionOn(ErrorString*, const String& objectId, const String& expression, const RefPtr<InspectorArray>* const optionalArguments, RefPtr<InspectorObject>* result, bool* wasThrown);
     56    void evaluate(ErrorString*,
     57                  const String& expression,
     58                  const String* const objectGroup,
     59                  const bool* const includeCommandLineAPI,
     60                  const bool* const doNotPauseOnExceptions,
     61                  const String* const frameId,
     62                  const bool* const sendResultByValue,
     63                  RefPtr<InspectorObject>* result,
     64                  bool* wasThrown);
     65    void callFunctionOn(ErrorString*,
     66                        const String& objectId,
     67                        const String& expression,
     68                        const RefPtr<InspectorArray>* const optionalArguments,
     69                        const bool* const sendResultByValue,
     70                        RefPtr<InspectorObject>* result,
     71                        bool* wasThrown);
    5872    void releaseObject(ErrorString*, const String& objectId);
    5973    void getProperties(ErrorString*, const String& objectId, bool ignoreHasOwnProperty, RefPtr<InspectorArray>* result);
  • trunk/Source/WebCore/inspector/front-end/ConsoleView.js

    r91839 r92122  
    409409            WebInspector.panels.scripts.getSelectedCallFrameVariables(reportCompletions.bind(this));
    410410        else
    411             this.evalInInspectedWindow(expressionString, "completion", true, true, evaluated.bind(this));
     411            this.evalInInspectedWindow(expressionString, "completion", true, true, undefined, evaluated.bind(this));
    412412
    413413        function evaluated(result, wasThrown)
     
    415415            if (wasThrown)
    416416                return;
    417             result.getAllProperties(evaluatedProperties.bind(this));
    418         }
    419 
    420         function evaluatedProperties(properties)
     417            var getCompletions = function()
     418            {
     419                var resultSet = {};
     420                for (var o = this; o; o = o.__proto__) {
     421                    try {
     422                        var names = Object.getOwnPropertyNames(o);
     423                        for (var i = 0; i < names.length; ++i)
     424                            resultSet[names[i]] = true;
     425                    } catch (e) {
     426                    }
     427                }
     428                return resultSet;
     429            }
     430            result.callFunctionJSON(getCompletions, receivedPropertyNames.bind(this));
     431        }
     432
     433        function receivedPropertyNames(propertyNames)
    421434        {
    422435            RuntimeAgent.releaseObjectGroup("completion");
    423             var propertyNames = {};
    424             for (var i = 0; properties && i < properties.length; ++i)
    425                 propertyNames[properties[i].name] = true;
    426             reportCompletions.call(this, propertyNames);
    427         }
    428 
    429         function reportCompletions(propertyNames)
    430         {
     436            if (!propertyNames)
     437                return;
    431438            var includeCommandLineAPI = (!dotNotation && !bracketNotation);
    432439            if (includeCommandLineAPI) {
     
    596603    },
    597604
    598     evalInInspectedWindow: function(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptions, callback)
     605    evalInInspectedWindow: function(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptions, evalAsJSONValue, callback)
    599606    {
    600607        if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused) {
     
    613620                callback(WebInspector.RemoteObject.fromPayload(result), wasThrown);
    614621        }
    615         RuntimeAgent.evaluate(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptions, this._currentEvaluationContextId(), evalCallback);
     622        RuntimeAgent.evaluate(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptions, this._currentEvaluationContextId(), evalAsJSONValue, evalCallback);
    616623    },
    617624
     
    644651            self.addMessage(new WebInspector.ConsoleCommandResult(result, wasThrown, commandMessage));
    645652        }
    646         this.evalInInspectedWindow(str, "console", true, undefined, printResult);
     653        this.evalInInspectedWindow(str, "console", true, undefined, undefined, printResult);
    647654
    648655        WebInspector.userMetrics.ConsoleEvaluated.record();
  • trunk/Source/WebCore/inspector/front-end/RemoteObject.js

    r91750 r92122  
    195195        }
    196196
    197         RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), undefined, mycallback);
     197        RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), undefined, undefined, mycallback);
     198    },
     199
     200    callFunctionJSON: function(functionDeclaration, callback)
     201    {
     202        function mycallback(error, result, wasThrown)
     203        {
     204            callback((error || wasThrown) ? null : result.value);
     205        }
     206
     207        RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), undefined, true, mycallback);
    198208    },
    199209
  • trunk/Source/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js

    r91176 r92122  
    160160                continue;
    161161
    162             WebInspector.console.evalInInspectedWindow(expression, this._watchObjectGroupId, false, true, appendResult.bind(this, expression, i));
     162            WebInspector.console.evalInInspectedWindow(expression, this._watchObjectGroupId, false, true, undefined, appendResult.bind(this, expression, i));
    163163        }
    164164
Note: See TracChangeset for help on using the changeset viewer.