Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2085)

Unified Diff: extensions/renderer/api_last_error.cc

Issue 2947463002: [Extensions Bindings] Add a bindings/ subdirectory under renderer (Closed)
Patch Set: . Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « extensions/renderer/api_last_error.h ('k') | extensions/renderer/api_last_error_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/renderer/api_last_error.cc
diff --git a/extensions/renderer/api_last_error.cc b/extensions/renderer/api_last_error.cc
deleted file mode 100644
index fbf516b564331e6eb71cedab574b2c33302a92bb..0000000000000000000000000000000000000000
--- a/extensions/renderer/api_last_error.cc
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "extensions/renderer/api_last_error.h"
-
-#include "gin/converter.h"
-#include "gin/handle.h"
-#include "gin/object_template_builder.h"
-#include "gin/wrappable.h"
-
-namespace extensions {
-
-namespace {
-
-const char kLastErrorProperty[] = "lastError";
-const char kScriptSuppliedValueKey[] = "script_supplied_value";
-
-// The object corresponding to the lastError property, containing a single
-// property ('message') with the last error. This object is stored on the parent
-// (chrome.runtime in production) as a private property, and is returned via an
-// accessor which marks the error as accessed.
-class LastErrorObject final : public gin::Wrappable<LastErrorObject> {
- public:
- explicit LastErrorObject(const std::string& error) : error_(error) {}
-
- static gin::WrapperInfo kWrapperInfo;
-
- // gin::Wrappable:
- gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
- v8::Isolate* isolate) override {
- DCHECK(isolate);
- return Wrappable<LastErrorObject>::GetObjectTemplateBuilder(isolate)
- .SetProperty("message", &LastErrorObject::error);
- }
-
- void Reset(const std::string& error) {
- error_ = error;
- accessed_ = false;
- }
-
- const std::string& error() const { return error_; }
- bool accessed() const { return accessed_; }
- void set_accessed() { accessed_ = true; }
-
- private:
- std::string error_;
- bool accessed_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(LastErrorObject);
-};
-
-gin::WrapperInfo LastErrorObject::kWrapperInfo = {gin::kEmbedderNativeGin};
-
-// An accessor to retrieve the last error property (curried in through data),
-// and mark it as accessed.
-void LastErrorGetter(v8::Local<v8::Name> property,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- v8::Isolate* isolate = info.GetIsolate();
- v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Object> holder = info.Holder();
- v8::Local<v8::Context> context = holder->CreationContext();
-
- v8::Local<v8::Value> last_error;
- v8::Local<v8::Private> last_error_key = v8::Private::ForApi(
- isolate, gin::StringToSymbol(isolate, kLastErrorProperty));
- if (!holder->GetPrivate(context, last_error_key).ToLocal(&last_error) ||
- last_error != info.Data()) {
- // Something funny happened - our private properties aren't set right.
- NOTREACHED();
- return;
- }
-
- v8::Local<v8::Value> return_value;
-
- // It's possible that some script has set their own value for the last error
- // property. If so, return that. Otherwise, return the real last error.
- v8::Local<v8::Private> script_value_key = v8::Private::ForApi(
- isolate, gin::StringToSymbol(isolate, kScriptSuppliedValueKey));
- v8::Local<v8::Value> script_value;
- if (holder->GetPrivate(context, script_value_key).ToLocal(&script_value) &&
- !script_value->IsUndefined()) {
- return_value = script_value;
- } else {
- LastErrorObject* last_error_obj = nullptr;
- CHECK(gin::Converter<LastErrorObject*>::FromV8(isolate, last_error,
- &last_error_obj));
- last_error_obj->set_accessed();
- return_value = last_error;
- }
-
- info.GetReturnValue().Set(return_value);
-}
-
-// Allow script to set the last error property.
-void LastErrorSetter(v8::Local<v8::Name> property,
- v8::Local<v8::Value> value,
- const v8::PropertyCallbackInfo<void>& info) {
- v8::Isolate* isolate = info.GetIsolate();
- v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Object> holder = info.Holder();
- v8::Local<v8::Context> context = holder->CreationContext();
-
- v8::Local<v8::Private> script_value_key = v8::Private::ForApi(
- isolate, gin::StringToSymbol(isolate, kScriptSuppliedValueKey));
- v8::Maybe<bool> set_private =
- holder->SetPrivate(context, script_value_key, value);
- if (!set_private.IsJust() || !set_private.FromJust())
- NOTREACHED();
-}
-
-} // namespace
-
-APILastError::APILastError(const GetParent& get_parent,
- const AddConsoleError& add_console_error)
- : get_parent_(get_parent), add_console_error_(add_console_error) {}
-APILastError::APILastError(APILastError&& other) = default;
-APILastError::~APILastError() = default;
-
-void APILastError::SetError(v8::Local<v8::Context> context,
- const std::string& error) {
- v8::Isolate* isolate = context->GetIsolate();
- DCHECK(isolate);
- v8::HandleScope handle_scope(isolate);
-
- // The various accesses/sets on an object could potentially fail if script has
- // set any crazy interceptors. For the most part, we don't care about behaving
- // perfectly in these circumstances, but we eat the exception so callers don't
- // have to worry about it. We also SetVerbose() so that developers will have a
- // clue what happened if this does arise.
- // TODO(devlin): Whether or not this needs to be verbose is debatable.
- v8::TryCatch try_catch(isolate);
- try_catch.SetVerbose(true);
-
- v8::Local<v8::Object> parent = get_parent_.Run(context);
- if (parent.IsEmpty())
- return;
- v8::Local<v8::String> key = gin::StringToSymbol(isolate, kLastErrorProperty);
- v8::Local<v8::Value> v8_error;
- // Two notes: this Get() is visible to external script, and this will actually
- // mark the lastError as accessed, if one exists. These shouldn't be a
- // problem (lastError is meant to be helpful, but isn't designed to handle
- // crazy chaining, etc). However, if we decide we needed to be fancier, we
- // could detect the presence of a current error through a GetPrivate(), and
- // optionally throw it if one exists.
- if (!parent->Get(context, key).ToLocal(&v8_error))
- return;
-
- if (!v8_error->IsUndefined()) {
- // There may be an existing last error to overwrite.
- LastErrorObject* last_error = nullptr;
- if (!gin::Converter<LastErrorObject*>::FromV8(isolate, v8_error,
- &last_error)) {
- // If it's not a real lastError (e.g. if a script manually set it), don't
- // do anything. We shouldn't mangle a property set by other script.
- // TODO(devlin): Or should we? If someone sets chrome.runtime.lastError,
- // it might be the right course of action to overwrite it.
- return;
- }
- last_error->Reset(error);
- } else {
- v8::Local<v8::Value> last_error =
- gin::CreateHandle(isolate, new LastErrorObject(error)).ToV8();
- v8::Maybe<bool> set_private = parent->SetPrivate(
- context, v8::Private::ForApi(isolate, key), last_error);
- if (!set_private.IsJust() || !set_private.FromJust()) {
- NOTREACHED();
- return;
- }
- DCHECK(!last_error.IsEmpty());
- // This Set() can fail, but there's nothing to do if it does (the exception
- // will be caught by the TryCatch above).
- ignore_result(parent->SetAccessor(context, key, &LastErrorGetter,
- &LastErrorSetter, last_error));
- }
-}
-
-void APILastError::ClearError(v8::Local<v8::Context> context,
- bool report_if_unchecked) {
- v8::Isolate* isolate = context->GetIsolate();
- v8::HandleScope handle_scope(isolate);
-
- v8::Local<v8::Object> parent;
- LastErrorObject* last_error = nullptr;
- v8::Local<v8::String> key;
- v8::Local<v8::Private> private_key;
- {
- // See comment in SetError().
- v8::TryCatch try_catch(isolate);
- try_catch.SetVerbose(true);
-
- parent = get_parent_.Run(context);
- if (parent.IsEmpty())
- return;
- key = gin::StringToSymbol(isolate, kLastErrorProperty);
- private_key = v8::Private::ForApi(isolate, key);
- v8::Local<v8::Value> error;
- // Access through GetPrivate() so that we don't trigger accessed().
- if (!parent->GetPrivate(context, private_key).ToLocal(&error))
- return;
- if (!gin::Converter<LastErrorObject*>::FromV8(context->GetIsolate(), error,
- &last_error)) {
- return;
- }
- }
-
- if (report_if_unchecked && !last_error->accessed()) {
- add_console_error_.Run(
- context, "Unchecked runtime.lastError: " + last_error->error());
- }
-
- // See comment in SetError().
- v8::TryCatch try_catch(isolate);
- try_catch.SetVerbose(true);
-
- v8::Maybe<bool> delete_private = parent->DeletePrivate(context, private_key);
- if (!delete_private.IsJust() || !delete_private.FromJust()) {
- NOTREACHED();
- return;
- }
- // This Delete() can fail, but there's nothing to do if it does (the exception
- // will be caught by the TryCatch above).
- ignore_result(parent->Delete(context, key));
-}
-
-bool APILastError::HasError(v8::Local<v8::Context> context) {
- v8::Isolate* isolate = context->GetIsolate();
- v8::HandleScope handle_scope(isolate);
-
- // See comment in SetError().
- v8::TryCatch try_catch(isolate);
- try_catch.SetVerbose(true);
-
- v8::Local<v8::Object> parent = get_parent_.Run(context);
- if (parent.IsEmpty())
- return false;
- v8::Local<v8::Value> error;
- v8::Local<v8::Private> key = v8::Private::ForApi(
- isolate, gin::StringToSymbol(isolate, kLastErrorProperty));
- // Access through GetPrivate() so we don't trigger accessed().
- if (!parent->GetPrivate(context, key).ToLocal(&error))
- return false;
-
- LastErrorObject* last_error = nullptr;
- return gin::Converter<LastErrorObject*>::FromV8(context->GetIsolate(), error,
- &last_error);
-}
-
-} // namespace extensions
« no previous file with comments | « extensions/renderer/api_last_error.h ('k') | extensions/renderer/api_last_error_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698