From 43ce9c6f101c4224addd9a54e0c39963188dc7fa Mon Sep 17 00:00:00 2001 From: caitpotter88 Date: Tue, 7 Jul 2015 14:06:10 -0700 Subject: [PATCH] [d8] bounds-check before getting Shell::Worker internal field Prevents fatal error in debug builds BUG=v8:4271 R=binji@chromium.org LOG=N Review URL: https://codereview.chromium.org/1214053004 Cr-Commit-Position: refs/heads/master@{#29524} --- src/d8.cc | 22 +++++++++++++++------- test/mjsunit/regress/regress-4271.js | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 test/mjsunit/regress/regress-4271.js diff --git a/src/d8.cc b/src/d8.cc index 7db6f3e..2117825 100644 --- a/src/d8.cc +++ b/src/d8.cc @@ -717,14 +717,17 @@ void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); HandleScope handle_scope(isolate); Local context = isolate->GetCurrentContext(); + Local this_value; if (args.Length() < 1) { Throw(isolate, "Invalid argument"); return; } - Local this_value = args.This()->GetInternalField(0); - if (!this_value->IsExternal()) { + if (args.This()->InternalFieldCount() > 0) { + this_value = args.This()->GetInternalField(0); + } + if (this_value.IsEmpty()) { Throw(isolate, "this is not a Worker"); return; } @@ -770,9 +773,11 @@ void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo& args) { void Shell::WorkerGetMessage(const v8::FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); HandleScope handle_scope(isolate); - - Local this_value = args.This()->GetInternalField(0); - if (!this_value->IsExternal()) { + Local this_value; + if (args.This()->InternalFieldCount() > 0) { + this_value = args.This()->GetInternalField(0); + } + if (this_value.IsEmpty()) { Throw(isolate, "this is not a Worker"); return; } @@ -795,8 +800,11 @@ void Shell::WorkerGetMessage(const v8::FunctionCallbackInfo& args) { void Shell::WorkerTerminate(const v8::FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); HandleScope handle_scope(isolate); - Local this_value = args.This()->GetInternalField(0); - if (!this_value->IsExternal()) { + Local this_value; + if (args.This()->InternalFieldCount() > 0) { + this_value = args.This()->GetInternalField(0); + } + if (this_value.IsEmpty()) { Throw(isolate, "this is not a Worker"); return; } diff --git a/test/mjsunit/regress/regress-4271.js b/test/mjsunit/regress/regress-4271.js new file mode 100644 index 0000000..eff0803 --- /dev/null +++ b/test/mjsunit/regress/regress-4271.js @@ -0,0 +1,24 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Throw rather than overflow internal field index + +assertThrows(function() { + Worker.prototype.terminate(); +}); + +assertThrows(function() { + Worker.prototype.getMessage(); +}); + +assertThrows(function() { + Worker.prototype.postMessage({}); +}); + +// Don't throw for real worker + +var worker = new Worker(''); +worker.getMessage(); +worker.postMessage({}); +worker.terminate(); -- 2.7.4