|
| 1 | +var tape = require("tape"); |
| 2 | + |
| 3 | +var protobuf = require(".."); |
| 4 | + |
| 5 | +tape.test("decoder respects enclosing message boundaries", function(test) { |
| 6 | + var constructed; |
| 7 | + var Inner = new protobuf.Type("Inner") |
| 8 | + .add(new protobuf.Field("ix", 1, "int32")) |
| 9 | + .add(new protobuf.Field("iy", 2, "int32")) |
| 10 | + .add(new protobuf.Field("iz", 3, "int32")); |
| 11 | + Inner.ctor = function Inner() { |
| 12 | + constructed = this; |
| 13 | + }; |
| 14 | + var Mid = new protobuf.Type("Mid") |
| 15 | + .add(new protobuf.Field("inner", 1, "Inner")) |
| 16 | + .add(new protobuf.Field("mx", 2, "int32")) |
| 17 | + .add(new protobuf.Field("my", 3, "int32")) |
| 18 | + .add(Inner); |
| 19 | + var Outer = new protobuf.Type("Outer") |
| 20 | + .add(new protobuf.Field("mid", 1, "Mid")) |
| 21 | + .add(new protobuf.Field("ox", 2, "int32")) |
| 22 | + .add(new protobuf.Field("oy", 3, "int32")) |
| 23 | + .add(Mid); |
| 24 | + |
| 25 | + test.throws(function() { |
| 26 | + Outer.decode([ 0x0a, 0x08, 0x0a, 0x08, 0x08, 0x07, 0x10, 0x65, 0x18, 0x78, 0x10, 0x64, 0x18, 0x7b ]); |
| 27 | + }, RangeError, "rejects a nested message that consumes its parent's following fields"); |
| 28 | + test.notOk(constructed, "rejects the nested length before constructing the message"); |
| 29 | + |
| 30 | + test.throws(function() { |
| 31 | + Outer.decode([ 0x0a, 0x04, 0x0a, 0x02, 0x08, 0x80, 0x10, 0x64 ]); |
| 32 | + }, RangeError, "rejects a scalar value that crosses the nested boundary"); |
| 33 | + test.ok(constructed, "constructs a message within a valid declared length"); |
| 34 | + test.notOk(Object.hasOwnProperty.call(constructed, "ix"), "does not assign bytes from the parent field"); |
| 35 | + test.end(); |
| 36 | +}); |
| 37 | + |
| 38 | +tape.test("decoder respects map-entry boundaries", function(test) { |
| 39 | + var Type = new protobuf.Type("MapMessage") |
| 40 | + .add(new protobuf.MapField("values", 1, "string", "uint32")) |
| 41 | + .add(new protobuf.Field("after", 2, "uint32")) |
| 42 | + .add(new protobuf.Field("tail", 3, "uint32")); |
| 43 | + |
| 44 | + test.throws(function() { |
| 45 | + Type.decode([ 0x0a, 0x03, 0x0a, 0x02, 0x41, 0x10, 0x18, 0x07 ]); |
| 46 | + }, RangeError, "rejects a map key that consumes the following field"); |
| 47 | + test.end(); |
| 48 | +}); |
| 49 | + |
| 50 | +tape.test("decoder respects packed-field boundaries", function(test) { |
| 51 | + var Type = new protobuf.Type("PackedMessage") |
| 52 | + .add(new protobuf.Field("values", 1, "uint32", "repeated", { packed: true })) |
| 53 | + .add(new protobuf.Field("after", 2, "uint32")) |
| 54 | + .add(new protobuf.Field("tail", 3, "uint32")); |
| 55 | + |
| 56 | + test.throws(function() { |
| 57 | + Type.decode([ 0x0a, 0x01, 0x80, 0x10, 0x18, 0x07 ]); |
| 58 | + }, RangeError, "rejects a packed varint that consumes the following field"); |
| 59 | + test.end(); |
| 60 | +}); |
| 61 | + |
| 62 | +tape.test("decoder respects group boundaries", function(test) { |
| 63 | + var Type = protobuf.parse([ |
| 64 | + "syntax = \"proto2\";", |
| 65 | + "message Outer { optional Inner inner = 1; optional int32 after = 2; }", |
| 66 | + "message Inner { optional group Child = 1 { optional int32 value = 2; } }" |
| 67 | + ].join("\n")).root.lookupType("Outer"); |
| 68 | + |
| 69 | + test.throws(function() { |
| 70 | + Type.decode([ 0x0a, 0x01, 0x0b, 0x0c, 0x10, 0x07 ]); |
| 71 | + }, RangeError, "rejects an end-group tag beyond the parent boundary"); |
| 72 | + test.end(); |
| 73 | +}); |
| 74 | + |
| 75 | +tape.test("decoder respects unknown fixed-width field boundaries", function(test) { |
| 76 | + var Inner = new protobuf.Type("Inner"); |
| 77 | + var Outer = new protobuf.Type("Outer") |
| 78 | + .add(new protobuf.Field("inner", 1, "Inner")) |
| 79 | + .add(new protobuf.Field("after", 2, "uint32")) |
| 80 | + .add(new protobuf.Field("tail", 3, "uint32")) |
| 81 | + .add(Inner); |
| 82 | + |
| 83 | + test.throws(function() { |
| 84 | + Outer.decode([ 0x0a, 0x01, 0x09, 0x10, 1, 0x10, 2, 0x10, 3, 0x10, 4, 0x18, 7 ]); |
| 85 | + }, RangeError, "rejects an unknown fixed64 field that crosses the parent boundary"); |
| 86 | + test.end(); |
| 87 | +}); |
0 commit comments