Skip to content

Commit

Permalink
parser: refactor parseJSTPMessages
Browse files Browse the repository at this point in the history
Avoid using `strlen()` magic and explicitly check for `'\0'`
character.

Refs: metarhia/jstp#254
  • Loading branch information
belochub committed Aug 22, 2018
1 parent 34d2e03 commit 2089e9f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 38 deletions.
81 changes: 45 additions & 36 deletions src/message_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,45 +29,54 @@ namespace mdsf {
namespace message_parser {

Local<String> ParseJSTPMessages(Isolate* isolate,
const String::Utf8Value& in,
Local<Array> out) {
const size_t total_size = in.length();
size_t parsed_size = 0;
const char* source = *in;
const char* curr_chunk = source;
int index = 0;

while (parsed_size < total_size) {
auto chunk_size = strlen(curr_chunk);
parsed_size += chunk_size + 1;

if (parsed_size <= total_size) {
size_t skipped_size = SkipToNextToken(curr_chunk,
curr_chunk + chunk_size);
size_t parsed_chunk_size;
auto result = ParseObject(isolate, curr_chunk + skipped_size,
curr_chunk + chunk_size, &parsed_chunk_size);

if (result.IsEmpty()) {
return Local<String>();
}

parsed_chunk_size += skipped_size;
parsed_chunk_size += SkipToNextToken(curr_chunk + parsed_chunk_size,
curr_chunk + chunk_size);

if (parsed_chunk_size != chunk_size) {
THROW_EXCEPTION(SyntaxError, "Invalid format");
return Local<String>();
}

out->Set(index++, result.ToLocalChecked());
curr_chunk += chunk_size + 1;
const char* str,
size_t length,
Local<Array> out) {

auto context = isolate->GetCurrentContext();
uint32_t out_index = 0;
int32_t parsed_length = 0;

for (size_t i = 0; i < length; i++) {
if (str[i] != '\0') {
continue;
}
const char* current_message = str + parsed_length;
const char* current_message_end = str + i;
size_t skipped_size = SkipToNextToken(current_message,
current_message_end);
size_t parsed_message_size;
if (current_message[skipped_size] != '{') {
THROW_EXCEPTION(SyntaxError, "Invalid message type");
return Local<String>();
}
auto message_object = ParseObject(isolate,
current_message + skipped_size,
current_message_end,
&parsed_message_size);

if (message_object.IsEmpty()) {
return Local<String>();
}

parsed_message_size += skipped_size;
parsed_message_size += SkipToNextToken(current_message +
parsed_message_size, current_message_end);

if (parsed_message_size != i - parsed_length) {
THROW_EXCEPTION(SyntaxError, "Invalid format");
return Local<String>();
}

auto mb = out->Set(context, out_index++, message_object.ToLocalChecked());
if (!mb.FromMaybe(false)) {
return Local<String>();
}

parsed_length = i + 1;
}

auto rest = String::NewFromUtf8(isolate, curr_chunk);
return rest;
return String::NewFromUtf8(isolate, str + parsed_length);
}

} // namespace message_parser
Expand Down
4 changes: 3 additions & 1 deletion src/message_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef SRC_MESSAGE_PARSER_H_
#define SRC_MESSAGE_PARSER_H_

#include <cstddef>

#include <v8.h>

namespace mdsf {
Expand All @@ -16,7 +18,7 @@ namespace message_parser {
// delimiters eliminating the need to split the stream data into parts before
// parsing and allowing to do that in one pass.
v8::Local<v8::String> ParseJSTPMessages(v8::Isolate* isolate,
const v8::String::Utf8Value& in, v8::Local<v8::Array> out);
const char* str, std::size_t length, v8::Local<v8::Array> out);

} // namespace message_parser

Expand Down
4 changes: 3 additions & 1 deletion src/node_bindings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ void ParseJSTPMessages(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(isolate);

String::Utf8Value str(args[0]->ToString());
std::size_t length = str.length();
auto array = args[1].As<Array>();
auto result = mdsf::message_parser::ParseJSTPMessages(isolate, str, array);
auto result = mdsf::message_parser::ParseJSTPMessages(isolate,
*str, length, array);
args.GetReturnValue().Set(result);
}

Expand Down

0 comments on commit 2089e9f

Please sign in to comment.