How to parse JSON in embedded v8?

I try Parse JS in my embedded V8 application and I always get SIGSEGV. I'm not sure what is going on.

My code for parsing json,

v8::Handle<v8::Value> FromJSONString(
    v8::Handle<v8::Value> json_string) {
  v8::HandleScope scope;
  v8::Handle<v8::Context> context = v8::Context::GetCurrent();
  v8::Handle<v8::Object> global = context->Global();

  v8::Handle<v8::Value> JSON_value = global->Get(v8::String::New("JSON"));
  if (!IsObject(JSON_value)) {
    return scope.Close(v8::Undefined());
  }
  v8::Handle<v8::Object> JSON  = JSON_value->ToObject();

  v8::Handle<v8::Value> JSON_parse_value = JSON->Get(v8::String::New("parse"));

  if (JSON_parse_value.IsEmpty() || JSON_parse_value->IsNull() ||
      JSON_parse_value->IsUndefined() ||!JSON_parse_value->IsFunction()) {
    return scope.Close(v8::Undefined());
  }


  v8::Handle<v8::Function> JSON_parse =
      v8::Handle<v8::Function>::Cast(JSON_parse_value);

  return scope.Close(JSON_parse->Call(JSON, 1, &json_string));
}

A specific site that crashes =>

bool extractSource(std::string* source, std::string& body) {
    v8::HandleScope scope; // this is needed and clears the memory
    if (body.empty()) {
        return false;
    }
    v8::Handle<v8::Value> value = v8_server_utils::FromJSONString(body);
    if (value->IsEmpty()) { // CRASHES HERE.
        return false;
    }
    if (value->IsNull()) {
        return false;
    }
    if (value->IsUndefined()) {
        return false;
    }
    if (!value->IsObject()) {
        return false;
    }
    auto object = value->ToObject();
    auto source_key = v8::String::New("source");
    if (object.IsEmpty() || object->IsNull() || object->IsUndefined() ||
        !object->Has(source_key)) {
        return false;
    }
    auto source_obj = object->Get(source_key);
    *source = v8_server_utils::JSStringToCString(source_obj->ToString());
    return true;
}
+4
source share
4 answers

You can use the JSON Parse function open through the API:

v8::Local<v8::String> str; // some string
v8::Local<v8::Value> result = v8::JSON::Parse(str);

Newer versions of V8 provide EscapableHandleScopethat you must use to return a handle from a function:

v8::EscapableHandleScope scope(isolate);
return scope.Escape(value);

it

if (value->IsEmpty()) { // CRASHES HERE.

it should be

if (value.IsEmpty())

Hope this helps.

+6
source

The following code should work provided that you are using an older version of V8, such as v3.14:

v8::Handle<v8::Value> FromJsonString (v8::Handle<v8::Value> jsonString) {
  v8::HandleScope scope;
  v8::Handle<v8::Context> context = v8::Context::GetCurrent();
  v8::Handle<v8::Object> global = context->Global();

  // find JSON object in global scope
  v8::Handle<v8::Value> jsonValue = global->Get(v8::String::New("JSON"));

  if (! jsonValue->IsObject()) {
    return scope.Close(v8::Undefined());
  }

  v8::Handle<v8::Object> json = jsonValue->ToObject();

  // find "parse" attribute
  v8::Handle<v8::Value> parse = json->Get(v8::String::New("parse"));

  if (parse.IsEmpty() ||
      ! parse->IsFunction()) {
    return scope.Close(v8::Undefined());
  }

  // cast into a function    
  v8::Handle<v8::Function> parseFunction = v8::Handle<v8::Function>::Cast(parse);

  // and call it
  return scope.Close(parseFunction->Call(json, 1, &jsonString));
}


static bool ExtractSource (std::string& source, std::string const& body) {
  v8::HandleScope scope;

  // convert whole body from cstring to V8 string
  v8::Handle<v8::String> bodyString = v8::String::New(body.c_str(), body.size());

  // call JSON.parse() on the body
  v8::Handle<v8::Value> value = FromJsonString(bodyString);

  // check if result is valid
  if (value.IsEmpty() ||
      value->IsNull() ||
      value->IsUndefined() ||
      ! value->IsObject()) {
    return false;
  }

  auto object = value->ToObject();

  // extract "source" attribute from result     
  auto sourceKey = v8::String::New("source");

  if (object.IsEmpty() || 
      object->IsNull() || 
      object->IsUndefined() ||
      ! object->Has(sourceKey)) {
    return false;
  }

  auto sourceValue = object->Get(sourceKey);

  if (! sourceValue->IsString()) {
    return false;
  }

  // convert the v8 string value into a cstring
  v8::String::Utf8Value sourceString(sourceValue->ToString());

  if (*sourceString == nullptr) {
    return false;
  }

  source.assign(*sourceString, sourceString.length());
  return true;
}

int main () {
  // test data
  std::string body = "{ \"body\": \"test\", \"source\": \"some string value\" }";
  // result
  std::string source;

  // call function and dump result
  std::cout << "is valid: " << ExtractSource(source, body) << std::endl;
  std::cout << "value of source: '" << source << "'" << std::endl;
}
+3
source

node NAN, Node.js, native-json npm.

:

static Nan::MaybeLocal<v8::Value> Native::JSON::Parse(v8::Local<v8::String> jsonString);

static Nan::MaybeLocal<v8::String> Native::JSON::Stringify(v8::Local<v8::Object> jsonObject, v8::Local<v8::String> gap = v8::Local<v8::String>())

v8::JSON node, NAN:

v8::JSON::Parse node 0.12.x - 0.8 0.10.x

v8::JSON::Stringify node 7 -

native-json package Native::JSON singleton , Node.js, . V8, . Native::JSON singleton JSON .

github: node-native-json

Native::JSON::Parse:

v8::Local<v8::String> json_string = Nan::New("{ \"JSON\": \"object\" }").ToLocalChecked();

v8::Local<v8::Value> val = Native::JSON::Parse(json_string).ToLocalChecked();
+1

, - , .

NAN 2.6.2 12 2017 . Nan::JSON

Nan::JSON ++, JSON javascript, , Node.js, NAN. V8 v8::JSON.

Nan:: JSON.parse

v8::JSON::Parse.

:

Nan::MaybeLocal<v8::Value> Nan::JSON::Parse(v8::Local<v8::String> json_string);

JSON.Parse(json_string) v8::Value.

:

v8::Local<v8::String> json_string = Nan::New("{ \"JSON\": \"object\" }").ToLocalChecked();

Nan::JSON NanJSON;
Nan::MaybeLocal<v8::Value> result = NanJSON.Parse(json_string);
if (!result.IsEmpty()) {
  v8::Local<v8::Value> val = result.ToLocalChecked();
}

Nan:: JSON.stringify

v8::JSON::Stringify.

:

Nan::MaybeLocal<v8::String> Nan::JSON::Stringify(v8::Local<v8::Object> json_object, v8::Local<v8::String> gap = v8::Local<v8::String>());

JSON.Stringify(value), v8::Object.

:

v8::Local<v8::Object> obj = Nan::To<v8::Object>(val).ToLocalChecked();

Nan::JSON NanJSON;
Nan::MaybeLocal<v8::String> result = NanJSON.Stringify(obj);
if (!result.IsEmpty()) {
  v8::Local<v8::String> stringified = result.ToLocalChecked();
}

Refer to the object V8 JSONin the V8 documentation for more information on the source versions of V8these methods and their arguments.

The above has been rephrased from the NAN documentation

0
source

Source: https://habr.com/ru/post/1540609/


All Articles