Commit 8aae1b30 authored by yangguo's avatar yangguo Committed by Commit bot

Throw on range error when creating a string via API.

R=jkummerow@chromium.org
BUG=v8:3853
LOG=Y

Review URL: https://codereview.chromium.org/867373003

Cr-Commit-Position: refs/heads/master@{#26574}
parent 7bf9b23c
......@@ -2133,10 +2133,9 @@ class V8_EXPORT String : public Name {
enum NewStringType { kNormalString, kInternalizedString };
/** Allocates a new string from UTF-8 data.*/
static Local<String> NewFromUtf8(Isolate* isolate,
const char* data,
NewStringType type = kNormalString,
int length = -1);
static Local<String> NewFromUtf8(Isolate* isolate, const char* data,
NewStringType type = kNormalString,
int length = -1);
/** Allocates a new string from Latin-1 data.*/
static Local<String> NewFromOneByte(
......
......@@ -5431,17 +5431,19 @@ inline Local<String> NewString(Isolate* v8_isolate,
String::NewStringType type,
int length) {
i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
ON_BAILOUT(isolate, location, return Local<String>());
LOG_API(isolate, env);
if (length == 0) {
return String::Empty(v8_isolate);
}
ENTER_V8(isolate);
if (length == -1) length = StringLength(data);
// We do not expect this to fail. Change this if it does.
i::Handle<i::String> result = NewString(
isolate->factory(),
type,
i::Vector<const Char>(data, length)).ToHandleChecked();
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::String> result;
has_pending_exception =
!NewString(isolate->factory(), type, i::Vector<const Char>(data, length))
.ToHandle(&result);
EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
return Utils::ToLocal(result);
}
......
......@@ -21914,3 +21914,36 @@ TEST(StreamingScriptWithSourceMappingURLInTheMiddle) {
RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true, NULL,
"bar2.js");
}
TEST(NewStringRangeError) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
LocalContext env;
const int length = i::String::kMaxLength + 1;
const int buffer_size = length * sizeof(uint16_t);
void* buffer = malloc(buffer_size);
memset(buffer, 'A', buffer_size);
{
v8::TryCatch try_catch;
char* data = reinterpret_cast<char*>(buffer);
CHECK(v8::String::NewFromUtf8(isolate, data, v8::String::kNormalString,
length).IsEmpty());
CHECK(try_catch.HasCaught());
}
{
v8::TryCatch try_catch;
uint8_t* data = reinterpret_cast<uint8_t*>(buffer);
CHECK(v8::String::NewFromOneByte(isolate, data, v8::String::kNormalString,
length).IsEmpty());
CHECK(try_catch.HasCaught());
}
{
v8::TryCatch try_catch;
uint16_t* data = reinterpret_cast<uint16_t*>(buffer);
CHECK(v8::String::NewFromTwoByte(isolate, data, v8::String::kNormalString,
length).IsEmpty());
CHECK(try_catch.HasCaught());
}
free(buffer);
}
......@@ -270,31 +270,23 @@ TEST(TerminateLoadICException) {
}
v8::Persistent<v8::String> reenter_script_1;
v8::Persistent<v8::String> reenter_script_2;
void ReenterAfterTermination(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::TryCatch try_catch;
CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
"function f() {"
" var term = true;"
" try {"
" while(true) {"
" if (term) terminate();"
" term = false;"
" }"
" fail();"
" } catch(e) {"
" fail();"
" }"
"}"
"f()"))->Run();
v8::Isolate* isolate = args.GetIsolate();
CHECK(!v8::V8::IsExecutionTerminating(isolate));
v8::Local<v8::String> script =
v8::Local<v8::String>::New(isolate, reenter_script_1);
v8::Script::Compile(script)->Run();
CHECK(try_catch.HasCaught());
CHECK(try_catch.Exception()->IsNull());
CHECK(try_catch.Message().IsEmpty());
CHECK(!try_catch.CanContinue());
CHECK(v8::V8::IsExecutionTerminating(args.GetIsolate()));
v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
"function f() { fail(); } f()"))
->Run();
CHECK(v8::V8::IsExecutionTerminating(isolate));
script = v8::Local<v8::String>::New(isolate, reenter_script_2);
v8::Script::Compile(script)->Run();
}
......@@ -309,17 +301,28 @@ TEST(TerminateAndReenterFromThreadItself) {
v8::Context::New(isolate, NULL, global);
v8::Context::Scope context_scope(context);
CHECK(!v8::V8::IsExecutionTerminating());
v8::Handle<v8::String> source = v8::String::NewFromUtf8(
isolate, "try { loop(); fail(); } catch(e) { fail(); }");
v8::Script::Compile(source)->Run();
// Create script strings upfront as it won't work when terminating.
reenter_script_1.Reset(isolate, v8_str(
"function f() {"
" var term = true;"
" try {"
" while(true) {"
" if (term) terminate();"
" term = false;"
" }"
" fail();"
" } catch(e) {"
" fail();"
" }"
"}"
"f()"));
reenter_script_2.Reset(isolate, v8_str("function f() { fail(); } f()"));
CompileRun("try { loop(); fail(); } catch(e) { fail(); }");
CHECK(!v8::V8::IsExecutionTerminating(isolate));
// Check we can run JS again after termination.
CHECK(v8::Script::Compile(
v8::String::NewFromUtf8(isolate,
"function f() { return true; }"
"f()"))
->Run()
->IsTrue());
CHECK(CompileRun("function f() { return true; } f()")->IsTrue());
reenter_script_1.Reset();
reenter_script_2.Reset();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment