Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ converter.toObject = function toObject(mtype) {
genValuePartial_toObject(gen, field, /* sorted */ index, prop + "[j]")
("}");
} else { gen
("if(m%s!=null&&m.hasOwnProperty(%j)){", prop, field.name); // !== undefined && !== null
("if(m%s!=null&&Object.hasOwnProperty.call(m,%j)){", prop, field.name); // !== undefined && !== null
genValuePartial_toObject(gen, field, /* sorted */ index, prop);
if (field.partOf && !field.partOf.isProto3Optional) gen
("if(o.oneofs)")
Expand Down
2 changes: 1 addition & 1 deletion src/util/minimal.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ util.isset =
*/
util.isSet = function isSet(obj, prop) {
var value = obj[prop];
if (value != null && obj.hasOwnProperty(prop)) // eslint-disable-line eqeqeq, no-prototype-builtins
if (value != null && Object.hasOwnProperty.call(obj, prop)) // eslint-disable-line eqeqeq
return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0;
return false;
};
Expand Down
2 changes: 1 addition & 1 deletion src/verifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ function verifier(mtype) {
ref = "m" + util.safeProp(field.name);

if (field.optional) gen
("if(%s!=null&&m.hasOwnProperty(%j)){", ref, field.name); // !== undefined && !== null
("if(%s!=null&&Object.hasOwnProperty.call(m,%j)){", ref, field.name); // !== undefined && !== null

// map fields
if (field.map) { gen
Expand Down
21 changes: 21 additions & 0 deletions tests/api_converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,27 @@ tape.test("converters", function(test) {

});

test.test(test.name + " - null-prototype objects", function(test) {
var userRoot = protobuf.parse("syntax = \"proto2\"; message User { optional string name = 1; optional int32 age = 2; }").root,
User = userRoot.lookupType("User"),
user = Object.create(null),
oneofRoot = protobuf.parse("syntax = \"proto3\"; message M { oneof kind { string a = 1; int32 b = 2; } }").root,
M = oneofRoot.lookupType("M"),
oneof = Object.create(null);

user.name = "attacker";
user.age = 99;
test.equal(User.verify(user), null, "verify accepts valid null-prototype objects");

user.age = "bad";
test.equal(User.verify(user), "age: integer expected", "verify returns errors for invalid null-prototype objects");

oneof.a = "x";
test.same(M.toObject(oneof, { oneofs: true }), { a: "x", kind: "a" }, "toObject converts null-prototype oneof objects");

test.end();
});

test.test(test.name + " - Message.fromObject", function(test) {

var obj = {
Expand Down
3 changes: 3 additions & 0 deletions tests/api_util.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ tape.test("util", function(test) {
test.notOk(util.isSet(instance, "p"), "should return that " + name + " on the prototype are not present");
test.ok(util.isSet(instance, "i"), "should return that " + name + " on the instance ARE present");
});
var nullProto = Object.create(null);
nullProto.present = 1;
test.ok(util.isSet(nullProto, "present"), "should support null-prototype objects");

test.end();
});
Expand Down
16 changes: 10 additions & 6 deletions tests/data/comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,13 @@ $root.Test1 = (function() {
_depth = 0;
if (_depth > $util.recursionLimit)
return "max depth exceeded";
if (message.field1 != null && message.hasOwnProperty("field1"))
if (message.field1 != null && Object.hasOwnProperty.call(message, "field1"))
if (!$util.isString(message.field1))
return "field1: string expected";
if (message.field2 != null && message.hasOwnProperty("field2"))
if (message.field2 != null && Object.hasOwnProperty.call(message, "field2"))
if (!$util.isInteger(message.field2))
return "field2: integer expected";
if (message.field3 != null && message.hasOwnProperty("field3"))
if (message.field3 != null && Object.hasOwnProperty.call(message, "field3"))
if (typeof message.field3 !== "boolean")
return "field3: boolean expected";
return null;
Expand All @@ -253,6 +253,8 @@ $root.Test1 = (function() {
Test1.fromObject = function fromObject(object, _depth) {
if (object instanceof $root.Test1)
return object;
if (!$util.isObject(object))
throw TypeError(".Test1: object expected");
if (_depth === undefined)
_depth = 0;
if (_depth > $util.recursionLimit)
Expand Down Expand Up @@ -292,11 +294,11 @@ $root.Test1 = (function() {
object.field2 = 0;
object.field3 = false;
}
if (message.field1 != null && message.hasOwnProperty("field1"))
if (message.field1 != null && Object.hasOwnProperty.call(message, "field1"))
object.field1 = message.field1;
if (message.field2 != null && message.hasOwnProperty("field2"))
if (message.field2 != null && Object.hasOwnProperty.call(message, "field2"))
object.field2 = message.field2;
if (message.field3 != null && message.hasOwnProperty("field3"))
if (message.field3 != null && Object.hasOwnProperty.call(message, "field3"))
object.field3 = message.field3;
return object;
};
Expand Down Expand Up @@ -498,6 +500,8 @@ $root.Test2 = (function() {
Test2.fromObject = function fromObject(object, _depth) {
if (object instanceof $root.Test2)
return object;
if (!$util.isObject(object))
throw TypeError(".Test2: object expected");
if (_depth === undefined)
_depth = 0;
if (_depth > $util.recursionLimit)
Expand Down
30 changes: 16 additions & 14 deletions tests/data/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,45 +396,45 @@ $root.Message = (function() {
_depth = 0;
if (_depth > $util.recursionLimit)
return "max depth exceeded";
if (message.stringVal != null && message.hasOwnProperty("stringVal"))
if (message.stringVal != null && Object.hasOwnProperty.call(message, "stringVal"))
if (!$util.isString(message.stringVal))
return "stringVal: string expected";
if (message.stringRepeated != null && message.hasOwnProperty("stringRepeated")) {
if (message.stringRepeated != null && Object.hasOwnProperty.call(message, "stringRepeated")) {
if (!Array.isArray(message.stringRepeated))
return "stringRepeated: array expected";
for (var i = 0; i < message.stringRepeated.length; ++i)
if (!$util.isString(message.stringRepeated[i]))
return "stringRepeated: string[] expected";
}
if (message.uint64Val != null && message.hasOwnProperty("uint64Val"))
if (message.uint64Val != null && Object.hasOwnProperty.call(message, "uint64Val"))
if (!$util.isInteger(message.uint64Val) && !(message.uint64Val && $util.isInteger(message.uint64Val.low) && $util.isInteger(message.uint64Val.high)))
return "uint64Val: integer|Long expected";
if (message.uint64Repeated != null && message.hasOwnProperty("uint64Repeated")) {
if (message.uint64Repeated != null && Object.hasOwnProperty.call(message, "uint64Repeated")) {
if (!Array.isArray(message.uint64Repeated))
return "uint64Repeated: array expected";
for (var i = 0; i < message.uint64Repeated.length; ++i)
if (!$util.isInteger(message.uint64Repeated[i]) && !(message.uint64Repeated[i] && $util.isInteger(message.uint64Repeated[i].low) && $util.isInteger(message.uint64Repeated[i].high)))
return "uint64Repeated: integer|Long[] expected";
}
if (message.bytesVal != null && message.hasOwnProperty("bytesVal"))
if (message.bytesVal != null && Object.hasOwnProperty.call(message, "bytesVal"))
if (!(message.bytesVal && typeof message.bytesVal.length === "number" || $util.isString(message.bytesVal)))
return "bytesVal: buffer expected";
if (message.bytesRepeated != null && message.hasOwnProperty("bytesRepeated")) {
if (message.bytesRepeated != null && Object.hasOwnProperty.call(message, "bytesRepeated")) {
if (!Array.isArray(message.bytesRepeated))
return "bytesRepeated: array expected";
for (var i = 0; i < message.bytesRepeated.length; ++i)
if (!(message.bytesRepeated[i] && typeof message.bytesRepeated[i].length === "number" || $util.isString(message.bytesRepeated[i])))
return "bytesRepeated: buffer[] expected";
}
if (message.enumVal != null && message.hasOwnProperty("enumVal"))
if (message.enumVal != null && Object.hasOwnProperty.call(message, "enumVal"))
switch (message.enumVal) {
default:
return "enumVal: enum value expected";
case 1:
case 2:
break;
}
if (message.enumRepeated != null && message.hasOwnProperty("enumRepeated")) {
if (message.enumRepeated != null && Object.hasOwnProperty.call(message, "enumRepeated")) {
if (!Array.isArray(message.enumRepeated))
return "enumRepeated: array expected";
for (var i = 0; i < message.enumRepeated.length; ++i)
Expand All @@ -446,7 +446,7 @@ $root.Message = (function() {
break;
}
}
if (message.int64Map != null && message.hasOwnProperty("int64Map")) {
if (message.int64Map != null && Object.hasOwnProperty.call(message, "int64Map")) {
if (!$util.isObject(message.int64Map))
return "int64Map: object expected";
var key = Object.keys(message.int64Map);
Expand All @@ -468,6 +468,8 @@ $root.Message = (function() {
Message.fromObject = function fromObject(object, _depth) {
if (object instanceof $root.Message)
return object;
if (!$util.isObject(object))
throw TypeError(".Message: object expected");
if (_depth === undefined)
_depth = 0;
if (_depth > $util.recursionLimit)
Expand Down Expand Up @@ -562,7 +564,7 @@ $root.Message = (function() {
}
}
if (object.int64Map) {
if (typeof object.int64Map !== "object")
if (!$util.isObject(object.int64Map))
throw TypeError(".Message.int64Map: object expected");
message.int64Map = {};
for (var keys = Object.keys(object.int64Map), i = 0; i < keys.length; ++i) {
Expand Down Expand Up @@ -622,14 +624,14 @@ $root.Message = (function() {
}
object.enumVal = options.enums === String ? "ONE" : 1;
}
if (message.stringVal != null && message.hasOwnProperty("stringVal"))
if (message.stringVal != null && Object.hasOwnProperty.call(message, "stringVal"))
object.stringVal = message.stringVal;
if (message.stringRepeated && message.stringRepeated.length) {
object.stringRepeated = Array(message.stringRepeated.length);
for (var j = 0; j < message.stringRepeated.length; ++j)
object.stringRepeated[j] = message.stringRepeated[j];
}
if (message.uint64Val != null && message.hasOwnProperty("uint64Val"))
if (message.uint64Val != null && Object.hasOwnProperty.call(message, "uint64Val"))
if (typeof BigInt !== "undefined" && options.longs === BigInt)
object.uint64Val = typeof message.uint64Val === "number" ? BigInt(message.uint64Val) : $util.Long.fromBits(message.uint64Val.low >>> 0, message.uint64Val.high >>> 0, true).toBigInt();
else if (typeof message.uint64Val === "number")
Expand All @@ -646,14 +648,14 @@ $root.Message = (function() {
else
object.uint64Repeated[j] = options.longs === String ? $util.Long.prototype.toString.call(message.uint64Repeated[j]) : options.longs === Number ? new $util.LongBits(message.uint64Repeated[j].low >>> 0, message.uint64Repeated[j].high >>> 0).toNumber(true) : message.uint64Repeated[j];
}
if (message.bytesVal != null && message.hasOwnProperty("bytesVal"))
if (message.bytesVal != null && Object.hasOwnProperty.call(message, "bytesVal"))
object.bytesVal = options.bytes === String ? $util.base64.encode(message.bytesVal, 0, message.bytesVal.length) : options.bytes === Array ? Array.prototype.slice.call(message.bytesVal) : message.bytesVal;
if (message.bytesRepeated && message.bytesRepeated.length) {
object.bytesRepeated = Array(message.bytesRepeated.length);
for (var j = 0; j < message.bytesRepeated.length; ++j)
object.bytesRepeated[j] = options.bytes === String ? $util.base64.encode(message.bytesRepeated[j], 0, message.bytesRepeated[j].length) : options.bytes === Array ? Array.prototype.slice.call(message.bytesRepeated[j]) : message.bytesRepeated[j];
}
if (message.enumVal != null && message.hasOwnProperty("enumVal"))
if (message.enumVal != null && Object.hasOwnProperty.call(message, "enumVal"))
object.enumVal = options.enums === String ? $root.Message.SomeEnum[message.enumVal] === undefined ? message.enumVal : $root.Message.SomeEnum[message.enumVal] : message.enumVal;
if (message.enumRepeated && message.enumRepeated.length) {
object.enumRepeated = Array(message.enumRepeated.length);
Expand Down
Loading