diff --git a/src/jsrs_parser.cc b/src/jsrs_parser.cc index 56354e6..d95ed56 100644 --- a/src/jsrs_parser.cc +++ b/src/jsrs_parser.cc @@ -32,13 +32,13 @@ using v8::Integer; using v8::Isolate; using v8::Local; using v8::Maybe; +using v8::MaybeLocal; using v8::NewStringType; using v8::Null; using v8::Number; using v8::Object; using v8::String; using v8::True; -using v8::TryCatch; using v8::Undefined; using v8::Value; @@ -63,10 +63,10 @@ static bool GetType(const char* begin, const char* end, Type* type); // The table of parsing functions indexed with the values of the Type // enumeration. -static constexpr Local (*kParseFunctions[])(Isolate*, - const char*, - const char*, - size_t*) = { +static constexpr MaybeLocal (*kParseFunctions[])(Isolate*, + const char*, + const char*, + size_t*) = { &internal::ParseUndefined, &internal::ParseNull, &internal::ParseBool, @@ -90,16 +90,13 @@ Local Parse(Isolate* isolate, const String::Utf8Value& in) { } size_t parsed_size = 0; - Local result; - { - TryCatch trycatch(isolate); - result = - (kParseFunctions[type])(isolate, str + start_pos, end, &parsed_size); - - if (trycatch.HasCaught()) { - trycatch.ReThrow(); - return Undefined(isolate); - } + MaybeLocal result = kParseFunctions[type](isolate, + str + start_pos, + end, + &parsed_size); + + if (result.IsEmpty()) { + return Undefined(isolate); } parsed_size += internal::SkipToNextToken(str + start_pos + parsed_size, end); @@ -110,7 +107,7 @@ Local Parse(Isolate* isolate, const String::Utf8Value& in) { return Undefined(isolate); } - return result; + return result.ToLocalChecked(); } static bool GetType(const char* begin, const char* end, Type* type) { @@ -238,33 +235,34 @@ size_t SkipToNextToken(const char* str, const char* end) { return pos; } -Local ParseUndefined(Isolate* isolate, - const char* begin, - const char* end, - size_t* size) { +MaybeLocal ParseUndefined(Isolate* isolate, + const char* begin, + const char* end, + size_t* size) { if (*begin == ',' || *begin == ']') { *size = 0; } else if (*begin == 'u') { *size = 9; } else { THROW_EXCEPTION(TypeError, "Invalid format of undefined value"); + return MaybeLocal(); } return Undefined(isolate); } -Local ParseNull(Isolate* isolate, - const char* begin, - const char* end, - size_t* size) { +MaybeLocal ParseNull(Isolate* isolate, + const char* begin, + const char* end, + size_t* size) { *size = 4; return Null(isolate); } -Local ParseBool(Isolate* isolate, - const char* begin, - const char* end, - size_t* size) { - Local result; +MaybeLocal ParseBool(Isolate* isolate, + const char* begin, + const char* end, + size_t* size) { + MaybeLocal result; if (begin + 4 <= end && strncmp(begin, "true", 4) == 0) { result = True(isolate); *size = 4; @@ -273,7 +271,6 @@ Local ParseBool(Isolate* isolate, *size = 5; } else { THROW_EXCEPTION(TypeError, "Invalid format: expected boolean"); - result = Undefined(isolate); } return result; } @@ -283,10 +280,10 @@ inline bool IsOctalDigit(char character) { return character >= '0' && character <= '7'; } -Local ParseNumber(Isolate* isolate, - const char* begin, - const char* end, - size_t* size) { +MaybeLocal ParseNumber(Isolate* isolate, + const char* begin, + const char* end, + size_t* size) { bool negate_result = false; const char* number_start = begin; @@ -302,7 +299,7 @@ Local ParseNumber(Isolate* isolate, if (IsOctalDigit(*number_start)) { THROW_EXCEPTION(SyntaxError, "Use new octal literal syntax"); - return Undefined(isolate); + return MaybeLocal(); } else if (*number_start == 'b') { base = 2; number_start++; @@ -366,10 +363,10 @@ static bool GetControlChar(Isolate* isolate, size_t* size, char* write_to); -Local ParseString(Isolate* isolate, - const char* begin, - const char* end, - size_t* size) { +MaybeLocal ParseString(Isolate* isolate, + const char* begin, + const char* end, + size_t* size) { *size = end - begin; char* result = new char[*size + 1]; @@ -396,7 +393,7 @@ Local ParseString(Isolate* isolate, result + res_index); if (!ok) { delete[] result; - return Undefined(isolate); + return MaybeLocal(); } i += in_offset - 1; res_index += out_offset; @@ -404,7 +401,7 @@ Local ParseString(Isolate* isolate, } else if (IsLineTerminatorSequence(begin + i, &in_offset)) { delete[] result; THROW_EXCEPTION(SyntaxError, "Unexpected line end in string"); - return Undefined(isolate); + return MaybeLocal(); } else { result[res_index++] = begin[i]; } @@ -413,7 +410,7 @@ Local ParseString(Isolate* isolate, if (!is_ended) { delete[] result; THROW_EXCEPTION(SyntaxError, "Error while parsing string"); - return Undefined(isolate); + return MaybeLocal(); } Local result_str = String::NewFromUtf8(isolate, result, @@ -525,10 +522,10 @@ static unsigned int ReadHexNumber(const char* str, size_t len, bool* ok) { return result; } -Local ParseKeyInObject(Isolate* isolate, - const char* begin, - const char* end, - size_t* size) { +MaybeLocal ParseKeyInObject(Isolate* isolate, + const char* begin, + const char* end, + size_t* size) { *size = end - begin; Local result; if (begin[0] == '\'' || begin[0] == '"') { @@ -536,13 +533,17 @@ Local ParseKeyInObject(Isolate* isolate, bool valid = GetType(begin, end, ¤t_type); if (valid && current_type == Type::kString) { size_t offset; - result = ParseString(isolate, begin, end, &offset).As(); + MaybeLocal key = ParseString(isolate, begin, end, &offset); + if (key.IsEmpty()) { + return MaybeLocal(); + } + result = key.ToLocalChecked().As(); *size = offset; return result; } else { THROW_EXCEPTION(SyntaxError, "Invalid format in object: key is invalid string"); - return Local(); + return MaybeLocal(); } } else { size_t current_length = 0; @@ -560,7 +561,7 @@ Local ParseKeyInObject(Isolate* isolate, break; } else { THROW_EXCEPTION(SyntaxError, "Unexpected identifier"); - return Local(); + return MaybeLocal(); } } } @@ -569,35 +570,28 @@ Local ParseKeyInObject(Isolate* isolate, } } -Local ParseValueInObject(Isolate* isolate, - const char* begin, - const char* end, - size_t* size) { - Local value; +MaybeLocal ParseValueInObject(Isolate* isolate, + const char* begin, + const char* end, + size_t* size) { Type current_type; bool valid = GetType(begin, end, ¤t_type); if (valid) { - TryCatch trycatch(isolate); - value = (kParseFunctions[current_type])(isolate, begin, end, size); - if (trycatch.HasCaught()) { - trycatch.ReThrow(); - return Undefined(isolate); - } - return value; + return (kParseFunctions[current_type])(isolate, begin, end, size); } else { THROW_EXCEPTION(TypeError, "Invalid type in object"); - return Undefined(isolate); + return MaybeLocal(); } } -Local ParseObject(Isolate* isolate, - const char* begin, - const char* end, - size_t* size) { +MaybeLocal ParseObject(Isolate* isolate, + const char* begin, + const char* end, + size_t* size) { bool key_mode = true; *size = end - begin; - Local current_key; - Local current_value; + MaybeLocal current_key; + MaybeLocal current_value; size_t current_length = 0; auto result = Object::New(isolate); bool has_ended = false; @@ -610,54 +604,47 @@ Local ParseObject(Isolate* isolate, has_ended = true; break; } - { - TryCatch trycatch(isolate); - current_key = ParseKeyInObject(isolate, - begin + i, - end, - ¤t_length); - if (trycatch.HasCaught()) { - trycatch.ReThrow(); - return Undefined(isolate); - } + current_key = ParseKeyInObject(isolate, + begin + i, + end, + ¤t_length); + if (current_key.IsEmpty()) { + return MaybeLocal(); } i += current_length; i += SkipToNextToken(begin + i, end); if (begin[i] != ':') { THROW_EXCEPTION(SyntaxError, "Unexpected token"); - return Undefined(isolate); + return MaybeLocal(); } } else { i += SkipToNextToken(begin + i, end); if (begin[i] == ',') { THROW_EXCEPTION(SyntaxError, "Value is missing in object"); - return Undefined(isolate); + return MaybeLocal(); } - { - TryCatch trycatch(isolate); - current_value = ParseValueInObject(isolate, - begin + i, - end, - ¤t_length); - if (trycatch.HasCaught()) { - trycatch.ReThrow(); - return Undefined(isolate); - } + current_value = ParseValueInObject(isolate, + begin + i, + end, + ¤t_length); + if (current_value.IsEmpty()) { + return current_value; } - if (!current_value->IsUndefined()) { + Local value = current_value.ToLocalChecked(); + if (!value->IsUndefined()) { Maybe is_ok = result->Set(isolate->GetCurrentContext(), - current_key, - current_value); + current_key.ToLocalChecked(), + value); if (is_ok.IsNothing()) { THROW_EXCEPTION(Error, "Cannot add property to object"); - return Undefined(isolate); + return MaybeLocal(); } } i += current_length; i += SkipToNextToken(begin + i, end); if (begin[i] != ',' && begin[i] != '}') { THROW_EXCEPTION(SyntaxError, "Invalid format in object"); - return Undefined(isolate); + return MaybeLocal(); } else if (begin[i] == '}') { *size = i + 1; has_ended = true; @@ -669,16 +656,16 @@ Local ParseObject(Isolate* isolate, if (!has_ended) { THROW_EXCEPTION(SyntaxError, "Missing closing brace in object"); - return Undefined(isolate); + return MaybeLocal(); } return result; } -Local ParseArray(Isolate* isolate, - const char* begin, - const char* end, - size_t* size) { +MaybeLocal ParseArray(Isolate* isolate, + const char* begin, + const char* end, + size_t* size) { auto array = Array::New(isolate); size_t current_length = 0; *size = end - begin; @@ -698,20 +685,16 @@ Local ParseArray(Isolate* isolate, bool valid = GetType(begin + i, end, ¤t_type); if (valid) { - Local t; - { - TryCatch trycatch(isolate); - t = kParseFunctions[current_type](isolate, - begin + i, - end, - ¤t_length); - if (trycatch.HasCaught()) { - trycatch.ReThrow(); - return Undefined(isolate); - } + MaybeLocal t = kParseFunctions[current_type](isolate, + begin + i, + end, + ¤t_length); + if (t.IsEmpty()) { + return t; } if (!(current_type == Type::kUndefined && begin[i] == ']')) { - array->Set(static_cast(current_element++), t); + array->Set(static_cast(current_element++), + t.ToLocalChecked()); is_empty = false; } @@ -722,7 +705,7 @@ Local ParseArray(Isolate* isolate, if (begin[i] != ',' && begin[i] != ']') { THROW_EXCEPTION(SyntaxError, "Invalid format in array: missed comma"); - return Undefined(isolate); + return MaybeLocal(); } else if (begin[i] == ']') { *size = i + 1; has_ended = true; @@ -730,13 +713,13 @@ Local ParseArray(Isolate* isolate, } } else { THROW_EXCEPTION(TypeError, "Invalid type in array"); - return Undefined(isolate); + return MaybeLocal(); } } if (!has_ended) { THROW_EXCEPTION(SyntaxError, "Missing closing bracket in array"); - return Undefined(isolate); + return MaybeLocal(); } return array; diff --git a/src/jsrs_parser.h b/src/jsrs_parser.h index ac067e5..b7ab14f 100644 --- a/src/jsrs_parser.h +++ b/src/jsrs_parser.h @@ -26,82 +26,82 @@ size_t SkipToNextToken(const char* str, const char* end); // parsed JavaScript value. The `size` is incremented by the number of // characters the function has used in the string so that the calling side // knows where to continue from. -v8::Local ParseUndefined(v8::Isolate* isolate, - const char* begin, - const char* end, - std::size_t* size); +v8::MaybeLocal ParseUndefined(v8::Isolate* isolate, + const char* begin, + const char* end, + std::size_t* size); // Parses a null value from `begin` but never past `end` and returns the parsed // JavaScript value. The `size` is incremented by the number of characters the // function has used in the string so that the calling side knows where to // continue from. -v8::Local ParseNull(v8::Isolate* isolate, - const char* begin, - const char* end, - std::size_t* size); +v8::MaybeLocal ParseNull(v8::Isolate* isolate, + const char* begin, + const char* end, + std::size_t* size); // Parses a boolean value from `begin` but never past `end` and returns the // parsed JavaScript value. The `size` is incremented by the number of // characters the function has used in the string so that the calling side // knows where to continue from. -v8::Local ParseBool(v8::Isolate* isolate, - const char* begin, - const char* end, - std::size_t* size); +v8::MaybeLocal ParseBool(v8::Isolate* isolate, + const char* begin, + const char* end, + std::size_t* size); // Parses a numeric value from `begin` but never past `end` and returns the // parsed JavaScript value. The `size` is incremented by the number of // characters the function has used in the string so that the calling side // knows where to continue from. -v8::Local ParseNumber(v8::Isolate* isolate, - const char* begin, - const char* end, - std::size_t* size); +v8::MaybeLocal ParseNumber(v8::Isolate* isolate, + const char* begin, + const char* end, + std::size_t* size); // Parses a string value from `begin` but never past `end` and returns the // parsed JavaScript value. The `size` is incremented by the number of // characters the function has used in the string so that the calling side // knows where to continue from. -v8::Local ParseString(v8::Isolate* isolate, - const char* begin, - const char* end, - std::size_t* size); +v8::MaybeLocal ParseString(v8::Isolate* isolate, + const char* begin, + const char* end, + std::size_t* size); // Parses an array from `begin` but never past `end` and returns the parsed // JavaScript value. The `size` is incremented by the number of characters the // function has used in the string so that the calling side knows where to // continue from. -v8::Local ParseArray(v8::Isolate* isolate, - const char* begin, - const char* end, - std::size_t* size); +v8::MaybeLocal ParseArray(v8::Isolate* isolate, + const char* begin, + const char* end, + std::size_t* size); // Parses an object key from `begin` but never past `end` and returns // the parsed JavaScript value. The `size` is incremented by the number // of characters the function has used in the string so that the calling side // knows where to continue from. -v8::Local ParseKeyInObject(v8::Isolate* isolate, - const char* begin, - const char* end, - std::size_t* size); +v8::MaybeLocal ParseKeyInObject(v8::Isolate* isolate, + const char* begin, + const char* end, + std::size_t* size); // Parses a value corresponding to key inside object from `begin` // but never past `end` and returns the parsed JavaScript value. // The `size` is incremented by the number of characters the function has used // in the string so that the calling side knows where to continue from. -v8::Local ParseValueInObject(v8::Isolate* isolate, - const char* begin, - const char* end, - std::size_t* size); +v8::MaybeLocal ParseValueInObject(v8::Isolate* isolate, + const char* begin, + const char* end, + std::size_t* size); // Parses an object from `begin` but never past `end` and returns the parsed // JavaScript value. The `size` is incremented by the number of characters the // function has used in the string so that the calling side knows where to // continue from. -v8::Local ParseObject(v8::Isolate* isolate, - const char* begin, - const char* end, - std::size_t* size); +v8::MaybeLocal ParseObject(v8::Isolate* isolate, + const char* begin, + const char* end, + std::size_t* size); // Parses a decimal number, either integer or float. v8::Local ParseDecimalNumber(v8::Isolate* isolate, diff --git a/src/packet_parser.cc b/src/packet_parser.cc index c63a704..3942128 100644 --- a/src/packet_parser.cc +++ b/src/packet_parser.cc @@ -46,6 +46,10 @@ Local ParseNetworkPackets(Isolate* isolate, auto result = ParseObject(isolate, curr_chunk + skipped_size, curr_chunk + chunk_size, &parsed_chunk_size); + if (result.IsEmpty()) { + return Local(); + } + parsed_chunk_size += skipped_size; parsed_chunk_size += SkipToNextToken(curr_chunk + parsed_chunk_size, curr_chunk + chunk_size); @@ -55,7 +59,7 @@ Local ParseNetworkPackets(Isolate* isolate, return Local(); } - out->Set(index++, result); + out->Set(index++, result.ToLocalChecked()); curr_chunk += chunk_size + 1; } }