| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #ifndef V8DOMWrapper_h | 31 #ifndef V8DOMWrapper_h |
| 32 #define V8DOMWrapper_h | 32 #define V8DOMWrapper_h |
| 33 | 33 |
| 34 #include "bindings/core/v8/BindingSecurity.h" | |
| 35 #include "bindings/core/v8/DOMDataStore.h" | 34 #include "bindings/core/v8/DOMDataStore.h" |
| 36 #include "bindings/core/v8/ScriptWrappable.h" | 35 #include "bindings/core/v8/ScriptWrappable.h" |
| 37 #include "bindings/core/v8/V8Binding.h" | 36 #include "bindings/core/v8/V8Binding.h" |
| 37 #include "bindings/core/v8/WrapperCreationSecurityCheck.h" |
| 38 #include "core/CoreExport.h" | 38 #include "core/CoreExport.h" |
| 39 #include "platform/wtf/Compiler.h" | 39 #include "platform/wtf/Compiler.h" |
| 40 #include "platform/wtf/text/AtomicString.h" | 40 #include "platform/wtf/text/AtomicString.h" |
| 41 #include "v8/include/v8.h" | 41 #include "v8/include/v8.h" |
| 42 | 42 |
| 43 namespace blink { | 43 namespace blink { |
| 44 | 44 |
| 45 struct WrapperTypeInfo; | 45 struct WrapperTypeInfo; |
| 46 | 46 |
| 47 class V8DOMWrapper { | 47 class V8DOMWrapper { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 SECURITY_CHECK(ToScriptWrappable(wrapper) == impl); | 120 SECURITY_CHECK(ToScriptWrappable(wrapper) == impl); |
| 121 return wrapper; | 121 return wrapper; |
| 122 } | 122 } |
| 123 | 123 |
| 124 class V8WrapperInstantiationScope { | 124 class V8WrapperInstantiationScope { |
| 125 STACK_ALLOCATED(); | 125 STACK_ALLOCATED(); |
| 126 | 126 |
| 127 public: | 127 public: |
| 128 V8WrapperInstantiationScope(v8::Local<v8::Object> creation_context, | 128 V8WrapperInstantiationScope(v8::Local<v8::Object> creation_context, |
| 129 v8::Isolate* isolate, | 129 v8::Isolate* isolate, |
| 130 bool with_security_check) | 130 const WrapperTypeInfo* type) |
| 131 : did_enter_context_(false), | 131 : did_enter_context_(false), |
| 132 context_(isolate->GetCurrentContext()), | 132 context_(isolate->GetCurrentContext()), |
| 133 try_catch_(isolate), | 133 try_catch_(isolate), |
| 134 convert_exceptions_(false) { | 134 type_(type), |
| 135 access_check_failed_(false) { |
| 135 // creationContext should not be empty. Because if we have an | 136 // creationContext should not be empty. Because if we have an |
| 136 // empty creationContext, we will end up creating | 137 // empty creationContext, we will end up creating |
| 137 // a new object in the context currently entered. This is wrong. | 138 // a new object in the context currently entered. This is wrong. |
| 138 CHECK(!creation_context.IsEmpty()); | 139 CHECK(!creation_context.IsEmpty()); |
| 139 v8::Local<v8::Context> context_for_wrapper = | 140 v8::Local<v8::Context> context_for_wrapper = |
| 140 creation_context->CreationContext(); | 141 creation_context->CreationContext(); |
| 141 | 142 |
| 142 // For performance, we enter the context only if the currently running | 143 // For performance, we enter the context only if the currently running |
| 143 // context is different from the context that we are about to enter. | 144 // context is different from the context that we are about to enter. |
| 144 if (context_for_wrapper == context_) | 145 if (context_for_wrapper == context_) |
| 145 return; | 146 return; |
| 146 if (with_security_check) { | 147 |
| 147 SecurityCheck(isolate, context_for_wrapper); | 148 context_ = context_for_wrapper; |
| 148 } else { | 149 |
| 149 convert_exceptions_ = true; | 150 if (!WrapperCreationSecurityCheck::VerifyContextAccess(context_, type_)) { |
| 151 DCHECK(try_catch_.HasCaught()); |
| 152 try_catch_.ReThrow(); |
| 153 access_check_failed_ = true; |
| 154 return; |
| 150 } | 155 } |
| 151 context_ = v8::Local<v8::Context>::New(isolate, context_for_wrapper); | 156 |
| 152 did_enter_context_ = true; | 157 did_enter_context_ = true; |
| 153 context_->Enter(); | 158 context_->Enter(); |
| 154 } | 159 } |
| 155 | 160 |
| 156 ~V8WrapperInstantiationScope() { | 161 ~V8WrapperInstantiationScope() { |
| 157 if (!did_enter_context_) { | 162 if (!did_enter_context_) { |
| 158 try_catch_.ReThrow(); | 163 try_catch_.ReThrow(); |
| 159 return; | 164 return; |
| 160 } | 165 } |
| 161 context_->Exit(); | 166 context_->Exit(); |
| 162 // Rethrow any cross-context exceptions as security error. | 167 |
| 163 if (try_catch_.HasCaught()) { | 168 if (access_check_failed_ || !try_catch_.HasCaught()) |
| 164 if (convert_exceptions_) { | 169 return; |
| 165 try_catch_.Reset(); | 170 |
| 166 ConvertException(); | 171 // Any exception caught here is a cross context exception and it may not be |
| 167 } | 172 // safe to directly rethrow the exception in the current context (without |
| 168 try_catch_.ReThrow(); | 173 // converting it). rethrowCrossContextException converts the exception in |
| 169 } | 174 // such a scenario. |
| 175 v8::Local<v8::Value> caught_exception = try_catch_.Exception(); |
| 176 try_catch_.Reset(); |
| 177 WrapperCreationSecurityCheck::RethrowCrossContextException( |
| 178 context_, type_, caught_exception); |
| 179 try_catch_.ReThrow(); |
| 170 } | 180 } |
| 171 | 181 |
| 172 v8::Local<v8::Context> GetContext() const { return context_; } | 182 v8::Local<v8::Context> GetContext() const { return context_; } |
| 183 bool AccessCheckFailed() const { return access_check_failed_; } |
| 173 | 184 |
| 174 private: | 185 private: |
| 175 void SecurityCheck(v8::Isolate*, v8::Local<v8::Context> context_for_wrapper); | |
| 176 void ConvertException(); | |
| 177 | |
| 178 bool did_enter_context_; | 186 bool did_enter_context_; |
| 179 v8::Local<v8::Context> context_; | 187 v8::Local<v8::Context> context_; |
| 180 v8::TryCatch try_catch_; | 188 v8::TryCatch try_catch_; |
| 181 bool convert_exceptions_; | 189 const WrapperTypeInfo* type_; |
| 190 bool access_check_failed_; |
| 182 }; | 191 }; |
| 183 | 192 |
| 184 } // namespace blink | 193 } // namespace blink |
| 185 | 194 |
| 186 #endif // V8DOMWrapper_h | 195 #endif // V8DOMWrapper_h |
| OLD | NEW |