package/protobuf-c: fix protobuf >= 26.0 compatibility

Add some patches fixing protobuf >= 26.0 compatibility, before doing
this version bump.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
This commit is contained in:
James Hilliard 2024-10-30 13:00:18 -06:00 committed by Thomas Petazzoni
parent a3b2bc8e16
commit c679a44b31
3 changed files with 185 additions and 0 deletions

View File

@ -0,0 +1,57 @@
From 2480f4d9d2fa97e5511ed0914ee529a344e969a7 Mon Sep 17 00:00:00 2001
From: Robert Edmonds <edmonds@users.noreply.github.com>
Date: Wed, 20 Mar 2024 22:43:30 -0400
Subject: [PATCH] CGenerator: Protect against being invoked against "edition"
syntax .proto files
The Google protobuf project is currently experimenting with a new syntax
for .proto files called "editions". Since protobuf-c is a proto2/proto3
compiler, after the previous commit reimplementing `FieldSyntax()`, the
protobuf compiler will abort like this if presented with an "editions"
syntax .proto file due to the safety check in `FieldSyntax()`:
$ protoc --experimental_editions --c_out=. test.proto
protoc-gen-c: ./protoc-c/c_helpers.h:178: int google::protobuf::compiler::c::FieldSyntax(const google::protobuf::FieldDescriptor*): Assertion `syntax == "proto2" || syntax == "proto3"' failed.
--c_out: protoc-gen-c: Plugin killed by signal 6.
On protobuf 26, our `CodeGenerator` can implement certain methods to
declare that we "support" editions, and then reject any other edition
except proto2 and proto3, which have apparently been retroactively
declared to be "editions". Of course this needs to be wrapped in a
version guard.
With this protection in place, the protobuf compiler cleanly exits with
a nice error message like this:
$ protoc --experimental_editions --c_out=. test.proto
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
E0000 00:00:1710988958.296200 20022 descriptor.cc:4620] Invalid proto descriptor for file "test.proto":
E0000 00:00:1710988958.296239 20022 descriptor.cc:4623] test.proto: Edition 2023 is later than the maximum supported edition PROTO3
--c_out: protoc-gen-c: Plugin failed with status code 1.
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Upstream: https://github.com/protobuf-c/protobuf-c/pull/711
---
protoc-c/c_generator.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/protoc-c/c_generator.h b/protoc-c/c_generator.h
index b8b44aa..4aeb579 100644
--- a/protoc-c/c_generator.h
+++ b/protoc-c/c_generator.h
@@ -93,6 +93,12 @@ class PROTOC_C_EXPORT CGenerator : public CodeGenerator {
const std::string& parameter,
OutputDirectory* output_directory,
std::string* error) const;
+
+#if GOOGLE_PROTOBUF_VERSION >= 5026000
+ uint64_t GetSupportedFeatures() const { return CodeGenerator::FEATURE_SUPPORTS_EDITIONS; }
+ Edition GetMinimumEdition() const { return Edition::EDITION_PROTO2; }
+ Edition GetMaximumEdition() const { return Edition::EDITION_PROTO3; }
+#endif
};
} // namespace c
--
2.34.1

View File

@ -0,0 +1,84 @@
From ee3d9e5423c93ee6b828fdda8e7fef13a77634eb Mon Sep 17 00:00:00 2001
From: Robert Edmonds <edmonds@users.noreply.github.com>
Date: Wed, 20 Mar 2024 22:25:54 -0400
Subject: [PATCH] Reimplement FieldSyntax() to maximize compatibility across
protobuf versions
Recent versions of Google protobuf have broken the interfaces for
determining the syntax version of a .proto file. The current protobuf-c
1.5.0 release does not compile with Google protobuf 26.0 due to the most
recentage breakage. There is a possible workaround involving the Google
protobuf `FileDescriptorLegacy` class, which is documented as:
// TODO Remove this deprecated API entirely.
So we probably shouldn't rely on it.
Instead, this commit obtains the `FileDescriptorProto` corresponding
to the passed in `FieldDescriptor` and interrogates the `syntax` field
directly. This is a single implementation with no version-specific
workarounds. Hopefully this won't break in the next Google protobuf
release.
I tested the `FieldSyntax()` implementation in this commit across a
number of different Google protobuf releases and found that it worked
(`make && make check`) on all of them:
- Google protobuf 3.6.1.3 (Ubuntu 20.04)
- Google protobuf 3.12.4 (Ubuntu 22.04)
- Google protobuf 3.21.12 (Debian 12 + Debian unstable)
- Google protobuf 3.25.2 (Debian experimental)
- Google protobuf 26.1-dev
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Upstream: https://github.com/protobuf-c/protobuf-c/pull/711
---
protoc-c/c_helpers.h | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/protoc-c/c_helpers.h b/protoc-c/c_helpers.h
index 062d330..be28b60 100644
--- a/protoc-c/c_helpers.h
+++ b/protoc-c/c_helpers.h
@@ -70,10 +70,6 @@
#include <protobuf-c/protobuf-c.pb.h>
#include <google/protobuf/io/printer.h>
-#if GOOGLE_PROTOBUF_VERSION >= 4023000
-# include <google/protobuf/descriptor_legacy.h>
-#endif
-
namespace google {
namespace protobuf {
namespace compiler {
@@ -173,13 +169,21 @@ struct NameIndex
int compare_name_indices_by_name(const void*, const void*);
// Return the syntax version of the file containing the field.
-// This wrapper is needed to be able to compile against protobuf2.
inline int FieldSyntax(const FieldDescriptor* field) {
-#if GOOGLE_PROTOBUF_VERSION >= 4023000
- return FileDescriptorLegacy(field->file()).syntax() == FileDescriptorLegacy::SYNTAX_PROTO3 ? 3 : 2;
-#else
- return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ? 3 : 2;
-#endif
+ auto proto = FileDescriptorProto();
+ field->file()->CopyTo(&proto);
+
+ if (proto.has_syntax()) {
+ auto syntax = proto.syntax();
+ assert(syntax == "proto2" || syntax == "proto3");
+ if (syntax == "proto2") {
+ return 2;
+ } else if (syntax == "proto3") {
+ return 3;
+ }
+ }
+
+ return 2;
}
// Work around changes in protobuf >= 22.x without breaking compilation against
--
2.34.1

View File

@ -0,0 +1,44 @@
From a6cf1aa386067e26d582cc1d1e327787595c9f13 Mon Sep 17 00:00:00 2001
From: Robert Edmonds <edmonds@users.noreply.github.com>
Date: Wed, 20 Mar 2024 21:48:10 -0400
Subject: [PATCH] FileGenerator::GenerateHeader(): Set `min_header_version`
unconditionally
Previously, we were conditionally trying to set `min_header_version` to
the lowest possible value, and relying on a "legacy" Google interface to
determine the file descriptor's syntax version as part of that
determination.
Instead, simply bump the minimum version to 1003000 (1.3.0). This
release was almost 7 years ago. In practice protobuf-c users should not
be shipping pre-compiled .pb-c.c/.pb-c.h files, anyway.
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Upstream: https://github.com/protobuf-c/protobuf-c/pull/711
---
protoc-c/c_file.cc | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/protoc-c/c_file.cc b/protoc-c/c_file.cc
index ca0ad34..c6d8a24 100644
--- a/protoc-c/c_file.cc
+++ b/protoc-c/c_file.cc
@@ -117,14 +117,7 @@ FileGenerator::~FileGenerator() {}
void FileGenerator::GenerateHeader(io::Printer* printer) {
std::string filename_identifier = FilenameIdentifier(file_->name());
- int min_header_version = 1000000;
-#if GOOGLE_PROTOBUF_VERSION >= 4023000
- if (FileDescriptorLegacy(file_).syntax() == FileDescriptorLegacy::SYNTAX_PROTO3) {
-#else
- if (file_->syntax() == FileDescriptor::SYNTAX_PROTO3) {
-#endif
- min_header_version = 1003000;
- }
+ const int min_header_version = 1003000;
// Generate top of header.
printer->Print(
--
2.34.1