void InspectorDebuggerAgent::runScript(ErrorString* errorString, const ScriptId& scriptId, const int* executionContextId, const String* const objectGroup, const bool* const doNotPauseOnExceptionsAndMuteConsole, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown) { InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId); if (injectedScript.hasNoValue()) { *errorString = "Inspected frame has gone"; return; } ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = scriptDebugServer().pauseOnExceptionsState(); if (doNotPauseOnExceptionsAndMuteConsole && *doNotPauseOnExceptionsAndMuteConsole) { if (previousPauseOnExceptionsState != ScriptDebugServer::DontPauseOnExceptions) scriptDebugServer().setPauseOnExceptionsState(ScriptDebugServer::DontPauseOnExceptions); muteConsole(); } ScriptValue value; bool wasThrownValue; String exceptionMessage; scriptDebugServer().runScript(injectedScript.scriptState(), scriptId, &value, &wasThrownValue, &exceptionMessage); *wasThrown = wasThrownValue; if (value.hasNoValue()) { *errorString = "Script execution failed"; return; } result = injectedScript.wrapObject(value, objectGroup ? *objectGroup : ""); if (wasThrownValue) result->setDescription(exceptionMessage); if (doNotPauseOnExceptionsAndMuteConsole && *doNotPauseOnExceptionsAndMuteConsole) { unmuteConsole(); if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnExceptionsState) scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExceptionsState); } }
bool InspectorFrontendClientLocal::evaluateAsBoolean(const String& expression) { if (!m_frontendPage->mainFrame()) return false; ScriptValue value = m_frontendPage->mainFrame()->script()->executeScript(expression); return value.toString(mainWorldScriptState(m_frontendPage->mainFrame())) == "true"; }
static JSC::JSValue handleInitMessageEvent(JSMessageEvent* jsEvent, JSC::ExecState* exec) { const String& typeArg = exec->argument(0).toString(exec)->value(exec); bool canBubbleArg = exec->argument(1).toBoolean(exec); bool cancelableArg = exec->argument(2).toBoolean(exec); const String originArg = exec->argument(4).toString(exec)->value(exec); const String lastEventIdArg = exec->argument(5).toString(exec)->value(exec); DOMWindow* sourceArg = toDOMWindow(exec->argument(6)); OwnPtr<MessagePortArray> messagePorts; OwnPtr<ArrayBufferArray> arrayBuffers; if (!exec->argument(7).isUndefinedOrNull()) { messagePorts = adoptPtr(new MessagePortArray); arrayBuffers = adoptPtr(new ArrayBufferArray); fillMessagePortArray(exec, exec->argument(7), *messagePorts, *arrayBuffers); if (exec->hadException()) return jsUndefined(); } ScriptValue dataArg = ScriptValue(exec->vm(), exec->argument(3)); if (exec->hadException()) return jsUndefined(); MessageEvent* event = static_cast<MessageEvent*>(jsEvent->impl()); event->initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, sourceArg, messagePorts.release()); jsEvent->m_data.set(exec->vm(), jsEvent, dataArg.jsValue()); return jsUndefined(); }
ScriptPreprocessor::ScriptPreprocessor(const ScriptSourceCode& preprocessorSourceCode, Frame* frame) : m_isolate(V8PerIsolateData::mainThreadIsolate()) , m_isPreprocessing(false) { ASSERT(frame); v8::TryCatch tryCatch; tryCatch.SetVerbose(true); Vector<ScriptSourceCode> sources; sources.append(preprocessorSourceCode); Vector<ScriptValue> scriptResults; frame->script().executeScriptInIsolatedWorld(ScriptPreprocessorIsolatedWorldId, sources, DOMWrapperWorld::mainWorldExtensionGroup, &scriptResults); if (scriptResults.size() != 1) { frame->host()->console().addMessage(JSMessageSource, ErrorMessageLevel, "ScriptPreprocessor internal error, one ScriptSourceCode must give exactly one result."); return; } ScriptValue preprocessorFunction = scriptResults[0]; if (!preprocessorFunction.isFunction()) { frame->host()->console().addMessage(JSMessageSource, ErrorMessageLevel, "The preprocessor must compile to a function."); return; } m_world = DOMWrapperWorld::ensureIsolatedWorld(ScriptPreprocessorIsolatedWorldId, DOMWrapperWorld::mainWorldExtensionGroup); v8::Local<v8::Context> context = toV8Context(m_isolate, frame, m_world.get()); m_context.set(m_isolate, context); m_preprocessorFunction.set(m_isolate, v8::Handle<v8::Function>::Cast(preprocessorFunction.v8Value())); }
PassRefPtr<Intent> Intent::create(ScriptState* scriptState, const Dictionary& options, ExceptionCode& ec) { String action; if (!options.get("action", action) || action.isEmpty()) { ec = SYNTAX_ERR; return 0; } String type; if (!options.get("type", type) || type.isEmpty()) { ec = SYNTAX_ERR; return 0; } String service; KURL serviceUrl; if (options.get("service", service) && !service.isEmpty()) { serviceUrl = KURL(KURL(), service); if (!serviceUrl.isValid()) { ec = SYNTAX_ERR; return 0; } } MessagePortArray ports; OwnPtr<MessagePortChannelArray> channels; if (options.get("transfer", ports)) channels = MessagePort::disentanglePorts(&ports, ec); ScriptValue dataValue; RefPtr<SerializedScriptValue> serializedData; if (options.get("data", dataValue)) { bool didThrow = false; serializedData = dataValue.serialize(scriptState, &ports, 0, didThrow); if (didThrow) { ec = DATA_CLONE_ERR; return 0; } } HashMap<String, String> extras; Dictionary extrasDictionary; if (options.get("extras", extrasDictionary)) extrasDictionary.getOwnPropertiesAsStringHashMap(extras); HashSet<AtomicString> suggestionsStrings; Vector<KURL> suggestions; if (options.get("suggestions", suggestionsStrings)) { for (HashSet<AtomicString>::iterator iter = suggestionsStrings.begin(); iter != suggestionsStrings.end(); ++iter) { KURL suggestedURL = KURL(KURL(), *iter); if (!suggestedURL.isValid()) { ec = SYNTAX_ERR; return 0; } suggestions.append(suggestedURL); } } return adoptRef(new Intent(action, type, serializedData.release(), channels.release(), extras, serviceUrl, suggestions)); }
Response* Response::create(ScriptState* scriptState, ScriptValue bodyValue, const Dictionary& init, ExceptionState& exceptionState) { v8::Local<v8::Value> body = bodyValue.v8Value(); ScriptValue reader; v8::Isolate* isolate = scriptState->isolate(); ExecutionContext* executionContext = scriptState->executionContext(); OwnPtr<FetchDataConsumerHandle> bodyHandle; String contentType; if (bodyValue.isUndefined() || bodyValue.isNull()) { // Note: The IDL processor cannot handle this situation. See // https://crbug.com/335871. } else if (V8Blob::hasInstance(body, isolate)) { Blob* blob = V8Blob::toImpl(body.As<v8::Object>()); bodyHandle = FetchBlobDataConsumerHandle::create(executionContext, blob->blobDataHandle()); contentType = blob->type(); } else if (V8ArrayBuffer::hasInstance(body, isolate)) { bodyHandle = FetchFormDataConsumerHandle::create(V8ArrayBuffer::toImpl(body.As<v8::Object>())); } else if (V8ArrayBufferView::hasInstance(body, isolate)) { bodyHandle = FetchFormDataConsumerHandle::create(V8ArrayBufferView::toImpl(body.As<v8::Object>())); } else if (V8FormData::hasInstance(body, isolate)) { RefPtr<EncodedFormData> formData = V8FormData::toImpl(body.As<v8::Object>())->encodeMultiPartFormData(); // Here we handle formData->boundary() as a C-style string. See // FormDataEncoder::generateUniqueBoundaryString. contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + formData->boundary().data(); bodyHandle = FetchFormDataConsumerHandle::create(executionContext, formData.release()); } else if (RuntimeEnabledFeatures::responseConstructedWithReadableStreamEnabled() && ReadableStreamOperations::isReadableStream(scriptState, bodyValue)) { bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, bodyValue); reader = ReadableStreamOperations::getReader(scriptState, bodyValue, exceptionState); if (exceptionState.hadException()) { reader = ScriptValue(); bodyHandle = createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorDataConsumerHandle()); exceptionState.clearException(); } else { bodyHandle = ReadableStreamDataConsumerHandle::create(scriptState, reader); } } else { String string = toUSVString(isolate, body, exceptionState); if (exceptionState.hadException()) return nullptr; bodyHandle = FetchFormDataConsumerHandle::create(string); contentType = "text/plain;charset=UTF-8"; } // TODO(yhirano): Add the URLSearchParams case. Response* response = create(executionContext, bodyHandle.release(), contentType, ResponseInit(init, exceptionState), exceptionState); if (!exceptionState.hadException() && !reader.isEmpty()) { // Add a hidden reference so that the weak persistent in the // ReadableStreamDataConsumerHandle will be valid as long as the // Response is valid. v8::Local<v8::Value> wrapper = toV8(response, scriptState); if (wrapper.IsEmpty()) { exceptionState.throwTypeError("Cannot create a Response wrapper"); return nullptr; } ASSERT(wrapper->IsObject()); V8HiddenValue::setHiddenValue(scriptState, wrapper.As<v8::Object>(), V8HiddenValue::readableStreamReaderInResponse(scriptState->isolate()), reader.v8Value()); } return response; }
void ScriptFunction::callCallback( const v8::FunctionCallbackInfo<v8::Value>& args) { ASSERT(args.Data()->IsExternal()); ScriptFunction* scriptFunction = static_cast<ScriptFunction*>( v8::Local<v8::External>::Cast(args.Data())->Value()); ScriptValue result = scriptFunction->call( ScriptValue(scriptFunction->getScriptState(), args[0])); v8SetReturnValue(args, result.v8Value()); }
void IDBCursor::continueFunction(ScriptState* scriptState, const ScriptValue& keyValue, ExceptionState& exceptionState) { IDB_TRACE("IDBCursor::continue"); IDBKey* key = keyValue.isUndefined() || keyValue.isNull() ? nullptr : scriptValueToIDBKey(scriptState->isolate(), keyValue); if (key && !key->isValid()) { exceptionState.throwDOMException(DataError, IDBDatabase::notValidKeyErrorMessage); return; } continueFunction(key, 0, exceptionState); }
bool ReadableStreamOperations::isReadableStreamReader(ScriptState* scriptState, ScriptValue value) { ASSERT(!value.isEmpty()); if (!value.isObject()) return false; v8::Local<v8::Value> args[] = { value.v8Value() }; return V8ScriptRunner::callExtraOrCrash(scriptState, "IsReadableStreamReader", args)->ToBoolean()->Value(); }
void IDBCursor::continueFunction(ExecutionContext* context, const ScriptValue& keyValue, ExceptionState& exceptionState) { IDB_TRACE("IDBCursor::continue"); RefPtrWillBeRawPtr<IDBKey> key = keyValue.isUndefined() || keyValue.isNull() ? nullptr : scriptValueToIDBKey(toIsolate(context), keyValue); if (key && !key->isValid()) { exceptionState.throwDOMException(DataError, IDBDatabase::notValidKeyErrorMessage); return; } continueFunction(key.release(), nullptr, exceptionState); }
ScheduledAction::ScheduledAction(ScriptState* scriptState, const ScriptValue& function, const Vector<ScriptValue>& arguments) : m_scriptState(scriptState) , m_info(scriptState->isolate()) , m_code(String(), KURL(), TextPosition::belowRangePosition()) { ASSERT(function.isFunction()); m_function.set(scriptState->isolate(), v8::Handle<v8::Function>::Cast(function.v8Value())); m_info.ReserveCapacity(arguments.size()); for (const ScriptValue& argument : arguments) m_info.Append(argument.v8Value()); }
PassRefPtr<InspectorArray> InjectedScript::wrapCallFrames(const ScriptValue& callFrames) { ASSERT(!hasNoValue()); ScriptFunctionCall function(m_injectedScriptObject, "wrapCallFrames"); function.appendArgument(callFrames); ScriptValue callFramesValue = function.call(); RefPtr<InspectorValue> result = callFramesValue.toInspectorValue(m_injectedScriptObject.scriptState()); if (result->type() == InspectorValue::TypeArray) return result->asArray(); return InspectorArray::create(); }
void ScriptFunction::callCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::Isolate* isolate = args.GetIsolate(); ASSERT(!args.Data().IsEmpty()); ScriptFunction* function = ScriptFunction::Cast(args.Data()); v8::Local<v8::Value> value = args.Length() > 0 ? args[0] : v8::Local<v8::Value>(v8::Undefined(isolate)); ScriptValue result = function->call(ScriptValue(ScriptState::current(isolate), value)); v8SetReturnValue(args, result.v8Value()); }
v8::Handle<v8::Value> WebDocument::registerEmbedderCustomElement(const WebString& name, v8::Handle<v8::Value> options, WebExceptionCode& ec) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); Document* document = unwrap<Document>(); Dictionary dictionary(options, isolate); TrackExceptionState exceptionState; ScriptValue constructor = document->registerElement(ScriptState::current(isolate), name, dictionary, exceptionState, CustomElement::EmbedderNames); ec = exceptionState.code(); if (exceptionState.hadException()) return v8::Handle<v8::Value>(); return constructor.v8Value(); }
ScriptObject InjectedScriptCanvasModule::callWrapContextFunction(const String& functionName, const ScriptObject& context) { ScriptFunctionCall function(injectedScriptObject(), functionName); function.appendArgument(context); bool hadException = false; ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException); if (hadException || resultValue.hasNoValue() || !resultValue.isObject()) { ASSERT_NOT_REACHED(); return ScriptObject(); } return ScriptObject(context.scriptState(), resultValue); }
ScriptPromise::ScriptPromise(const ScriptValue& value) { if (value.hasNoValue()) return; v8::Local<v8::Value> v8Value(value.v8Value()); v8::Isolate* isolate = value.isolate(); if (V8PromiseCustom::isPromise(v8Value, isolate)) { m_promise = value; return; } m_promise = ScriptValue(V8PromiseCustom::toPromise(v8Value, isolate), isolate); }
void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) { if (isExecutionForbidden()) return; ScriptValue exception; evaluate(sourceCode, &exception); if (exception.jsValue()) { JSLockHolder lock(vm()); reportException(m_workerContextWrapper->globalExec(), exception.jsValue()); } }
PassRefPtr<SerializedScriptValue> InjectedScript::wrapForConsole(ScriptValue value) { ASSERT(!hasNoValue()); ScriptFunctionCall wrapFunction(m_injectedScriptObject, "wrapObjectForConsole"); wrapFunction.appendArgument(value); wrapFunction.appendArgument(canAccessInspectedWindow()); bool hadException = false; ScriptValue r = wrapFunction.call(hadException); if (hadException) return SerializedScriptValue::create("<exception>"); return r.serialize(m_injectedScriptObject.scriptState()); }
void DevToolsHost::showContextMenu(LocalFrame* targetFrame, float x, float y, const Vector<ContextMenuItem>& items) { ASSERT(m_frontendFrame); ScriptState* frontendScriptState = ScriptState::forMainWorld(m_frontendFrame); ScriptValue devtoolsApiObject = frontendScriptState->getFromGlobalObject("DevToolsAPI"); ASSERT(devtoolsApiObject.isObject()); RefPtrWillBeRawPtr<FrontendMenuProvider> menuProvider = FrontendMenuProvider::create(this, devtoolsApiObject, items); m_menuProvider = menuProvider.get(); float zoom = targetFrame->pageZoomFactor(); if (m_client) m_client->showContextMenu(targetFrame, x * zoom, y * zoom, menuProvider); }
ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) { if (isExecutionForbidden()) return ScriptValue(); ScriptValue exception; ScriptValue result(evaluate(sourceCode, &exception)); if (exception.jsValue()) { JSLock lock(SilenceAssertionsOnly); reportException(m_workerContextWrapper->globalExec(), exception.jsValue()); } return result; }
PassRefPtr<Array<CallFrame> > InjectedScript::wrapCallFrames(const ScriptValue& callFrames) { ASSERT(!hasNoValue()); ScriptFunctionCall function(m_injectedScriptObject, "wrapCallFrames"); function.appendArgument(callFrames); bool hadException = false; ScriptValue callFramesValue = callFunctionWithEvalEnabled(function, hadException); ASSERT(!hadException); RefPtr<InspectorValue> result = callFramesValue.toInspectorValue(m_injectedScriptObject.scriptState()); if (result->type() == InspectorValue::TypeArray) return Array<CallFrame>::runtimeCast(result); return Array<CallFrame>::create(); }
void V8XMLHttpRequest::responseTextAttributeGetterCustom(const v8::PropertyCallbackInfo<v8::Value>& info) { XMLHttpRequest* xmlHttpRequest = V8XMLHttpRequest::toNative(info.Holder()); ExceptionState exceptionState(ExceptionState::GetterContext, "responseText", "XMLHttpRequest", info.Holder(), info.GetIsolate()); ScriptValue text = xmlHttpRequest->responseText(exceptionState); if (exceptionState.throwIfNeeded()) return; if (text.hasNoValue()) { v8SetReturnValueString(info, emptyString(), info.GetIsolate()); return; } v8SetReturnValue(info, text.v8Value()); }
bool ScriptController::executeIfJavaScriptURL(const KURL& url, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL) { if (!protocolIsJavaScript(url)) return false; if (!m_frame->page() || !m_frame->page()->javaScriptURLsAreAllowed() || !m_frame->document()->contentSecurityPolicy()->allowJavaScriptURLs() || m_frame->inViewSourceMode()) return true; // We need to hold onto the Frame here because executing script can // destroy the frame. RefPtr<Frame> protector(m_frame); RefPtr<Document> ownerDocument(m_frame->document()); const int javascriptSchemeLength = sizeof("javascript:") - 1; String decodedURL = decodeURLEscapeSequences(url.string()); ScriptValue result = executeScript(decodedURL.substring(javascriptSchemeLength)); // If executing script caused this frame to be removed from the page, we // don't want to try to replace its document! if (!m_frame->page()) return true; String scriptResult; #if USE(JSC) JSDOMWindowShell* shell = windowShell(mainThreadNormalWorld()); JSC::ExecState* exec = shell->window()->globalExec(); if (!result.getString(exec, scriptResult)) return true; #else if (!result.getString(scriptResult)) return true; #endif // FIXME: We should always replace the document, but doing so // synchronously can cause crashes: // http://bugs.webkit.org/show_bug.cgi?id=16782 if (shouldReplaceDocumentIfJavaScriptURL == ReplaceDocumentIfJavaScriptURL) { // We're still in a frame, so there should be a DocumentLoader. ASSERT(m_frame->document()->loader()); // DocumentWriter::replaceDocument can cause the DocumentLoader to get deref'ed and possible destroyed, // so protect it with a RefPtr. if (RefPtr<DocumentLoader> loader = m_frame->document()->loader()) loader->writer()->replaceDocument(scriptResult, ownerDocument.get()); } return true; }
PassRefPtr<Array<CallFrame> > InjectedScript::wrapCallFrames(const ScriptValue& callFrames, int asyncOrdinal) { ASSERT(!isEmpty()); ScriptFunctionCall function(injectedScriptObject(), "wrapCallFrames"); function.appendArgument(callFrames); function.appendArgument(asyncOrdinal); bool hadException = false; ScriptValue callFramesValue = callFunctionWithEvalEnabled(function, hadException); ASSERT(!hadException); RefPtr<JSONValue> result = callFramesValue.toJSONValue(scriptState()); if (result && result->type() == JSONValue::TypeArray) return Array<CallFrame>::runtimeCast(result); return Array<CallFrame>::create(); }
ScriptValue InjectedScript::findCallFrameById(ErrorString* errorString, const ScriptValue& topCallFrame, const String& callFrameId) { ScriptFunctionCall function(injectedScriptObject(), "callFrameForId"); function.appendArgument(topCallFrame); function.appendArgument(callFrameId); bool hadException = false; ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException); ASSERT(!hadException); if (hadException || resultValue.hasNoValue() || !resultValue.isObject()) { *errorString = "Internal error"; return ScriptValue(); } return resultValue; }
ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) { { MutexLocker lock(m_sharedDataMutex); if (m_executionForbidden) return JSValue(); } ScriptValue exception; ScriptValue result = evaluate(sourceCode, &exception); if (exception.jsValue()) { JSLock lock(SilenceAssertionsOnly); reportException(m_workerContextWrapper->globalExec(), exception.jsValue()); } return result; }
void InspectorHeapProfilerAgent::getHeapObjectId(ErrorString* errorString, const String& objectId, String* heapSnapshotObjectId) { InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId); if (injectedScript.hasNoValue()) { *errorString = "Inspected context has gone"; return; } ScriptValue value = injectedScript.findObjectById(objectId); if (value.hasNoValue() || value.isUndefined()) { *errorString = "Object with given id not found"; return; } unsigned id = ScriptProfiler::getHeapObjectId(value); *heapSnapshotObjectId = String::number(id); }
PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapObject(const ScriptValue& value, const String& groupName, bool generatePreview) const { ASSERT(!isEmpty()); ScriptFunctionCall wrapFunction(injectedScriptObject(), "wrapObject"); wrapFunction.appendArgument(value); wrapFunction.appendArgument(groupName); wrapFunction.appendArgument(canAccessInspectedWindow()); wrapFunction.appendArgument(generatePreview); bool hadException = false; ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException); if (hadException) return nullptr; RefPtr<JSONObject> rawResult = r.toJSONValue(scriptState())->asObject(); return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult); }
PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapObject(ScriptValue value, const String& groupName) const { ASSERT(!hasNoValue()); ScriptFunctionCall wrapFunction(m_injectedScriptObject, "wrapObject"); wrapFunction.appendArgument(value); wrapFunction.appendArgument(groupName); wrapFunction.appendArgument(canAccessInspectedWindow()); bool hadException = false; ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException); if (hadException) { return 0; } RefPtr<InspectorObject> rawResult = r.toInspectorValue(m_injectedScriptObject.scriptState())->asObject(); return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult); }
void assertPrimaryKeyValidOrInjectable(ScriptState* scriptState, PassRefPtr<SharedBuffer> buffer, const Vector<blink::WebBlobInfo>* blobInfo, IDBKey* key, const IDBKeyPath& keyPath) { ScriptState::Scope scope(scriptState); v8::Isolate* isolate = scriptState->isolate(); ScriptValue keyValue = idbKeyToScriptValue(scriptState, key); ScriptValue scriptValue(scriptState, deserializeIDBValueBuffer(isolate, buffer.get(), blobInfo)); // This assertion is about already persisted data, so allow experimental types. const bool allowExperimentalTypes = true; IDBKey* expectedKey = createIDBKeyFromScriptValueAndKeyPathInternal(isolate, scriptValue, keyPath, allowExperimentalTypes); ASSERT(!expectedKey || expectedKey->isEqual(key)); bool injected = injectV8KeyIntoV8Value(isolate, keyValue.v8Value(), scriptValue.v8Value(), keyPath); ASSERT_UNUSED(injected, injected); }