Commit 928ebb6b authored by temporal's avatar temporal

Fix bytes type setter to work with byte sequences with embedded NULLs.

Patch from Alkis Evlogimenos <alkis@evlogimenos.com>.
parent 40ee5517
......@@ -96,8 +96,14 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
"inline const ::std::string& $name$() const;\n"
"inline void set_$name$(const ::std::string& value);\n"
"inline void set_$name$(const char* value);\n");
"inline void set_$name$(const ::std::string& value);\n");
if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
printer->Print(variables_,
"inline void set_$name$(const char* value, size_t size);\n");
} else {
printer->Print(variables_,
"inline void set_$name$(const char* value);\n");
}
printer->Print(variables_,
"inline ::std::string* mutable_$name$();\n");
......@@ -121,14 +127,28 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(value);\n"
"}\n"
"inline void $classname$::set_$name$(const char* value) {\n"
" _set_bit($index$);\n"
" if ($name$_ == &_default_$name$_) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(value);\n"
"}\n");
if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
printer->Print(variables_,
"inline void $classname$::set_$name$(const char* value, size_t size) {\n"
" _set_bit($index$);\n"
" if ($name$_ == &_default_$name$_) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(value, size);\n"
"}\n");
} else {
printer->Print(variables_,
"inline void $classname$::set_$name$(const char* value) {\n"
" _set_bit($index$);\n"
" if ($name$_ == &_default_$name$_) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(value);\n"
"}\n");
}
printer->Print(variables_,
"inline ::std::string* $classname$::mutable_$name$() {\n"
" _set_bit($index$);\n"
......@@ -245,10 +265,18 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
"inline const ::std::string& $name$(int index) const;\n"
"inline ::std::string* mutable_$name$(int index);\n"
"inline void set_$name$(int index, const ::std::string& value);\n"
"inline void set_$name$(int index, const char* value);\n"
"inline ::std::string* add_$name$();\n"
"inline void add_$name$(const ::std::string& value);\n"
"inline void add_$name$(const char* value);\n");
"inline void add_$name$(const ::std::string& value);\n");
if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
printer->Print(variables_,
"inline void set_$name$(int index, const char* value, size_t size);\n"
"inline void add_$name$(const char* value, size_t size);\n");
} else {
printer->Print(variables_,
"inline void set_$name$(int index, const char* value);\n"
"inline void add_$name$(const char* value);\n");
}
if (descriptor_->options().has_ctype()) {
printer->Outdent();
......@@ -277,18 +305,31 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
"inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
" $name$_.Mutable(index)->assign(value);\n"
"}\n"
"inline void $classname$::set_$name$(int index, const char* value) {\n"
" $name$_.Mutable(index)->assign(value);\n"
"}\n"
"inline ::std::string* $classname$::add_$name$() {\n"
" return $name$_.Add();\n"
"}\n"
"inline void $classname$::add_$name$(const ::std::string& value) {\n"
" $name$_.Add()->assign(value);\n"
"}\n"
"inline void $classname$::add_$name$(const char* value) {\n"
" $name$_.Add()->assign(value);\n"
"}\n");
if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
printer->Print(variables_,
"inline void "
"$classname$::set_$name$(int index, const char* value, size_t size) {\n"
" $name$_.Mutable(index)->assign(value, size);\n"
"}\n"
"inline void $classname$::add_$name$(const char* value, size_t size) {\n"
" $name$_.Add()->assign(value, size);\n"
"}\n");
} else {
printer->Print(variables_,
"inline void $classname$::set_$name$(int index, const char* value) {\n"
" $name$_.Mutable(index)->assign(value);\n"
"}\n"
"inline void $classname$::add_$name$(const char* value) {\n"
" $name$_.Add()->assign(value);\n"
"}\n");
}
}
void RepeatedStringFieldGenerator::
......
......@@ -172,6 +172,19 @@ TEST(GeneratedMessageTest, Clear) {
&message.optional_import_message());
}
TEST(GeneratedMessageTest, EmbeddedNullsInBytesCharStar) {
unittest::TestAllTypes message;
const char* value = "\0lalala\0\0";
message.set_optional_bytes(value, 9);
ASSERT_EQ(9, message.optional_bytes().size());
EXPECT_EQ(0, memcmp(value, message.optional_bytes().data(), 9));
message.add_repeated_bytes(value, 9);
ASSERT_EQ(9, message.repeated_bytes(0).size());
EXPECT_EQ(0, memcmp(value, message.repeated_bytes(0).data(), 9));
}
TEST(GeneratedMessageTest, ClearOneField) {
// Set every field to a unique value, then clear one value and insure that
// only that one value is cleared.
......
......@@ -174,9 +174,9 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
inline const ::std::string& dependency(int index) const;
inline ::std::string* mutable_dependency(int index);
inline void set_dependency(int index, const ::std::string& value);
inline void set_dependency(int index, const char* value);
inline ::std::string* add_dependency();
inline void add_dependency(const ::std::string& value);
inline void set_dependency(int index, const char* value);
inline void add_dependency(const char* value);
// repeated .google.protobuf.DescriptorProto message_type = 4;
......@@ -1835,15 +1835,15 @@ inline ::std::string* FileDescriptorProto::mutable_dependency(int index) {
inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
dependency_.Mutable(index)->assign(value);
}
inline void FileDescriptorProto::set_dependency(int index, const char* value) {
dependency_.Mutable(index)->assign(value);
}
inline ::std::string* FileDescriptorProto::add_dependency() {
return dependency_.Add();
}
inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
dependency_.Add()->assign(value);
}
inline void FileDescriptorProto::set_dependency(int index, const char* value) {
dependency_.Mutable(index)->assign(value);
}
inline void FileDescriptorProto::add_dependency(const char* value) {
dependency_.Add()->assign(value);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment