blob: c9a3c54034860a3c8b1854d6ec4a58b81f6e7063 [file] [log] [blame]
--- a/src/google/protobuf/descriptor.cc 2022-03-14 15:16:40.588943398 -0700
+++ b/src/google/protobuf/descriptor.cc 2022-03-14 16:04:03.348461544 -0700
@@ -4002,6 +4002,11 @@
// Use its file as the parent instead.
if (parent == nullptr) parent = file_;
+ if (full_name.find('\0') != std::string::npos) {
+ AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+ "\"" + full_name + "\" contains null character.");
+ return false;
+ }
if (tables_->AddSymbol(full_name, symbol)) {
if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) {
// This is only possible if there was already an error adding something of
@@ -4041,6 +4046,11 @@
void DescriptorBuilder::AddPackage(const std::string& name,
const Message& proto,
const FileDescriptor* file) {
+ if (name.find('\0') != std::string::npos) {
+ AddError(name, proto, DescriptorPool::ErrorCollector::NAME,
+ "\"" + name + "\" contains null character.");
+ return;
+ }
if (tables_->AddSymbol(name, Symbol(file))) {
// Success. Also add parent package, if any.
std::string::size_type dot_pos = name.find_last_of('.');
@@ -4354,6 +4364,12 @@
}
result->pool_ = pool_;
+ if (result->name().find('\0') != std::string::npos) {
+ AddError(result->name(), proto, DescriptorPool::ErrorCollector::NAME,
+ "\"" + result->name() + "\" contains null character.");
+ return nullptr;
+ }
+
// Add to tables.
if (!tables_->AddFile(result)) {
AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
--- a/src/google/protobuf/descriptor_unittest.cc 2020-02-14 12:13:20.000000000 -0800
+++ b/src/google/protobuf/descriptor_unittest.cc 2022-03-14 15:18:13.727479837 -0700
@@ -3765,6 +3765,45 @@
"foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
}
+// 'str' is a static C-style string that may contain '\0'
+#define STATIC_STR(str) std::string((str), sizeof(str) - 1)
+
+TEST_F(ValidationErrorTest, NullCharSymbolName) {
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "package: \"foo\""
+ "message_type { "
+ " name: '\\000\\001\\013.Bar' "
+ " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ "} "
+ "}",
+ STATIC_STR("bar.proto: foo.\0\x1\v.Bar: NAME: \"\0\x1\v.Bar\" is not a "
+ "valid identifier.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
+ "\"\0\x1\v.Bar\" is not a valid identifier.\nbar.proto: "
+ "foo.\0\x1\v.Bar: NAME: \"\0\x1\v.Bar\" is not a valid "
+ "identifier.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
+ "\"\0\x1\v.Bar\" is not a valid identifier.\nbar.proto: "
+ "foo.\0\x1\v.Bar.foo: NAME: \"foo.\0\x1\v.Bar.foo\" contains "
+ "null character.\nbar.proto: foo.\0\x1\v.Bar: NAME: "
+ "\"foo.\0\x1\v.Bar\" contains null character.\n"));
+}
+
+TEST_F(ValidationErrorTest, NullCharFileName) {
+ BuildFileWithErrors(
+ "name: \"bar\\000\\001\\013.proto\" "
+ "package: \"outer.foo\"",
+ STATIC_STR("bar\0\x1\v.proto: bar\0\x1\v.proto: NAME: "
+ "\"bar\0\x1\v.proto\" contains null character.\n"));
+}
+
+TEST_F(ValidationErrorTest, NullCharPackageName) {
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "package: \"\\000\\001\\013.\"",
+ STATIC_STR("bar.proto: \0\x1\v.: NAME: \"\0\x1\v.\" contains null "
+ "character.\n"));
+}
+
TEST_F(ValidationErrorTest, MissingFileName) {
BuildFileWithErrors("",