Skip to content
This repository has been archived by the owner on Feb 3, 2022. It is now read-only.

Commit

Permalink
fix(parse): properly support null values in parsed strings
Browse files Browse the repository at this point in the history
closes #2
  • Loading branch information
mbroadst committed May 24, 2017
1 parent 66fe3d9 commit b3f88f9
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 45 deletions.
133 changes: 89 additions & 44 deletions lib/ext_json.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,58 @@ ExtJSON.extend = function(module) {
}

function deseralizeValue(self, value, options) {
if(value['$oid'] != null) {
if (typeof value === 'number') {
if (options.strict) {
if (Math.floor(value) === value && value >= JS_INT_MIN && value <= JS_INT_MAX) {
if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) {
return new self.bson.Int32(value);
}

if (value >= JS_INT_MIN && value <= JS_INT_MAX) {
return new self.bson.Double(value);
}

return new self.bson.Long.fromNumber(value);
}

return new self.bson.Double(value);
}


if (Math.floor(value) === value && value >= JS_INT_MIN && value <= JS_INT_MAX) {
if (value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) {
return value;
}

if (value >= JS_INT_MIN && value <= JS_INT_MAX) {
return value;
}

return new self.bson.Long.fromNumber(value);
}
}

// from here on out we're looking for bson types, so bail if its
// not an object
if (value == null || typeof value !== 'object') {
return value;
}

if (value['$oid'] != null) {
return new self.bson.ObjectID(value['$oid']);
} else if(value['$date'] && typeof value['$date'] == 'string') {
};

if (value['$date'] && typeof value['$date'] === 'string') {
return Date.parse(value['$date']);
} else if(value['$date'] && value['$date'] instanceof self.bson.Long) {
}

if (value['$date'] && value['$date'] instanceof self.bson.Long) {
var date = new Date();
date.setTime(value['$date'].toNumber());
return date;
} else if(value['$binary'] != null) {
}

if (value['$binary'] != null) {
if (typeof Buffer !== 'undefined') {
if (bufferConstructor === Buffer) {
var data = new Buffer(value['$binary'], 'base64');
Expand All @@ -65,59 +108,61 @@ function deseralizeValue(self, value, options) {

var type = value['$type'] ? parseInt(value['$type'], 16) : 0;
return new self.bson.Binary(data, type);
} else if(value['$maxKey'] != null) {
}

if (value['$maxKey'] != null) {
return new self.bson.MaxKey();
} else if(value['$minKey'] != null) {
}

if (value['$minKey'] != null) {
return new self.bson.MinKey();
} else if(value['$code'] != null) {
return new self.bson.Code(value['$code'], deseralizeValue(self, value['$scope'] || {}, options))
} else if(value['$numberLong'] != null) {
}

if (value['$code'] != null) {
return new self.bson.Code(value['$code'], deseralizeValue(self, value['$scope'] || {}, options));
}

if (value['$numberLong'] != null) {
return self.bson.Long.fromString(value['$numberLong']);
} else if(value['$numberDouble'] != null && options.strict) {
}

if (value['$numberDouble'] != null && options.strict) {
return new self.bson.Double(parseFloat(value['$numberDouble']));
} else if(value['$numberDouble'] != null && !options.strict) {
}

if (value['$numberDouble'] != null && !options.strict) {
return parseFloat(value['$numberDouble']);
} else if(value['$numberInt'] != null && options.strict) {
}

if (value['$numberInt'] != null && options.strict) {
return new self.bson.Int32(parseInt(value['$numberInt'], 10));
} else if(value['$numberInt'] != null && !options.strict) {
}

if (value['$numberInt'] != null && !options.strict) {
return parseInt(value['$numberInt'], 10);
} else if(value['$numberDecimal'] != null) {
}

if (value['$numberDecimal'] != null) {
return self.bson.Decimal128.fromString(value['$numberDecimal']);
} else if(value['$regex'] != null) {
}

if (value['$regex'] != null) {
return new self.bson.BSONRegExp(value['$regex'], value['$options'] || '');
} else if(value['$symbol'] != null) {
}

if (value['$symbol'] != null) {
return new self.bson.Symbol(value['$symbol']);
} else if(value['$ref'] != null) {
}

if (value['$ref'] != null) {
return new self.bson.DBRef(value['$ref'], deseralizeValue(self, value['$id'], options), value['$db']);
} else if(value['$timestamp'] != null) {
}

if (value['$timestamp'] != null) {
return self.bson.Timestamp.fromString(value['$timestamp']);
} else if(typeof value == 'number' && options.strict) {
if(Math.floor(value) === value && value >= JS_INT_MIN && value <= JS_INT_MAX) {
if(value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) {
return new self.bson.Int32(value);
} else if(value >= JS_INT_MIN && value <= JS_INT_MAX) {
return new self.bson.Double(value);
} else {
return new self.bson.Long.fromNumber(value);
}
} else {
return new self.bson.Double(value);
}
} else if(typeof value == 'number' && !options.strict) {
if(Math.floor(value) === value && value >= JS_INT_MIN && value <= JS_INT_MAX) {
if(value >= BSON_INT32_MIN && value <= BSON_INT32_MAX) {
return value;
} else if(value >= JS_INT_MIN && value <= JS_INT_MAX) {
return value;
} else {
return new self.bson.Long.fromNumber(value);
}
} else {
return value;
}
} else {
return value;
}

return value;
}

ExtJSON.prototype.parse = function(text, options) {
Expand Down
16 changes: 15 additions & 1 deletion test/extend_mongodb_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ describe('Extended JSON', function() {
});

it('should correctly serialize bson types when they are values', function() {
// Create ExtJSON instance
var extJSON = new ExtJSON();
var Int32 = ExtJSON.BSON.Int32,
ObjectId = ExtJSON.BSON.ObjectID;
Expand All @@ -207,6 +206,21 @@ describe('Extended JSON', function() {
assert.equal(serialized, '{"_id":{"$nin":[{"$oid":"591801a468f9e7024b6235ea"}]}}');
});

it('should correctly parse null values', function() {
var extJSON = new ExtJSON();
var ObjectId = ExtJSON.BSON.ObjectID;

assert.equal(extJSON.parse('null'), null);
assert.deepEqual(extJSON.parse('[null]'), [ null ]);
var input = '{"result":[{"_id":{"$oid":"591801a468f9e7024b623939"},"emptyField":null}]}';
var parsed = extJSON.parse(input, { strict: false });
assert.deepEqual(parsed, {
result: [
{ _id: new ObjectID('591801a468f9e7024b623939'), emptyField: null }
]
});
});

it('should correctly throw when passed a non-string to parse', function() {
// Create ExtJSON instance
var extJSON = new ExtJSON();
Expand Down

0 comments on commit b3f88f9

Please sign in to comment.