1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * Copyright (C) 2012 Google Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include "config.h" 33 #include "InjectedScript.h" 34 35 #include "InspectorValues.h" 36 #include "JSCInlines.h" 37 #include "ScriptFunctionCall.h" 38 #include "ScriptObject.h" 39 #include <wtf/text/WTFString.h> 40 41 using Inspector::Protocol::Array; 42 43 namespace Inspector { 44 45 InjectedScript::InjectedScript() 46 : InjectedScriptBase(ASCIILiteral("InjectedScript")) 47 { 48 } 49 50 InjectedScript::InjectedScript(Deprecated::ScriptObject injectedScriptObject, InspectorEnvironment* environment) 51 : InjectedScriptBase(ASCIILiteral("InjectedScript"), injectedScriptObject, environment) 52 { 53 } 54 55 InjectedScript::~InjectedScript() 56 { 57 } 58 59 void InjectedScript::evaluate(ErrorString& errorString, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Inspector::Protocol::Runtime::RemoteObject>* result, Inspector::Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex) 60 { 61 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("evaluate"), inspectorEnvironment()->functionCallHandler()); 62 function.appendArgument(expression); 63 function.appendArgument(objectGroup); 64 function.appendArgument(includeCommandLineAPI); 65 function.appendArgument(returnByValue); 66 function.appendArgument(generatePreview); 67 function.appendArgument(saveResult); 68 makeEvalCall(errorString, function, result, wasThrown, savedResultIndex); 69 } 70 71 void InjectedScript::callFunctionOn(ErrorString& errorString, const String& objectId, const String& expression, const String& arguments, bool returnByValue, bool generatePreview, RefPtr<Inspector::Protocol::Runtime::RemoteObject>* result, Inspector::Protocol::OptOutput<bool>* wasThrown) 72 { 73 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("callFunctionOn"), inspectorEnvironment()->functionCallHandler()); 74 function.appendArgument(objectId); 75 function.appendArgument(expression); 76 function.appendArgument(arguments); 77 function.appendArgument(returnByValue); 78 function.appendArgument(generatePreview); 79 makeEvalCall(errorString, function, result, wasThrown); 80 } 81 82 void InjectedScript::evaluateOnCallFrame(ErrorString& errorString, const Deprecated::ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, bool saveResult, RefPtr<Inspector::Protocol::Runtime::RemoteObject>* result, Inspector::Protocol::OptOutput<bool>* wasThrown, Inspector::Protocol::OptOutput<int>* savedResultIndex) 83 { 84 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("evaluateOnCallFrame"), inspectorEnvironment()->functionCallHandler()); 85 function.appendArgument(callFrames); 86 function.appendArgument(callFrameId); 87 function.appendArgument(expression); 88 function.appendArgument(objectGroup); 89 function.appendArgument(includeCommandLineAPI); 90 function.appendArgument(returnByValue); 91 function.appendArgument(generatePreview); 92 function.appendArgument(saveResult); 93 makeEvalCall(errorString, function, result, wasThrown, savedResultIndex); 94 } 95 96 void InjectedScript::getFunctionDetails(ErrorString& errorString, const String& functionId, RefPtr<Inspector::Protocol::Debugger::FunctionDetails>* result) 97 { 98 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getFunctionDetails"), inspectorEnvironment()->functionCallHandler()); 99 function.appendArgument(functionId); 100 101 RefPtr<InspectorValue> resultValue; 102 makeCall(function, &resultValue); 103 if (!resultValue || resultValue->type() != InspectorValue::Type::Object) { 104 if (!resultValue->asString(errorString)) 105 errorString = ASCIILiteral("Internal error"); 106 return; 107 } 108 109 *result = BindingTraits<Inspector::Protocol::Debugger::FunctionDetails>::runtimeCast(WTF::move(resultValue)); 110 } 111 112 void InjectedScript::getProperties(ErrorString& errorString, const String& objectId, bool ownProperties, bool generatePreview, RefPtr<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>* properties) 113 { 114 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getProperties"), inspectorEnvironment()->functionCallHandler()); 115 function.appendArgument(objectId); 116 function.appendArgument(ownProperties); 117 function.appendArgument(generatePreview); 118 119 RefPtr<InspectorValue> result; 120 makeCall(function, &result); 121 if (!result || result->type() != InspectorValue::Type::Array) { 122 errorString = ASCIILiteral("Internal error"); 123 return; 124 } 125 126 *properties = BindingTraits<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>::runtimeCast(WTF::move(result)); 127 } 128 129 void InjectedScript::getDisplayableProperties(ErrorString& errorString, const String& objectId, bool generatePreview, RefPtr<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>* properties) 130 { 131 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getDisplayableProperties"), inspectorEnvironment()->functionCallHandler()); 132 function.appendArgument(objectId); 133 function.appendArgument(generatePreview); 134 135 RefPtr<InspectorValue> result; 136 makeCall(function, &result); 137 if (!result || result->type() != InspectorValue::Type::Array) { 138 errorString = ASCIILiteral("Internal error"); 139 return; 140 } 141 142 *properties = BindingTraits<Array<Inspector::Protocol::Runtime::PropertyDescriptor>>::runtimeCast(WTF::move(result)); 143 } 144 145 void InjectedScript::getInternalProperties(ErrorString& errorString, const String& objectId, bool generatePreview, RefPtr<Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>* properties) 146 { 147 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getInternalProperties"), inspectorEnvironment()->functionCallHandler()); 148 function.appendArgument(objectId); 149 function.appendArgument(generatePreview); 150 151 RefPtr<InspectorValue> result; 152 makeCall(function, &result); 153 if (!result || result->type() != InspectorValue::Type::Array) { 154 errorString = ASCIILiteral("Internal error"); 155 return; 156 } 157 158 auto array = BindingTraits<Array<Inspector::Protocol::Runtime::InternalPropertyDescriptor>>::runtimeCast(WTF::move(result)); 159 *properties = array->length() > 0 ? array : nullptr; 160 } 161 162 void InjectedScript::getCollectionEntries(ErrorString& errorString, const String& objectId, const String& objectGroup, int startIndex, int numberToFetch, RefPtr<Protocol::Array<Protocol::Runtime::CollectionEntry>>* entries) 163 { 164 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("getCollectionEntries"), inspectorEnvironment()->functionCallHandler()); 165 function.appendArgument(objectId); 166 function.appendArgument(objectGroup); 167 function.appendArgument(startIndex); 168 function.appendArgument(numberToFetch); 169 170 RefPtr<InspectorValue> result; 171 makeCall(function, &result); 172 if (!result || result->type() != InspectorValue::Type::Array) { 173 errorString = ASCIILiteral("Internal error"); 174 return; 175 } 176 177 *entries = BindingTraits<Array<Protocol::Runtime::CollectionEntry>>::runtimeCast(WTF::move(result)); 178 } 179 180 void InjectedScript::saveResult(ErrorString& errorString, const String& callArgumentJSON, Inspector::Protocol::OptOutput<int>* savedResultIndex) 181 { 182 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("saveResult"), inspectorEnvironment()->functionCallHandler()); 183 function.appendArgument(callArgumentJSON); 184 185 RefPtr<InspectorValue> result; 186 makeCall(function, &result); 187 if (!result || result->type() != InspectorValue::Type::Integer) { 188 errorString = ASCIILiteral("Internal error"); 189 return; 190 } 191 192 int savedResultIndexInt = 0; 193 if (result->asInteger(savedResultIndexInt) && savedResultIndexInt > 0) 194 *savedResultIndex = savedResultIndexInt; 195 } 196 197 Ref<Array<Inspector::Protocol::Debugger::CallFrame>> InjectedScript::wrapCallFrames(const Deprecated::ScriptValue& callFrames) 198 { 199 ASSERT(!hasNoValue()); 200 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("wrapCallFrames"), inspectorEnvironment()->functionCallHandler()); 201 function.appendArgument(callFrames); 202 203 bool hadException = false; 204 Deprecated::ScriptValue callFramesValue = callFunctionWithEvalEnabled(function, hadException); 205 ASSERT(!hadException); 206 RefPtr<InspectorValue> result = callFramesValue.toInspectorValue(scriptState()); 207 if (result->type() == InspectorValue::Type::Array) 208 return BindingTraits<Array<Inspector::Protocol::Debugger::CallFrame>>::runtimeCast(WTF::move(result)).releaseNonNull(); 209 210 return Array<Inspector::Protocol::Debugger::CallFrame>::create(); 211 } 212 213 RefPtr<Inspector::Protocol::Runtime::RemoteObject> InjectedScript::wrapObject(const Deprecated::ScriptValue& value, const String& groupName, bool generatePreview) const 214 { 215 ASSERT(!hasNoValue()); 216 Deprecated::ScriptFunctionCall wrapFunction(injectedScriptObject(), ASCIILiteral("wrapObject"), inspectorEnvironment()->functionCallHandler()); 217 wrapFunction.appendArgument(value); 218 wrapFunction.appendArgument(groupName); 219 wrapFunction.appendArgument(hasAccessToInspectedScriptState()); 220 wrapFunction.appendArgument(generatePreview); 221 222 bool hadException = false; 223 Deprecated::ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException); 224 if (hadException) 225 return nullptr; 226 227 RefPtr<InspectorObject> resultObject; 228 bool castSucceeded = r.toInspectorValue(scriptState())->asObject(resultObject); 229 ASSERT_UNUSED(castSucceeded, castSucceeded); 230 231 return BindingTraits<Inspector::Protocol::Runtime::RemoteObject>::runtimeCast(resultObject); 232 } 233 234 RefPtr<Inspector::Protocol::Runtime::RemoteObject> InjectedScript::wrapTable(const Deprecated::ScriptValue& table, const Deprecated::ScriptValue& columns) const 235 { 236 ASSERT(!hasNoValue()); 237 Deprecated::ScriptFunctionCall wrapFunction(injectedScriptObject(), ASCIILiteral("wrapTable"), inspectorEnvironment()->functionCallHandler()); 238 wrapFunction.appendArgument(hasAccessToInspectedScriptState()); 239 wrapFunction.appendArgument(table); 240 if (columns.hasNoValue()) 241 wrapFunction.appendArgument(false); 242 else 243 wrapFunction.appendArgument(columns); 244 245 bool hadException = false; 246 Deprecated::ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException); 247 if (hadException) 248 return nullptr; 249 250 RefPtr<InspectorObject> resultObject; 251 bool castSucceeded = r.toInspectorValue(scriptState())->asObject(resultObject); 252 ASSERT_UNUSED(castSucceeded, castSucceeded); 253 254 return BindingTraits<Inspector::Protocol::Runtime::RemoteObject>::runtimeCast(resultObject); 255 } 256 257 void InjectedScript::setExceptionValue(const Deprecated::ScriptValue& value) 258 { 259 ASSERT(!hasNoValue()); 260 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("setExceptionValue"), inspectorEnvironment()->functionCallHandler()); 261 function.appendArgument(value); 262 RefPtr<InspectorValue> result; 263 makeCall(function, &result); 264 } 265 266 void InjectedScript::clearExceptionValue() 267 { 268 ASSERT(!hasNoValue()); 269 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("clearExceptionValue"), inspectorEnvironment()->functionCallHandler()); 270 RefPtr<InspectorValue> result; 271 makeCall(function, &result); 272 } 273 274 Deprecated::ScriptValue InjectedScript::findObjectById(const String& objectId) const 275 { 276 ASSERT(!hasNoValue()); 277 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("findObjectById"), inspectorEnvironment()->functionCallHandler()); 278 function.appendArgument(objectId); 279 280 bool hadException = false; 281 Deprecated::ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException); 282 ASSERT(!hadException); 283 284 return resultValue; 285 } 286 287 void InjectedScript::inspectObject(Deprecated::ScriptValue value) 288 { 289 ASSERT(!hasNoValue()); 290 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("inspectObject"), inspectorEnvironment()->functionCallHandler()); 291 function.appendArgument(value); 292 RefPtr<InspectorValue> result; 293 makeCall(function, &result); 294 } 295 296 void InjectedScript::releaseObject(const String& objectId) 297 { 298 Deprecated::ScriptFunctionCall function(injectedScriptObject(), ASCIILiteral("releaseObject"), inspectorEnvironment()->functionCallHandler()); 299 function.appendArgument(objectId); 300 RefPtr<InspectorValue> result; 301 makeCall(function, &result); 302 } 303 304 void InjectedScript::releaseObjectGroup(const String& objectGroup) 305 { 306 ASSERT(!hasNoValue()); 307 // JDK-8164076 308 if (hasNoValue()) 309 return; 310 311 Deprecated::ScriptFunctionCall releaseFunction(injectedScriptObject(), ASCIILiteral("releaseObjectGroup"), inspectorEnvironment()->functionCallHandler()); 312 releaseFunction.appendArgument(objectGroup); 313 314 bool hadException = false; 315 callFunctionWithEvalEnabled(releaseFunction, hadException); 316 ASSERT(!hadException); 317 } 318 319 } // namespace Inspector 320