我正在尝试在我的嵌入式V8应用程序中解析JS,并且我总是得到一个SIGSEGV。我不确定发生了什么。
我解析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));
}
崩溃的特定网站=&gt;
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;
}
答案 0 :(得分:6)
您可以使用通过API公开的JSON Parse功能:
v8::Local<v8::String> str; // some string
v8::Local<v8::Value> result = v8::JSON::Parse(str);
较新版本的V8提供了EscapableHandleScope
,您需要使用它来从函数返回句柄:
v8::EscapableHandleScope scope(isolate);
return scope.Escape(value);
此
if (value->IsEmpty()) { // CRASHES HERE.
应该是
if (value.IsEmpty())
希望这有帮助。
答案 1 :(得分:3)
以下代码应该可以使用,只要您使用的是较早的V8版本,例如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;
}
答案 2 :(得分:1)
如果您正在编写本机节点模块并使用 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>())
至于 NAN 支持的节点版本中v8::JSON
的更改:
v8::JSON::Parse
首次在节点版本0.12.x中可用 - 不,在版本0.8或0.10.x中可用
v8::JSON::Stringify
首次在节点版本7中提供 - 在早期版本中不
native-json
包的Native::JSON
单例类将以最有效的方式执行请求,具体取决于构建的 Node.js 的版本。如果该方法在该版本的 V8 中可用,则将调用该方法。否则,Native::JSON
单例类会回退到从全局上下文中抓取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();
答案 3 :(得分:0)
我添加了这个额外的答案,因为我之前的答案仍然是正确的,但截至目前,已有更新更好的答案。
NAN 版本2.6.2于2017年4月12日发布。此版本引入了一个新对象Nan::JSON
Nan::JSON
对象提供了javascript中JSON
对象提供的方法的c ++版本,其向后兼容 NAN 支持的所有Node.js版本。 EM>。否则V8会通过v8::JSON
对象公开这些方法。
围绕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();
}
围绕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();
}
有关这些方法及其参数的原始V8 JSON
版本的详细信息,请参阅V8 documentation中的V8
对象。
上述内容是从NAN documentation
转述的