Protobuf: fixed a bug in message deserialization when nested messages ignored their expected size and tried to parse themselves until the end of the input

This commit is contained in:
dsavvinov
2016-07-20 16:51:52 +03:00
parent 9da0c9cab5
commit abdd9dd9eb
4 changed files with 46 additions and 5 deletions
@@ -26,8 +26,14 @@ clean:
rm -rf $(BINDIR)
generate:
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/src ./test/addressbook.proto
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/src ./test/nested-msg.proto
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/protoc-artifacts ./test/addressbook.proto
./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/connect.proto
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/protoc-artifacts ./test/error.proto
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/protoc-artifacts ./test/location.proto
./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
debug:
gdb --args ./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/src ./test/addressbook.proto
@@ -163,6 +163,18 @@ void ClassGenerator::generateMergeMethods(io::Printer *printer) const {
printer->Print("}\n");
// mergeFromWithSize(input: CodedInputStream, expectedSize: Int)
printer->Print("\n");
printer->Print(vars, "fun mergeFromWithSize (input: CodedInputStream, expectedSize: Int) {\n");
printer->Indent();
vars["builderName"] = getBuilderFullType();
printer->Print(vars, "val builder = $builderName$()\n");
printer->Print("mergeWith(builder.parseFromWithSize(input, expectedSize).build())");
printer->Outdent();
printer->Print("}\n");
// mergeFrom(input: CodedInputStream)
printer->Print("\n");
printer->Print(vars, "fun mergeFrom (input: CodedInputStream) {\n");
@@ -312,14 +324,37 @@ void ClassGenerator::generateParseMethods(io::Printer *printer) const {
printer->Outdent();
printer->Print("}\n"); // parseFieldFrom body
// parseFromWithSize(input: CodedInputStream, expectedSize: Int)
printer->Print(vars,
"fun parseFromWithSize(input: CodedInputStream, expectedSize: Int): $builderName$ {\n");
printer->Indent();
printer->Print("while(parseFieldFrom(input)) {\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->Outdent(); // while-loop;
printer->Print("}\n");
printer->Print("return this\n");
printer->Outdent(); // function body
printer->Print("}\n");
// parseFrom(input: CodedInputStream)
printer->Print(vars,
"fun parseFrom(input: CodedInputStream): $builderName$ {\n");
printer->Indent();
printer->Print("while(parseFieldFrom(input)) {}\n");
printer->Print("while(parseFieldFrom(input)) {");
printer->Print("}\n");
printer->Print("return this\n");
printer->Outdent();
printer->Outdent(); // function body
printer->Print("}\n");
}
@@ -202,7 +202,7 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
// read message itself without tag
printer->Print(vars,
"$fieldName$.mergeFrom(input)\n");
"$fieldName$.mergeFromWithSize(input, expectedSize)\n");
// check that actual size equal to expected size
printer->Print(vars, "if (expectedSize != $fieldName$.getSize()) { "