Protobuf: fixed a bug in deserialization of messages with size 0. Corresponding test cross-branch-access.proto added

This commit is contained in:
dsavvinov
2016-07-20 17:31:59 +03:00
parent b473dfc5e2
commit de469ea0a1
13 changed files with 174 additions and 8 deletions
@@ -34,6 +34,7 @@ generate:
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/protoc-artifacts ./test/nested-msg.proto
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/protoc-artifacts ./test/routeDone.proto
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/protoc-artifacts ./test/route.proto
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/protoc-artifacts ./test/cross-branch-access.proto
debug:
gdb --args ./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/src ./test/addressbook.proto
@@ -328,17 +328,23 @@ void ClassGenerator::generateParseMethods(io::Printer *printer) const {
printer->Print(vars,
"fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): $builderName$ {\n");
printer->Indent();
printer->Print("while(parseFieldFrom(input)) {\n");
// read while we won't exceed expected amount of bytes
printer->Print("while(getSize() < expectedSize) {\n");
printer->Indent();
printer->Print("if (getSize() == expectedSize) { break }\n");
vars["dollar"] = "$";
printer->Print(vars,
"if (getSize() > expectedSize) { "
"throw InvalidProtocolBufferException(\"Error: expected size of message $dollar$expectedSize, but have read at least $dollar${getSize()}\") "
"}\n");
printer->Print("parseFieldFrom(input)\n");
printer->Outdent(); // while-loop;
printer->Print("}\n");
// check if we read more than expected
vars["dollar"] = "$";
printer->Print(vars,
"if (getSize() > expectedSize) { "
"throw InvalidProtocolBufferException(\"Error: expected size of message $dollar$expectedSize, but have read at least $dollar${getSize()}\") "
"}\n");
printer->Print("return this\n");
printer->Outdent(); // function body
@@ -194,8 +194,15 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
vars["fieldNumber"] = std::to_string(getFieldNumber());
vars["dollar"] = "$";
// We will create some temporary variables
// So we place following code into separate block for the sake of hygiene
printer->Print("run {\n");
printer->Indent();
// read tag
printer->Print(vars, "input.readTag($fieldNumber$, WireType.LENGTH_DELIMITED)\n");
if (!noTag) {
printer->Print(vars, "input.readTag($fieldNumber$, WireType.LENGTH_DELIMITED)\n");
}
// read expected size
printer->Print(vars, "val expectedSize = input.readInt32NoTag()\n");
@@ -209,6 +216,8 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
"throw InvalidProtocolBufferException ("
"\"Expected size $dollar${expectedSize} got $dollar${$fieldName$.getSize()}"
"\") }\n");
printer->Outdent();
printer->Print("}\n");
}
else {
vars["fieldNumber"] = std::to_string(getFieldNumber());
@@ -0,0 +1,21 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "Direction";
message DirectionRequest {
enum Command {
stop = 0;
forward = 1;
backward = 2;
left = 3;
right = 4;
}
Command command = 1;
}
message DirectionResponse {
int32 code = 1;
string errorMsg = 2;
}
@@ -0,0 +1,17 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "Connect";
message ConnectionRequest {
string ip = 1;
int32 port = 2;
}
message ConnectionResponse {
int32 uid = 1;
int32 code = 2;
string errorMsg = 3;
}
@@ -0,0 +1,24 @@
syntax = "proto3";
message Grandfather {
message FatherLeft {
message SonLeftLeft {
FatherLeft father = 1;
Grandfather.FatherRight.SonRightLeft brother = 2;
}
message SonLeftRight {
string foo = 3;
}
}
message FatherRight {
message SonRightLeft {
string bar = 4;
}
message SonRightRight {
Grandfather.FatherLeft.SonLeftRight brother = 5;
}
}
}
@@ -0,0 +1,21 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "Direction";
message DirectionRequest {
enum Command {
stop = 0;
forward = 1;
backward = 2;
left = 3;
right = 4;
}
Command command = 1;
}
message DirectionResponse {
int32 code = 1;
string errorMsg = 2;
}
@@ -0,0 +1,10 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "ErrorP";
message Error {
string errorMessage = 1;
int32 errorCode = 2;
}
@@ -0,0 +1,18 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "Location";
message LocationResponse {
LocationData locationResponseData = 1;
int32 code = 2;
string errorMsg = 3;
message LocationData {
double x = 1;
double y = 2;
double angle = 3;
}
}
@@ -0,0 +1,19 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "Route";
message RouteRequest {
repeated WayPoint way_points = 1;
message WayPoint {
double distance = 2;
double angle_delta = 3;
}
}
message RouteResponse {
int32 code = 1;
string errorMsg = 2;
}
@@ -0,0 +1,10 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "RouteDone";
message RouteDoneResponse {
int32 code = 1;
string errorMsg = 2;
}
@@ -0,0 +1,10 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "RouteDone";
message RouteDoneResponse {
int32 code = 1;
string errorMsg = 2;
}