Skip to content
This repository has been archived by the owner on Sep 23, 2024. It is now read-only.

Commit

Permalink
Better identify Map instances, avoid throwing on anything containing …
Browse files Browse the repository at this point in the history
…an entries field, #37
  • Loading branch information
christkv committed Jan 20, 2017
1 parent 18a6038 commit a6cb0b0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
12 changes: 10 additions & 2 deletions ext/bson.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ static const char* CODE_SCOPE_PROPERTY_NAME = "scope";
static const char* TO_BSON_PROPERTY_NAME = "toBSON";
static const char* TO_OBJECT_PROPERTY_NAME = "toObject";

// Equality Object for Map
static const char* MAP_NAME = "[object Map]";

void DataStream::WriteObjectId(const Local<Object>& object, const Local<String>& key)
{
uint16_t buffer[12];
Expand Down Expand Up @@ -175,8 +178,9 @@ template<typename T> void BSONSerializer<T>::SerializeDocument(const Local<Value
Local<Object> object = bson->GetSerializeObject(value);
Local<String> propertyName;
Local<Value> propertyValue;
Local<String> str = object->ToString();

if(!NanHas(object, "entries")) {
if(!str->StrictEquals(Nan::New(bson->MAP_NAME_STR)->ToString())) {
// Get the object property names
Local<Array> propertyNames = object->GetPropertyNames();

Expand Down Expand Up @@ -206,7 +210,9 @@ template<typename T> void BSONSerializer<T>::SerializeDocument(const Local<Value
} else {
// Get the entries function
const Local<Value>& entries = NanGet(object, "entries");
if(!entries->IsFunction()) ThrowAllocatedStringException(64, "Map.entries is not a function");
if(!entries->IsFunction()) {
ThrowAllocatedStringException(64, "Map.entries is not a function");
}

// Get the iterator
Local<Object> iterator = Local<Function>::Cast(entries)->Call(object, 0, NULL)->ToObject();
Expand Down Expand Up @@ -1069,6 +1075,7 @@ BSON::~BSON()
DBREF_DB_PROPERTY_NAME_STR.Reset();
REGEX_PATTERN_PROPERTY_NAME_STR.Reset();
REGEX_OPTIONS_PROPERTY_NAME_STR.Reset();
MAP_NAME_STR.Reset();
}

void BSON::initializeStatics() {
Expand Down Expand Up @@ -1164,6 +1171,7 @@ NAN_METHOD(BSON::New) {
bson->DBREF_DB_PROPERTY_NAME_STR.Reset(Nan::New<String>(DBREF_DB_PROPERTY_NAME).ToLocalChecked());
bson->REGEX_PATTERN_PROPERTY_NAME_STR.Reset(Nan::New<String>(REGEX_PATTERN_PROPERTY_NAME).ToLocalChecked());
bson->REGEX_OPTIONS_PROPERTY_NAME_STR.Reset(Nan::New<String>(REGEX_OPTIONS_PROPERTY_NAME).ToLocalChecked());
bson->MAP_NAME_STR.Reset(Nan::New<String>(MAP_NAME).ToLocalChecked());

// Allocate a new Buffer
bson->buffer.Reset(Unmaybe(Nan::NewBuffer(sizeof(char) * maxBSONSize)));
Expand Down
1 change: 1 addition & 0 deletions ext/bson.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class BSON : public Nan::ObjectWrap {
Nan::Persistent<String> DBREF_DB_PROPERTY_NAME_STR;
Nan::Persistent<String> REGEX_PATTERN_PROPERTY_NAME_STR;
Nan::Persistent<String> REGEX_OPTIONS_PROPERTY_NAME_STR;
Nan::Persistent<String> MAP_NAME_STR;

private:
static NAN_METHOD(New);
Expand Down
15 changes: 15 additions & 0 deletions test/node/map_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,18 @@ exports['should serialize a map'] = function(test) {
var data = bson.serialize(m, false, true);
test.equal('13000000103100010000001030000200000000', data.toString('hex'));
}

/**
* @ignore
*/
exports['should not crash due to object that looks like map'] = function(test) {
// Serialize top level map only
var m = { entries: "test" };
var bson = createBSON();
// Serialize the map
var data = bson.serialize(m, false, true);
// Deserialize the data
var object = bson.deserialize(data);
test.deepEqual(m, object);
test.done();
}

0 comments on commit a6cb0b0

Please sign in to comment.