Compare commits

2 Commits
main ... 1.1

23 changed files with 1397 additions and 5142 deletions

161
CVE-2024-2410.patch Normal file
View File

@@ -0,0 +1,161 @@
From b955165ebdcc5a8ba9c267230d6305f4e3d9c118 Mon Sep 17 00:00:00 2001
From: Adam Cozzette <acozzette@google.com>
Date: Fri, 13 Oct 2023 15:20:54 -0700
Subject: [PATCH] Internal change
PiperOrigin-RevId: 573332237
---
.../protobuf/io/test_zero_copy_stream.h | 22 ++++++++++++-------
src/google/protobuf/json/BUILD.bazel | 1 +
src/google/protobuf/json/internal/parser.cc | 2 +-
src/google/protobuf/json/json_test.cc | 20 +++++++++++++++++
4 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/src/google/protobuf/io/test_zero_copy_stream.h b/src/google/protobuf/io/test_zero_copy_stream.h
index 4c5a06db400ef..1a56d7038c964 100644
--- a/src/google/protobuf/io/test_zero_copy_stream.h
+++ b/src/google/protobuf/io/test_zero_copy_stream.h
@@ -9,12 +9,12 @@
#define GOOGLE_PROTOBUF_IO_TEST_ZERO_COPY_STREAM_H__
#include <deque>
+#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/log/absl_check.h"
-#include "absl/types/optional.h"
#include "google/protobuf/io/zero_copy_stream.h"
// Must be included last.
@@ -37,18 +37,22 @@ class TestZeroCopyInputStream final : public ZeroCopyInputStream {
TestZeroCopyInputStream(const TestZeroCopyInputStream& other)
: ZeroCopyInputStream(),
buffers_(other.buffers_),
- last_returned_buffer_(other.last_returned_buffer_),
+ last_returned_buffer_(
+ other.last_returned_buffer_
+ ? std::make_unique<std::string>(*other.last_returned_buffer_)
+ : nullptr),
byte_count_(other.byte_count_) {}
bool Next(const void** data, int* size) override {
ABSL_CHECK(data) << "data must not be null";
ABSL_CHECK(size) << "size must not be null";
- last_returned_buffer_ = absl::nullopt;
+ last_returned_buffer_ = nullptr;
// We are done
if (buffers_.empty()) return false;
- last_returned_buffer_ = std::move(buffers_.front());
+ last_returned_buffer_ =
+ std::make_unique<std::string>(std::move(buffers_.front()));
buffers_.pop_front();
*data = last_returned_buffer_->data();
*size = static_cast<int>(last_returned_buffer_->size());
@@ -58,19 +62,19 @@ class TestZeroCopyInputStream final : public ZeroCopyInputStream {
void BackUp(int count) override {
ABSL_CHECK_GE(count, 0) << "count must not be negative";
- ABSL_CHECK(last_returned_buffer_.has_value())
+ ABSL_CHECK(last_returned_buffer_ != nullptr)
<< "The last call was not a successful Next()";
ABSL_CHECK_LE(count, last_returned_buffer_->size())
<< "count must be within bounds of last buffer";
buffers_.push_front(
last_returned_buffer_->substr(last_returned_buffer_->size() - count));
- last_returned_buffer_ = absl::nullopt;
+ last_returned_buffer_ = nullptr;
byte_count_ -= count;
}
bool Skip(int count) override {
ABSL_CHECK_GE(count, 0) << "count must not be negative";
- last_returned_buffer_ = absl::nullopt;
+ last_returned_buffer_ = nullptr;
while (true) {
if (count == 0) return true;
if (buffers_.empty()) return false;
@@ -96,7 +100,9 @@ class TestZeroCopyInputStream final : public ZeroCopyInputStream {
// move them to `last_returned_buffer_`. It makes it simpler to keep track of
// the state of the object. The extra cost is not relevant for testing.
std::deque<std::string> buffers_;
- absl::optional<std::string> last_returned_buffer_;
+ // absl::optional could work here, but std::unique_ptr makes it more likely
+ // for sanitizers to detect if the string is used after it is destroyed.
+ std::unique_ptr<std::string> last_returned_buffer_;
int64_t byte_count_ = 0;
};
diff --git a/src/google/protobuf/json/BUILD.bazel b/src/google/protobuf/json/BUILD.bazel
index dece74e4d0f00..6ec8184e0e09e 100644
--- a/src/google/protobuf/json/BUILD.bazel
+++ b/src/google/protobuf/json/BUILD.bazel
@@ -41,6 +41,7 @@ cc_test(
"//src/google/protobuf:cc_test_protos",
"//src/google/protobuf:port_def",
"//src/google/protobuf/io",
+ "//src/google/protobuf/io:test_zero_copy_stream",
"//src/google/protobuf/util:json_format_cc_proto",
"//src/google/protobuf/util:json_format_proto3_cc_proto",
"//src/google/protobuf/util:type_resolver_util",
diff --git a/src/google/protobuf/json/internal/parser.cc b/src/google/protobuf/json/internal/parser.cc
index 17e8fcc07c421..fbf492afa7153 100644
--- a/src/google/protobuf/json/internal/parser.cc
+++ b/src/google/protobuf/json/internal/parser.cc
@@ -1273,7 +1273,7 @@ absl::Status ParseMessage(JsonLexer& lex, const Desc<Traits>& desc,
}
}
- return ParseField<Traits>(lex, desc, name.value.AsView(), msg);
+ return ParseField<Traits>(lex, desc, name.value.ToString(), msg);
});
}
} // namespace
diff --git a/src/google/protobuf/json/json_test.cc b/src/google/protobuf/json/json_test.cc
index 48379ceeb5f9e..2ff1e87a90fe6 100644
--- a/src/google/protobuf/json/json_test.cc
+++ b/src/google/protobuf/json/json_test.cc
@@ -26,6 +26,7 @@
#include "absl/strings/string_view.h"
#include "google/protobuf/descriptor_database.h"
#include "google/protobuf/dynamic_message.h"
+#include "google/protobuf/io/test_zero_copy_stream.h"
#include "google/protobuf/io/zero_copy_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include "google/protobuf/util/json_format.pb.h"
@@ -50,6 +51,7 @@ using ::proto3::TestMap;
using ::proto3::TestMessage;
using ::proto3::TestOneof;
using ::proto3::TestWrapper;
+using ::testing::ContainsRegex;
using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ::testing::Not;
@@ -1331,6 +1333,24 @@ TEST_P(JsonTest, ClearPreExistingRepeatedInJsonValues) {
EXPECT_THAT(s.fields(), IsEmpty());
}
+TEST(JsonErrorTest, FieldNameAndSyntaxErrorInSeparateChunks) {
+ std::unique_ptr<TypeResolver> resolver{
+ google::protobuf::util::NewTypeResolverForDescriptorPool(
+ "type.googleapis.com", DescriptorPool::generated_pool())};
+ io::internal::TestZeroCopyInputStream input_stream(
+ {"{\"bool_value\":", "5}"});
+ std::string result;
+ io::StringOutputStream output_stream(&result);
+ absl::Status s = JsonToBinaryStream(
+ resolver.get(), "type.googleapis.com/proto3.TestMessage", &input_stream,
+ &output_stream, ParseOptions{});
+ ASSERT_FALSE(s.ok());
+ EXPECT_THAT(
+ s.message(),
+ ContainsRegex("invalid *JSON *in *type.googleapis.com/proto3.TestMessage "
+ "*@ *bool_value"));
+}
+
} // namespace
} // namespace json
} // namespace protobuf

146
CVE-2024-7254.patch Normal file
View File

@@ -0,0 +1,146 @@
From 45fcced917ca6650a236eb628e0bca0da8587fd8 Mon Sep 17 00:00:00 2001
From: Protobuf Team Bot <protobuf-github-bot@google.com>
Date: Thu, 18 Jul 2024 07:41:01 -0700
Subject: [PATCH] Internal change
PiperOrigin-RevId: 653615736
---
.../core/src/main/java/com/google/protobuf/ArrayDecoders.java | 3 +--
.../com/google/protobuf/InvalidProtocolBufferException.java | 2 +-
.../core/src/main/java/com/google/protobuf/MessageSchema.java | 3 +++
.../src/main/java/com/google/protobuf/MessageSetSchema.java | 1 +
.../src/main/java/com/google/protobuf/UnknownFieldSchema.java | 3 +--
java/lite/src/test/java/com/google/protobuf/LiteTest.java | 3 +++
src/google/protobuf/unittest_lite.proto | 4 ++++
7 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java b/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java
index 183bbc2c5..855174f6d 100644
--- a/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java
+++ b/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java
@@ -47,8 +47,7 @@ import java.io.IOException;
@CheckReturnValue
final class ArrayDecoders {
- private ArrayDecoders() {
- }
+ private ArrayDecoders() {}
/**
* A helper used to return multiple values in a Java function. Java doesn't natively support
diff --git a/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java b/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
index 7f36e0983..fb7eb8fee 100644
--- a/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
+++ b/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
@@ -155,7 +155,7 @@ public class InvalidProtocolBufferException extends IOException {
static InvalidProtocolBufferException recursionLimitExceeded() {
return new InvalidProtocolBufferException(
"Protocol message had too many levels of nesting. May be malicious. "
- + "Use CodedInputStream.setRecursionLimit() to increase the depth limit.");
+ + "Use setRecursionLimit() to increase the recursion depth limit.");
}
static InvalidProtocolBufferException sizeLimitExceeded() {
diff --git a/java/core/src/main/java/com/google/protobuf/MessageSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSchema.java
index ae5dddc53..3d9f7b402 100644
--- a/java/core/src/main/java/com/google/protobuf/MessageSchema.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageSchema.java
@@ -3946,6 +3946,7 @@ final class MessageSchema<T> implements Schema<T> {
unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
}
// Unknown field.
+
if (unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) {
continue;
}
@@ -4321,6 +4322,7 @@ final class MessageSchema<T> implements Schema<T> {
if (unknownFields == null) {
unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
}
+
if (!unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) {
return;
}
@@ -4337,6 +4339,7 @@ final class MessageSchema<T> implements Schema<T> {
if (unknownFields == null) {
unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
}
+
if (!unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) {
return;
}
diff --git a/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java
index 987c08632..77b52d3e7 100644
--- a/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java
@@ -301,6 +301,7 @@ final class MessageSetSchema<T> implements Schema<T> {
reader, extension, extensionRegistry, extensions);
return true;
} else {
+
return unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader);
}
} else {
diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java
index 681b824d8..662242492 100644
--- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java
+++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java
@@ -78,7 +78,6 @@ abstract class UnknownFieldSchema<T, B> {
/** Marks unknown fields as immutable. */
abstract void makeImmutable(Object message);
- /** Merges one field into the unknown fields. */
final boolean mergeOneFieldFrom(B unknownFields, Reader reader) throws IOException {
int tag = reader.getTag();
int fieldNumber = WireFormat.getTagFieldNumber(tag);
@@ -111,7 +110,7 @@ abstract class UnknownFieldSchema<T, B> {
}
}
- final void mergeFrom(B unknownFields, Reader reader) throws IOException {
+ private final void mergeFrom(B unknownFields, Reader reader) throws IOException {
while (true) {
if (reader.getFieldNumber() == Reader.READ_DONE
|| !mergeOneFieldFrom(unknownFields, reader)) {
diff --git a/java/lite/src/test/java/com/google/protobuf/LiteTest.java b/java/lite/src/test/java/com/google/protobuf/LiteTest.java
index a58ce95df..cc664e639 100644
--- a/java/lite/src/test/java/com/google/protobuf/LiteTest.java
+++ b/java/lite/src/test/java/com/google/protobuf/LiteTest.java
@@ -33,12 +33,14 @@ package com.google.protobuf;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static java.util.Collections.singletonList;
+import static org.junit.Assert.assertThrows;
import com.google.protobuf.FieldPresenceTestProto.TestAllTypes;
import com.google.protobuf.UnittestImportLite.ImportEnumLite;
import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
import com.google.protobuf.UnittestLite.ForeignEnumLite;
import com.google.protobuf.UnittestLite.ForeignMessageLite;
+import com.google.protobuf.UnittestLite.RecursiveGroup;
import com.google.protobuf.UnittestLite.RecursiveMessage;
import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
import com.google.protobuf.UnittestLite.TestAllTypesLite;
@@ -73,6 +75,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto
index b594b6f6a..7cb988319 100644
--- a/src/google/protobuf/unittest_lite.proto
+++ b/src/google/protobuf/unittest_lite.proto
@@ -523,3 +523,7 @@ message RecursiveMessage {
optional RecursiveMessage recurse = 1;
optional bytes payload = 2;
}
+
+message RecursiveGroup {
+ RecursiveGroup recurse = 1 [features.message_encoding = DELIMITED];
+}
--
2.47.0

482
CVE-2025-4565.patch Normal file
View File

@@ -0,0 +1,482 @@
From 3393d55b62b65c34c5b7d415d0c248d584d931cc Mon Sep 17 00:00:00 2001
From: shaod2 <shaod@google.com>
Date: Wed, 21 May 2025 14:30:53 -0400
Subject: [PATCH 2/2] Manually backport recursion limit enforcement to 25.x
---
python/BUILD.bazel | 6 +
python/google/protobuf/internal/decoder.py | 110 ++++++++++++++----
.../google/protobuf/internal/decoder_test.py | 33 ++++++
.../google/protobuf/internal/message_test.py | 31 +++++
.../protobuf/internal/python_message.py | 6 +-
.../protobuf/internal/self_recursive.proto | 17 +++
6 files changed, 176 insertions(+), 27 deletions(-)
create mode 100644 python/google/protobuf/internal/decoder_test.py
create mode 100644 python/google/protobuf/internal/self_recursive.proto
diff --git a/python/BUILD.bazel b/python/BUILD.bazel
index 192c08a9a..827d51c3d 100644
--- a/python/BUILD.bazel
+++ b/python/BUILD.bazel
@@ -328,6 +328,12 @@ internal_py_test(
data = ["//src/google/protobuf:testdata"],
)
+internal_py_test(
+ name = "decoder_test",
+ srcs = ["google/protobuf/internal/decoder_test.py"],
+ data = ["//src/google/protobuf:testdata"],
+)
+
internal_py_test(
name = "proto_builder_test",
srcs = ["google/protobuf/internal/proto_builder_test.py"],
diff --git a/python/google/protobuf/internal/decoder.py b/python/google/protobuf/internal/decoder.py
index 8ff549381..c6df198de 100755
--- a/python/google/protobuf/internal/decoder.py
+++ b/python/google/protobuf/internal/decoder.py
@@ -195,7 +195,10 @@ def _SimpleDecoder(wire_type, decode_value):
clear_if_default=False):
if is_packed:
local_DecodeVarint = _DecodeVarint
- def DecodePackedField(buffer, pos, end, message, field_dict):
+ def DecodePackedField(
+ buffer, pos, end, message, field_dict, current_depth=0
+ ):
+ del current_depth # unused
value = field_dict.get(key)
if value is None:
value = field_dict.setdefault(key, new_default(message))
@@ -214,7 +217,10 @@ def _SimpleDecoder(wire_type, decode_value):
elif is_repeated:
tag_bytes = encoder.TagBytes(field_number, wire_type)
tag_len = len(tag_bytes)
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ def DecodeRepeatedField(
+ buffer, pos, end, message, field_dict, current_depth=0
+ ):
+ del current_depth # unused
value = field_dict.get(key)
if value is None:
value = field_dict.setdefault(key, new_default(message))
@@ -231,7 +237,8 @@ def _SimpleDecoder(wire_type, decode_value):
return new_pos
return DecodeRepeatedField
else:
- def DecodeField(buffer, pos, end, message, field_dict):
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
+ del current_depth # unused
(new_value, pos) = decode_value(buffer, pos)
if pos > end:
raise _DecodeError('Truncated message.')
@@ -375,7 +382,9 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
enum_type = key.enum_type
if is_packed:
local_DecodeVarint = _DecodeVarint
- def DecodePackedField(buffer, pos, end, message, field_dict):
+ def DecodePackedField(
+ buffer, pos, end, message, field_dict, current_depth=0
+ ):
"""Decode serialized packed enum to its value and a new position.
Args:
@@ -388,6 +397,7 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
Returns:
int, new position in serialized data.
"""
+ del current_depth # unused
value = field_dict.get(key)
if value is None:
value = field_dict.setdefault(key, new_default(message))
@@ -428,7 +438,9 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
elif is_repeated:
tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT)
tag_len = len(tag_bytes)
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ def DecodeRepeatedField(
+ buffer, pos, end, message, field_dict, current_depth=0
+ ):
"""Decode serialized repeated enum to its value and a new position.
Args:
@@ -441,6 +453,7 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
Returns:
int, new position in serialized data.
"""
+ del current_depth # unused
value = field_dict.get(key)
if value is None:
value = field_dict.setdefault(key, new_default(message))
@@ -469,7 +482,7 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
return new_pos
return DecodeRepeatedField
else:
- def DecodeField(buffer, pos, end, message, field_dict):
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
"""Decode serialized repeated enum to its value and a new position.
Args:
@@ -482,6 +495,7 @@ def EnumDecoder(field_number, is_repeated, is_packed, key, new_default,
Returns:
int, new position in serialized data.
"""
+ del current_depth # unused
value_start_pos = pos
(enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
if pos > end:
@@ -563,7 +577,10 @@ def StringDecoder(field_number, is_repeated, is_packed, key, new_default,
tag_bytes = encoder.TagBytes(field_number,
wire_format.WIRETYPE_LENGTH_DELIMITED)
tag_len = len(tag_bytes)
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ def DecodeRepeatedField(
+ buffer, pos, end, message, field_dict, current_depth=0
+ ):
+ del current_depth # unused
value = field_dict.get(key)
if value is None:
value = field_dict.setdefault(key, new_default(message))
@@ -580,7 +597,8 @@ def StringDecoder(field_number, is_repeated, is_packed, key, new_default,
return new_pos
return DecodeRepeatedField
else:
- def DecodeField(buffer, pos, end, message, field_dict):
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
+ del current_depth # unused
(size, pos) = local_DecodeVarint(buffer, pos)
new_pos = pos + size
if new_pos > end:
@@ -604,7 +622,10 @@ def BytesDecoder(field_number, is_repeated, is_packed, key, new_default,
tag_bytes = encoder.TagBytes(field_number,
wire_format.WIRETYPE_LENGTH_DELIMITED)
tag_len = len(tag_bytes)
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ def DecodeRepeatedField(
+ buffer, pos, end, message, field_dict, current_depth=0
+ ):
+ del current_depth # unused
value = field_dict.get(key)
if value is None:
value = field_dict.setdefault(key, new_default(message))
@@ -621,7 +642,8 @@ def BytesDecoder(field_number, is_repeated, is_packed, key, new_default,
return new_pos
return DecodeRepeatedField
else:
- def DecodeField(buffer, pos, end, message, field_dict):
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
+ del current_depth # unused
(size, pos) = local_DecodeVarint(buffer, pos)
new_pos = pos + size
if new_pos > end:
@@ -646,7 +668,9 @@ def GroupDecoder(field_number, is_repeated, is_packed, key, new_default):
tag_bytes = encoder.TagBytes(field_number,
wire_format.WIRETYPE_START_GROUP)
tag_len = len(tag_bytes)
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ def DecodeRepeatedField(
+ buffer, pos, end, message, field_dict, current_depth=0
+ ):
value = field_dict.get(key)
if value is None:
value = field_dict.setdefault(key, new_default(message))
@@ -655,7 +679,13 @@ def GroupDecoder(field_number, is_repeated, is_packed, key, new_default):
if value is None:
value = field_dict.setdefault(key, new_default(message))
# Read sub-message.
- pos = value.add()._InternalParse(buffer, pos, end)
+ current_depth += 1
+ if current_depth > _recursion_limit:
+ raise _DecodeError(
+ 'Error parsing message: too many levels of nesting.'
+ )
+ pos = value.add()._InternalParse(buffer, pos, end, current_depth)
+ current_depth -= 1
# Read end tag.
new_pos = pos+end_tag_len
if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
@@ -667,12 +697,16 @@ def GroupDecoder(field_number, is_repeated, is_packed, key, new_default):
return new_pos
return DecodeRepeatedField
else:
- def DecodeField(buffer, pos, end, message, field_dict):
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
value = field_dict.get(key)
if value is None:
value = field_dict.setdefault(key, new_default(message))
# Read sub-message.
- pos = value._InternalParse(buffer, pos, end)
+ current_depth += 1
+ if current_depth > _recursion_limit:
+ raise _DecodeError('Error parsing message: too many levels of nesting.')
+ pos = value._InternalParse(buffer, pos, end, current_depth)
+ current_depth -= 1
# Read end tag.
new_pos = pos+end_tag_len
if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
@@ -691,7 +725,9 @@ def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
tag_bytes = encoder.TagBytes(field_number,
wire_format.WIRETYPE_LENGTH_DELIMITED)
tag_len = len(tag_bytes)
- def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ def DecodeRepeatedField(
+ buffer, pos, end, message, field_dict, current_depth=0
+ ):
value = field_dict.get(key)
if value is None:
value = field_dict.setdefault(key, new_default(message))
@@ -702,18 +738,27 @@ def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
if new_pos > end:
raise _DecodeError('Truncated message.')
# Read sub-message.
- if value.add()._InternalParse(buffer, pos, new_pos) != new_pos:
+ current_depth += 1
+ if current_depth > _recursion_limit:
+ raise _DecodeError(
+ 'Error parsing message: too many levels of nesting.'
+ )
+ if (
+ value.add()._InternalParse(buffer, pos, new_pos, current_depth)
+ != new_pos
+ ):
# The only reason _InternalParse would return early is if it
# encountered an end-group tag.
raise _DecodeError('Unexpected end-group tag.')
# Predict that the next tag is another copy of the same repeated field.
+ current_depth -= 1
pos = new_pos + tag_len
if buffer[new_pos:pos] != tag_bytes or new_pos == end:
# Prediction failed. Return.
return new_pos
return DecodeRepeatedField
else:
- def DecodeField(buffer, pos, end, message, field_dict):
+ def DecodeField(buffer, pos, end, message, field_dict, current_depth=0):
value = field_dict.get(key)
if value is None:
value = field_dict.setdefault(key, new_default(message))
@@ -722,11 +767,14 @@ def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
new_pos = pos + size
if new_pos > end:
raise _DecodeError('Truncated message.')
- # Read sub-message.
- if value._InternalParse(buffer, pos, new_pos) != new_pos:
+ current_depth += 1
+ if current_depth > _recursion_limit:
+ raise _DecodeError('Error parsing message: too many levels of nesting.')
+ if value._InternalParse(buffer, pos, new_pos, current_depth) != new_pos:
# The only reason _InternalParse would return early is if it encountered
# an end-group tag.
raise _DecodeError('Unexpected end-group tag.')
+ current_depth -= 1
return new_pos
return DecodeField
@@ -882,7 +930,8 @@ def MapDecoder(field_descriptor, new_default, is_message_map):
# Can't read _concrete_class yet; might not be initialized.
message_type = field_descriptor.message_type
- def DecodeMap(buffer, pos, end, message, field_dict):
+ def DecodeMap(buffer, pos, end, message, field_dict, current_depth=0):
+ del current_depth # unused
submsg = message_type._concrete_class()
value = field_dict.get(key)
if value is None:
@@ -964,8 +1013,16 @@ def _SkipGroup(buffer, pos, end):
return pos
pos = new_pos
+DEFAULT_RECURSION_LIMIT = 100
+_recursion_limit = DEFAULT_RECURSION_LIMIT
+
+
+def SetRecursionLimit(new_limit):
+ global _recursion_limit
+ _recursion_limit = new_limit
+
-def _DecodeUnknownFieldSet(buffer, pos, end_pos=None):
+def _DecodeUnknownFieldSet(buffer, pos, end_pos=None, current_depth=0):
"""Decode UnknownFieldSet. Returns the UnknownFieldSet and new position."""
unknown_field_set = containers.UnknownFieldSet()
@@ -975,14 +1032,14 @@ def _DecodeUnknownFieldSet(buffer, pos, end_pos=None):
field_number, wire_type = wire_format.UnpackTag(tag)
if wire_type == wire_format.WIRETYPE_END_GROUP:
break
- (data, pos) = _DecodeUnknownField(buffer, pos, wire_type)
+ (data, pos) = _DecodeUnknownField(buffer, pos, wire_type, current_depth)
# pylint: disable=protected-access
unknown_field_set._add(field_number, wire_type, data)
return (unknown_field_set, pos)
-def _DecodeUnknownField(buffer, pos, wire_type):
+def _DecodeUnknownField(buffer, pos, wire_type, current_depth=0):
"""Decode a unknown field. Returns the UnknownField and new position."""
if wire_type == wire_format.WIRETYPE_VARINT:
@@ -996,7 +1053,12 @@ def _DecodeUnknownField(buffer, pos, wire_type):
data = buffer[pos:pos+size].tobytes()
pos += size
elif wire_type == wire_format.WIRETYPE_START_GROUP:
- (data, pos) = _DecodeUnknownFieldSet(buffer, pos)
+ print("MMP " + str(current_depth))
+ current_depth += 1
+ if current_depth >= _recursion_limit:
+ raise _DecodeError('Error parsing message: too many levels of nesting.')
+ (data, pos) = _DecodeUnknownFieldSet(buffer, pos, None, current_depth)
+ current_depth -= 1
elif wire_type == wire_format.WIRETYPE_END_GROUP:
return (0, -1)
else:
diff --git a/python/google/protobuf/internal/decoder_test.py b/python/google/protobuf/internal/decoder_test.py
new file mode 100644
index 000000000..613b73bcb
--- /dev/null
+++ b/python/google/protobuf/internal/decoder_test.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+#
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Test decoder."""
+
+import unittest
+
+from google.protobuf import message
+from google.protobuf.internal import decoder
+from google.protobuf.internal import testing_refleaks
+from google.protobuf.internal import wire_format
+
+@testing_refleaks.TestCase
+class DecoderTest(unittest.TestCase):
+ def test_decode_unknown_group_field_too_many_levels(self):
+ data = memoryview(b'\023' * 5_000_000)
+ self.assertRaisesRegex(
+ message.DecodeError,
+ 'Error parsing message',
+ decoder._DecodeUnknownField,
+ data,
+ 1,
+ wire_format.WIRETYPE_START_GROUP,
+ 1
+ )
+
+if __name__ == '__main__':
+ unittest.main()
\ No newline at end of file
diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py
index 01fe34321..f62f42971 100755
--- a/python/google/protobuf/internal/message_test.py
+++ b/python/google/protobuf/internal/message_test.py
@@ -52,9 +52,11 @@ cmp = lambda x, y: (x > y) - (x < y)
from google.protobuf.internal import api_implementation # pylint: disable=g-import-not-at-top
from google.protobuf.internal import encoder
+from google.protobuf.internal import decoder
from google.protobuf.internal import more_extensions_pb2
from google.protobuf.internal import more_messages_pb2
from google.protobuf.internal import packed_field_test_pb2
+from google.protobuf.internal import self_recursive_pb2
from google.protobuf.internal import test_proto3_optional_pb2
from google.protobuf.internal import test_util
from google.protobuf.internal import testing_refleaks
@@ -1264,6 +1266,35 @@ class MessageTest(unittest.TestCase):
self.assertEqual(True, m.repeated_bool[0])
+@testing_refleaks.TestCase
+class TestRecursiveGroup(unittest.TestCase):
+
+ def _MakeRecursiveGroupMessage(self, n):
+ msg = self_recursive_pb2.SelfRecursive.RecursiveGroup()
+ sub = msg
+ for _ in range(n):
+ sub = sub.sub_group
+ sub.i = 1
+ return msg.SerializeToString()
+
+ def testRecursiveGroups(self):
+ recurse_msg = self_recursive_pb2.SelfRecursive.RecursiveGroup()
+ data = self._MakeRecursiveGroupMessage(100)
+ recurse_msg.ParseFromString(data)
+ self.assertTrue(recurse_msg.HasField('sub_group'))
+
+ def testRecursiveGroupsException(self):
+ if api_implementation.Type() != 'python':
+ api_implementation._c_module.SetAllowOversizeProtos(False)
+ recurse_msg = self_recursive_pb2.SelfRecursive.RecursiveGroup()
+ data = self._MakeRecursiveGroupMessage(300)
+ with self.assertRaises(message.DecodeError) as context:
+ recurse_msg.ParseFromString(data)
+ self.assertIn('Error parsing message', str(context.exception))
+ if api_implementation.Type() == 'python':
+ self.assertIn('too many levels of nesting', str(context.exception))
+
+
# Class to test proto2-only features (required, extensions, etc.)
@testing_refleaks.TestCase
class Proto2Test(unittest.TestCase):
diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py
index a72276d1a..3f8bb6cbb 100755
--- a/python/google/protobuf/internal/python_message.py
+++ b/python/google/protobuf/internal/python_message.py
@@ -1153,7 +1153,7 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
fields_by_tag = cls._fields_by_tag
message_set_decoders_by_tag = cls._message_set_decoders_by_tag
- def InternalParse(self, buffer, pos, end):
+ def InternalParse(self, buffer, pos, end, current_depth=0):
"""Create a message from serialized bytes.
Args:
@@ -1197,7 +1197,7 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
# TODO(jieluo): remove old_pos.
old_pos = new_pos
(data, new_pos) = decoder._DecodeUnknownField(
- buffer, new_pos, wire_type) # pylint: disable=protected-access
+ buffer, new_pos, wire_type, current_depth) # pylint: disable=protected-access
if new_pos == -1:
return pos
# pylint: disable=protected-access
@@ -1212,7 +1212,7 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
else:
_MaybeAddDecoder(cls, field_des)
field_decoder = field_des._decoders[is_packed]
- pos = field_decoder(buffer, new_pos, end, self, field_dict)
+ pos = field_decoder(buffer, new_pos, end, self, field_dict, current_depth)
if field_des.containing_oneof:
self._UpdateOneofState(field_des)
return pos
diff --git a/python/google/protobuf/internal/self_recursive.proto b/python/google/protobuf/internal/self_recursive.proto
new file mode 100644
index 000000000..2a7aacb0b
--- /dev/null
+++ b/python/google/protobuf/internal/self_recursive.proto
@@ -0,0 +1,17 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2024 Google Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+syntax = "proto2";
+
+package google.protobuf.python.internal;
+
+message SelfRecursive {
+ optional group RecursiveGroup = 1 {
+ optional RecursiveGroup sub_group = 2;
+ optional int32 i = 3;
+ };
+}
\ No newline at end of file
--
2.49.0

View File

@@ -1,5 +0,0 @@
<multibuild>
<package>python-protobuf</package>
<package>protobuf-java</package>
</multibuild>

View File

@@ -0,0 +1,11 @@
--- a/src/google/protobuf/port.h.orig 2023-04-24 14:27:40.734888878 +0200
+++ b/src/google/protobuf/port.h 2023-04-24 14:27:53.607255222 +0200
@@ -33,6 +33,8 @@
// port_def.inc and port_undef.inc so they are not visible from outside of
// protobuf.
+#include <stdint.h>
+
#ifndef GOOGLE_PROTOBUF_PORT_H__
#define GOOGLE_PROTOBUF_PORT_H__

View File

@@ -1,4 +1,3 @@
libprotobuf28_3_0
libprotoc28_3_0
libprotobuf-lite28_3_0
libutf8_range-28_3_0
libprotobuf23_4_0
libprotoc23_4_0
libprotobuf-lite23_4_0

View File

@@ -0,0 +1,428 @@
From 3b0c1b873793da29ff46a42d448cda3b5f937c8a Mon Sep 17 00:00:00 2001
From: Jie Luo <jieluo@google.com>
Date: Mon, 28 Aug 2023 09:58:39 -0700
Subject: [PATCH 1/2] Fix a bug that strips options from descriptor.proto in
Pure Python.
GetOptions on fields (which parse the _serialized_options) will be called for the first time of parse or serialize instead of Build time.
Note: GetOptions on messages are still called in Build time because of message_set_wire_format. If message options are needed in descriptor.proto, a parse error will be raised in GetOptions(). We can check the file to not invoke GetOptions() for descriptor.proto as long as message_set_wire_format not needed in descriptor.proto.
Other options except message options do not invoke GetOptions() in Build time
PiperOrigin-RevId: 560741182
---
python/google/protobuf/descriptor.py | 18 ++--
python/google/protobuf/descriptor_pool.py | 1 +
.../protobuf/internal/python_message.py | 102 +++++++++++++-----
.../protobuf/internal/reflection_test.py | 43 ++++++++
.../protobuf/internal/unknown_fields_test.py | 33 ------
5 files changed, 128 insertions(+), 69 deletions(-)
diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py
index fcb87cab5..4c03a4669 100755
--- a/python/google/protobuf/descriptor.py
+++ b/python/google/protobuf/descriptor.py
@@ -176,14 +176,15 @@ class DescriptorBase(metaclass=DescriptorMetaclass):
raise RuntimeError('Unknown options class name %s!' %
(self._options_class_name))
- with _lock:
- if self._serialized_options is None:
+ if self._serialized_options is None:
+ with _lock:
self._options = options_class()
- else:
- self._options = _ParseOptions(options_class(),
- self._serialized_options)
+ else:
+ options = _ParseOptions(options_class(), self._serialized_options)
+ with _lock:
+ self._options = options
- return self._options
+ return self._options
class _NestedDescriptorBase(DescriptorBase):
@@ -285,6 +286,7 @@ class Descriptor(_NestedDescriptorBase):
oneofs_by_name (dict(str, OneofDescriptor)): Same objects as in
:attr:`oneofs`, but indexed by "name" attribute.
file (FileDescriptor): Reference to file descriptor.
+ is_map_entry: If the message type is a map entry.
"""
@@ -310,6 +312,7 @@ class Descriptor(_NestedDescriptorBase):
serialized_start=None,
serialized_end=None,
syntax=None,
+ is_map_entry=False,
create_key=None):
_message.Message._CheckCalledFromGeneratedFile()
return _message.default_pool.FindMessageTypeByName(full_name)
@@ -322,7 +325,7 @@ class Descriptor(_NestedDescriptorBase):
serialized_options=None,
is_extendable=True, extension_ranges=None, oneofs=None,
file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin
- syntax=None, create_key=None):
+ syntax=None, is_map_entry=False, create_key=None):
"""Arguments to __init__() are as described in the description
of Descriptor fields above.
@@ -372,6 +375,7 @@ class Descriptor(_NestedDescriptorBase):
for oneof in self.oneofs:
oneof.containing_type = self
self.syntax = syntax or "proto2"
+ self._is_map_entry = is_map_entry
@property
def fields_by_camelcase_name(self):
diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py
index 1ebf11834..04bd7a3e9 100644
--- a/python/google/protobuf/descriptor_pool.py
+++ b/python/google/protobuf/descriptor_pool.py
@@ -897,6 +897,7 @@ class DescriptorPool(object):
serialized_start=None,
serialized_end=None,
syntax=syntax,
+ is_map_entry=desc_proto.options.map_entry,
# pylint: disable=protected-access
create_key=descriptor._internal_create_key)
for nested in desc.nested_types:
diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py
index bf9acefd2..a72276d1a 100755
--- a/python/google/protobuf/internal/python_message.py
+++ b/python/google/protobuf/internal/python_message.py
@@ -182,11 +182,14 @@ class GeneratedProtocolMessageType(type):
% (descriptor.full_name))
return
- cls._decoders_by_tag = {}
+ cls._message_set_decoders_by_tag = {}
+ cls._fields_by_tag = {}
if (descriptor.has_options and
descriptor.GetOptions().message_set_wire_format):
- cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
- decoder.MessageSetItemDecoder(descriptor), None)
+ cls._message_set_decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
+ decoder.MessageSetItemDecoder(descriptor),
+ None,
+ )
# Attach stuff to each FieldDescriptor for quick lookup later on.
for field in descriptor.fields:
@@ -272,16 +275,36 @@ def _IsMessageSetExtension(field):
def _IsMapField(field):
return (field.type == _FieldDescriptor.TYPE_MESSAGE and
- field.message_type.has_options and
- field.message_type.GetOptions().map_entry)
+ field.message_type._is_map_entry)
def _IsMessageMapField(field):
value_type = field.message_type.fields_by_name['value']
return value_type.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE
-
def _AttachFieldHelpers(cls, field_descriptor):
+ is_repeated = field_descriptor.label == _FieldDescriptor.LABEL_REPEATED
+ field_descriptor._default_constructor = _DefaultValueConstructorForField(
+ field_descriptor
+ )
+
+ def AddFieldByTag(wiretype, is_packed):
+ tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
+ cls._fields_by_tag[tag_bytes] = (field_descriptor, is_packed)
+
+ AddFieldByTag(
+ type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], False
+ )
+
+ if is_repeated and wire_format.IsTypePackable(field_descriptor.type):
+ # To support wire compatibility of adding packed = true, add a decoder for
+ # packed values regardless of the field's options.
+ AddFieldByTag(wire_format.WIRETYPE_LENGTH_DELIMITED, True)
+
+
+def _MaybeAddEncoder(cls, field_descriptor):
+ if hasattr(field_descriptor, '_encoder'):
+ return
is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED)
is_map_entry = _IsMapField(field_descriptor)
is_packed = field_descriptor.is_packed
@@ -301,11 +324,17 @@ def _AttachFieldHelpers(cls, field_descriptor):
field_descriptor._encoder = field_encoder
field_descriptor._sizer = sizer
- field_descriptor._default_constructor = _DefaultValueConstructorForField(
- field_descriptor)
- def AddDecoder(wiretype, is_packed):
- tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
+
+def _MaybeAddDecoder(cls, field_descriptor):
+ if hasattr(field_descriptor, '_decoders'):
+ return
+
+ is_repeated = field_descriptor.label == _FieldDescriptor.LABEL_REPEATED
+ is_map_entry = _IsMapField(field_descriptor)
+ field_descriptor._decoders = {}
+
+ def AddDecoder(is_packed):
decode_type = field_descriptor.type
if (decode_type == _FieldDescriptor.TYPE_ENUM and
not field_descriptor.enum_type.is_closed):
@@ -337,15 +366,14 @@ def _AttachFieldHelpers(cls, field_descriptor):
field_descriptor, field_descriptor._default_constructor,
not field_descriptor.has_presence)
- cls._decoders_by_tag[tag_bytes] = (field_decoder, oneof_descriptor)
+ field_descriptor._decoders[is_packed] = field_decoder
- AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type],
- False)
+ AddDecoder(False)
if is_repeated and wire_format.IsTypePackable(field_descriptor.type):
# To support wire compatibility of adding packed = true, add a decoder for
# packed values regardless of the field's options.
- AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True)
+ AddDecoder(True)
def _AddClassAttributesForNestedExtensions(descriptor, dictionary):
@@ -1031,12 +1059,17 @@ def _AddByteSizeMethod(message_descriptor, cls):
size = 0
descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
+ if descriptor._is_map_entry:
# Fields of map entry should always be serialized.
- size = descriptor.fields_by_name['key']._sizer(self.key)
- size += descriptor.fields_by_name['value']._sizer(self.value)
+ key_field = descriptor.fields_by_name['key']
+ _MaybeAddEncoder(cls, key_field)
+ size = key_field._sizer(self.key)
+ value_field = descriptor.fields_by_name['value']
+ _MaybeAddEncoder(cls, value_field)
+ size += value_field._sizer(self.value)
else:
for field_descriptor, field_value in self.ListFields():
+ _MaybeAddEncoder(cls, field_descriptor)
size += field_descriptor._sizer(field_value)
for tag_bytes, value_bytes in self._unknown_fields:
size += len(tag_bytes) + len(value_bytes)
@@ -1079,14 +1112,17 @@ def _AddSerializePartialToStringMethod(message_descriptor, cls):
deterministic = bool(deterministic)
descriptor = self.DESCRIPTOR
- if descriptor.GetOptions().map_entry:
+ if descriptor._is_map_entry:
# Fields of map entry should always be serialized.
- descriptor.fields_by_name['key']._encoder(
- write_bytes, self.key, deterministic)
- descriptor.fields_by_name['value']._encoder(
- write_bytes, self.value, deterministic)
+ key_field = descriptor.fields_by_name['key']
+ _MaybeAddEncoder(cls, key_field)
+ key_field._encoder(write_bytes, self.key, deterministic)
+ value_field = descriptor.fields_by_name['value']
+ _MaybeAddEncoder(cls, value_field)
+ value_field._encoder(write_bytes, self.value, deterministic)
else:
for field_descriptor, field_value in self.ListFields():
+ _MaybeAddEncoder(cls, field_descriptor)
field_descriptor._encoder(write_bytes, field_value, deterministic)
for tag_bytes, value_bytes in self._unknown_fields:
write_bytes(tag_bytes)
@@ -1114,7 +1150,8 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
local_ReadTag = decoder.ReadTag
local_SkipField = decoder.SkipField
- decoders_by_tag = cls._decoders_by_tag
+ fields_by_tag = cls._fields_by_tag
+ message_set_decoders_by_tag = cls._message_set_decoders_by_tag
def InternalParse(self, buffer, pos, end):
"""Create a message from serialized bytes.
@@ -1137,8 +1174,14 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
unknown_field_set = self._unknown_field_set
while pos != end:
(tag_bytes, new_pos) = local_ReadTag(buffer, pos)
- field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (None, None))
- if field_decoder is None:
+ field_decoder, field_des = message_set_decoders_by_tag.get(
+ tag_bytes, (None, None)
+ )
+ if field_decoder:
+ pos = field_decoder(buffer, new_pos, end, self, field_dict)
+ continue
+ field_des, is_packed = fields_by_tag.get(tag_bytes, (None, None))
+ if field_des is None:
if not self._unknown_fields: # pylint: disable=protected-access
self._unknown_fields = [] # pylint: disable=protected-access
if unknown_field_set is None:
@@ -1167,9 +1210,11 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
(tag_bytes, buffer[old_pos:new_pos].tobytes()))
pos = new_pos
else:
+ _MaybeAddDecoder(cls, field_des)
+ field_decoder = field_des._decoders[is_packed]
pos = field_decoder(buffer, new_pos, end, self, field_dict)
- if field_desc:
- self._UpdateOneofState(field_desc)
+ if field_des.containing_oneof:
+ self._UpdateOneofState(field_des)
return pos
cls._InternalParse = InternalParse
@@ -1205,8 +1250,7 @@ def _AddIsInitializedMethod(message_descriptor, cls):
for field, value in list(self._fields.items()): # dict can change size!
if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
if field.label == _FieldDescriptor.LABEL_REPEATED:
- if (field.message_type.has_options and
- field.message_type.GetOptions().map_entry):
+ if (field.message_type._is_map_entry):
continue
for element in value:
if not element.IsInitialized():
diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py
index 0708d51e6..c5a600fa9 100755
--- a/python/google/protobuf/internal/reflection_test.py
+++ b/python/google/protobuf/internal/reflection_test.py
@@ -2053,6 +2053,49 @@ class Proto2ReflectionTest(unittest.TestCase):
# dependency on the C++ logging code.
self.assertIn('test_file_descriptor_errors.msg1', str(cm.exception))
+ def testDescriptorProtoHasFileOptions(self):
+ self.assertTrue(descriptor_pb2.DESCRIPTOR.has_options)
+ self.assertEqual(
+ descriptor_pb2.DESCRIPTOR.GetOptions().java_package,
+ 'com.google.protobuf',
+ )
+
+ def testDescriptorProtoHasFieldOptions(self):
+ self.assertTrue(descriptor_pb2.DESCRIPTOR.has_options)
+ self.assertEqual(
+ descriptor_pb2.DESCRIPTOR.GetOptions().java_package,
+ 'com.google.protobuf',
+ )
+ packed_desc = (
+ descriptor_pb2.SourceCodeInfo.DESCRIPTOR.nested_types_by_name.get(
+ 'Location'
+ ).fields_by_name.get('path')
+ )
+ self.assertTrue(packed_desc.has_options)
+ self.assertTrue(packed_desc.GetOptions().packed)
+
+ def testDescriptorProtoHasFeatureOptions(self):
+ self.assertTrue(descriptor_pb2.DESCRIPTOR.has_options)
+ self.assertEqual(
+ descriptor_pb2.DESCRIPTOR.GetOptions().java_package,
+ 'com.google.protobuf',
+ )
+ presence_desc = descriptor_pb2.FeatureSet.DESCRIPTOR.fields_by_name.get(
+ 'field_presence'
+ )
+ self.assertTrue(presence_desc.has_options)
+ self.assertEqual(
+ presence_desc.GetOptions().retention,
+ descriptor_pb2.FieldOptions.OptionRetention.RETENTION_RUNTIME,
+ )
+ self.assertListsEqual(
+ presence_desc.GetOptions().targets,
+ [
+ descriptor_pb2.FieldOptions.OptionTargetType.TARGET_TYPE_FIELD,
+ descriptor_pb2.FieldOptions.OptionTargetType.TARGET_TYPE_FILE,
+ ],
+ )
+
def testStringUTF8Serialization(self):
proto = message_set_extensions_pb2.TestMessageSet()
extension_message = message_set_extensions_pb2.TestMessageSetExtension2
diff --git a/python/google/protobuf/internal/unknown_fields_test.py b/python/google/protobuf/internal/unknown_fields_test.py
index ec1aa1b45..9a8d7d751 100755
--- a/python/google/protobuf/internal/unknown_fields_test.py
+++ b/python/google/protobuf/internal/unknown_fields_test.py
@@ -177,25 +177,6 @@ class UnknownFieldsAccessorsTest(unittest.TestCase):
self.empty_message = unittest_pb2.TestEmptyMessage()
self.empty_message.ParseFromString(self.all_fields_data)
- # InternalCheckUnknownField() is an additional Pure Python check which checks
- # a detail of unknown fields. It cannot be used by the C++
- # implementation because some protect members are called.
- # The test is added for historical reasons. It is not necessary as
- # serialized string is checked.
- # TODO(jieluo): Remove message._unknown_fields.
- def InternalCheckUnknownField(self, name, expected_value):
- if api_implementation.Type() != 'python':
- return
- field_descriptor = self.descriptor.fields_by_name[name]
- wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
- field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
- result_dict = {}
- for tag_bytes, value in self.empty_message._unknown_fields:
- if tag_bytes == field_tag:
- decoder = unittest_pb2.TestAllTypes._decoders_by_tag[tag_bytes][0]
- decoder(memoryview(value), 0, len(value), self.all_fields, result_dict)
- self.assertEqual(expected_value, result_dict[field_descriptor])
-
def CheckUnknownField(self, name, unknown_field_set, expected_value):
field_descriptor = self.descriptor.fields_by_name[name]
expected_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[
@@ -223,50 +204,36 @@ class UnknownFieldsAccessorsTest(unittest.TestCase):
self.CheckUnknownField('optional_nested_enum',
unknown_field_set,
self.all_fields.optional_nested_enum)
- self.InternalCheckUnknownField('optional_nested_enum',
- self.all_fields.optional_nested_enum)
# Test repeated enum.
self.CheckUnknownField('repeated_nested_enum',
unknown_field_set,
self.all_fields.repeated_nested_enum)
- self.InternalCheckUnknownField('repeated_nested_enum',
- self.all_fields.repeated_nested_enum)
# Test varint.
self.CheckUnknownField('optional_int32',
unknown_field_set,
self.all_fields.optional_int32)
- self.InternalCheckUnknownField('optional_int32',
- self.all_fields.optional_int32)
# Test fixed32.
self.CheckUnknownField('optional_fixed32',
unknown_field_set,
self.all_fields.optional_fixed32)
- self.InternalCheckUnknownField('optional_fixed32',
- self.all_fields.optional_fixed32)
# Test fixed64.
self.CheckUnknownField('optional_fixed64',
unknown_field_set,
self.all_fields.optional_fixed64)
- self.InternalCheckUnknownField('optional_fixed64',
- self.all_fields.optional_fixed64)
# Test length delimited.
self.CheckUnknownField('optional_string',
unknown_field_set,
self.all_fields.optional_string.encode('utf-8'))
- self.InternalCheckUnknownField('optional_string',
- self.all_fields.optional_string)
# Test group.
self.CheckUnknownField('optionalgroup',
unknown_field_set,
(17, 0, 117))
- self.InternalCheckUnknownField('optionalgroup',
- self.all_fields.optionalgroup)
self.assertEqual(98, len(unknown_field_set))
--
2.49.0

9
manifest.txt.in Normal file
View File

@@ -0,0 +1,9 @@
Manifest-Version: 1.0
Created-By: stick@gk2.sk
Name: com/google/protobuf/
Specification-Title: Google Protocol Buffers
Specification-Version: @VERSION@
Specification-Vendor: stick@gk2.sk
Implementation-Title: com.google.protobuf
Implementation-Version: @VERSION@
Implementation-Vendor: stick@gk2.sk

View File

@@ -1,5 +0,0 @@
#!/bin/sh
cp protobuf.changes protobuf-java.changes
cp protobuf.changes python-protobuf.changes
osc service runall format_spec_file

BIN
protobuf-23.4.tar.gz Normal file

Binary file not shown.

BIN
protobuf-28.3.tar.gz (Stored with Git LFS)

Binary file not shown.

BIN
protobuf-5.28.3.tar.gz (Stored with Git LFS)

Binary file not shown.

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>4.28.3</version>
</parent>
<artifactId>protobuf-java</artifactId>
<packaging>jar</packaging>
<name>Protocol Buffers [Core]</name>
<description>
Core Protocol Buffers library. Protocol Buffers are a way of encoding structured data in an
efficient yet extensible format.
</description>
<dependencies>
</dependencies>
<build>
<plugins>
<!-- OSGI bundle configuration -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Automatic-Module-Name>com.google.protobuf</Automatic-Module-Name> <!-- Java9+ Jigsaw module name -->
<Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
<Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
<Export-Package>com.google.protobuf;version=${project.version}</Export-Package>
<Import-Package>sun.misc;resolution:=optional,*</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>4.28.3</version>
</parent>
<artifactId>protobuf-java-util</artifactId>
<packaging>jar</packaging>
<name>Protocol Buffers [Util]</name>
<description>Utilities for Protocol Buffers</description>
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>4.28.3</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<version>2.18.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.0.1-jre</version>
</dependency>
<dependency>
<groupId>com.google.j2objc</groupId>
<artifactId>j2objc-annotations</artifactId>
<version>2.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- OSGI bundle configuration -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Automatic-Module-Name>com.google.protobuf.util</Automatic-Module-Name> <!-- Java9+ Jigsaw module name -->
<Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
<Bundle-SymbolicName>com.google.protobuf.util</Bundle-SymbolicName>
<Export-Package>com.google.protobuf.util;version=${project.version}</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

File diff suppressed because it is too large Load Diff

View File

@@ -1,283 +0,0 @@
#
# spec file for package protobuf-java
#
# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2024 Andreas Stieger <Andreas.Stieger@gmx.de>
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
%define tarname protobuf
Name: protobuf-java
Version: 28.3
Release: 0
Summary: Java Bindings for Google Protocol Buffers
License: BSD-3-Clause
Group: Development/Libraries/Java
URL: https://github.com/protocolbuffers/protobuf
Source0: https://github.com/protocolbuffers/protobuf/releases/download/v%{version}/%{tarname}-%{version}.tar.gz
Source1: https://repo1.maven.org/maven2/com/google/protobuf/%{name}/4.%{version}/%{name}-4.%{version}.pom
Source2: https://repo1.maven.org/maven2/com/google/protobuf/%{name}lite/4.%{version}/%{name}lite-4.%{version}.pom
Source3: https://repo1.maven.org/maven2/com/google/protobuf/%{name}-util/4.%{version}/%{name}-util-4.%{version}.pom
BuildRequires: fdupes
BuildRequires: java-devel >= 1.8
BuildRequires: maven-local
BuildRequires: protobuf-devel >= %{version}
BuildRequires: mvn(com.google.code.findbugs:jsr305)
BuildRequires: mvn(com.google.code.gson:gson)
BuildRequires: mvn(com.google.errorprone:error_prone_annotations)
BuildRequires: mvn(com.google.guava:guava)
BuildRequires: mvn(com.google.j2objc:j2objc-annotations)
BuildRequires: mvn(org.apache.felix:maven-bundle-plugin)
Requires: java >= 1.8
BuildArch: noarch
%description
Protocol Buffers are a way of encoding structured data in an efficient yet
extensible format. Google uses Protocol Buffers for almost all of its internal
RPC protocols and file formats.
This package contains the Java bindings.
%package parent
Summary: Java Bindings for Google Protocol Buffers (parent pom)
%description parent
Protocol Buffers are a way of encoding structured data in an efficient yet
extensible format. Google uses Protocol Buffers for almost all of its internal
RPC protocols and file formats.
This package contains the parent pom of the Java bindings.
%package bom
Summary: Java Bindings for Google Protocol Buffers (bom)
%description bom
Protocol Buffers are a way of encoding structured data in an efficient yet
extensible format. Google uses Protocol Buffers for almost all of its internal
RPC protocols and file formats.
This package contains the bill-of-materials pom of the Java bindings.
%package javadoc
Summary: Javadoc for %{name}
Group: Documentation/HTML
%description javadoc
This package contains the API documentation for %{name}.
%prep
%autosetup -p1 -n %{tarname}-%{version}
# The previous blank line is crucial for older system being able
# to use the autosetup macro
pushd java
cp %{SOURCE1} core/pom.xml
cp %{SOURCE2} lite/pom.xml
cp %{SOURCE3} util/pom.xml
%pom_disable_module kotlin
%pom_disable_module kotlin-lite
%pom_remove_plugin :animal-sniffer-maven-plugin
%pom_xpath_set "pom:plugin[pom:artifactId[text()='maven-compiler-plugin']]/pom:configuration/pom:source" "1.8"
%pom_xpath_set "pom:plugin[pom:artifactId[text()='maven-compiler-plugin']]/pom:configuration/pom:target" "1.8"
%{mvn_package} :{*}-parent parent
%{mvn_package} :{*}-bom bom
%{mvn_file} :{*} @1
%{mvn_file} :%{name} %{tarname}
popd
%build
pushd java
# Core build
protoc \
--java_out=core/src/main/java \
--proto_path=../src \
--proto_path=core/src/main/resources/google/protobuf \
core/src/main/resources/google/protobuf/java_features.proto \
../src/google/protobuf/any.proto \
../src/google/protobuf/api.proto \
../src/google/protobuf/descriptor.proto \
../src/google/protobuf/duration.proto \
../src/google/protobuf/empty.proto \
../src/google/protobuf/field_mask.proto \
../src/google/protobuf/source_context.proto \
../src/google/protobuf/struct.proto \
../src/google/protobuf/timestamp.proto \
../src/google/protobuf/type.proto \
../src/google/protobuf/wrappers.proto \
../src/google/protobuf/compiler/plugin.proto
cp \
../src/google/protobuf/any.proto \
../src/google/protobuf/api.proto \
../src/google/protobuf/descriptor.proto \
../src/google/protobuf/duration.proto \
../src/google/protobuf/empty.proto \
../src/google/protobuf/field_mask.proto \
../src/google/protobuf/source_context.proto \
../src/google/protobuf/struct.proto \
../src/google/protobuf/timestamp.proto \
../src/google/protobuf/type.proto \
../src/google/protobuf/wrappers.proto \
../src/google/protobuf/compiler/plugin.proto \
core/src/main/resources/google/protobuf/
# Lite build
mkdir -p lite/src/main/resources/google/protobuf
mkdir -p lite/src/main/java/com/google/protobuf
# lite sources from lite/BUILD.bazel
cp \
core/src/main/java/com/google/protobuf/AbstractMessageLite.java \
core/src/main/java/com/google/protobuf/AbstractParser.java \
core/src/main/java/com/google/protobuf/AbstractProtobufList.java \
core/src/main/java/com/google/protobuf/AllocatedBuffer.java \
core/src/main/java/com/google/protobuf/Android.java \
core/src/main/java/com/google/protobuf/ArrayDecoders.java \
core/src/main/java/com/google/protobuf/BinaryReader.java \
core/src/main/java/com/google/protobuf/BinaryWriter.java \
core/src/main/java/com/google/protobuf/BooleanArrayList.java \
core/src/main/java/com/google/protobuf/BufferAllocator.java \
core/src/main/java/com/google/protobuf/ByteBufferWriter.java \
core/src/main/java/com/google/protobuf/ByteOutput.java \
core/src/main/java/com/google/protobuf/ByteString.java \
core/src/main/java/com/google/protobuf/CanIgnoreReturnValue.java \
core/src/main/java/com/google/protobuf/CheckReturnValue.java \
core/src/main/java/com/google/protobuf/CodedInputStream.java \
core/src/main/java/com/google/protobuf/CodedInputStreamReader.java \
core/src/main/java/com/google/protobuf/CodedOutputStream.java \
core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java \
core/src/main/java/com/google/protobuf/CompileTimeConstant.java \
core/src/main/java/com/google/protobuf/DoubleArrayList.java \
core/src/main/java/com/google/protobuf/ExperimentalApi.java \
core/src/main/java/com/google/protobuf/ExtensionLite.java \
core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java \
core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java \
core/src/main/java/com/google/protobuf/ExtensionSchema.java \
core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java \
core/src/main/java/com/google/protobuf/ExtensionSchemas.java \
core/src/main/java/com/google/protobuf/FieldInfo.java \
core/src/main/java/com/google/protobuf/FieldSet.java \
core/src/main/java/com/google/protobuf/FieldType.java \
core/src/main/java/com/google/protobuf/FloatArrayList.java \
core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java \
core/src/main/java/com/google/protobuf/GeneratedMessageLite.java \
core/src/main/java/com/google/protobuf/InlineMe.java \
core/src/main/java/com/google/protobuf/IntArrayList.java \
core/src/main/java/com/google/protobuf/Internal.java \
core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \
core/src/main/java/com/google/protobuf/IterableByteBufferInputStream.java \
core/src/main/java/com/google/protobuf/Java8Compatibility.java \
core/src/main/java/com/google/protobuf/JavaType.java \
core/src/main/java/com/google/protobuf/LazyField.java \
core/src/main/java/com/google/protobuf/LazyFieldLite.java \
core/src/main/java/com/google/protobuf/LazyStringArrayList.java \
core/src/main/java/com/google/protobuf/LazyStringList.java \
core/src/main/java/com/google/protobuf/ListFieldSchema.java \
core/src/main/java/com/google/protobuf/ListFieldSchemaLite.java \
core/src/main/java/com/google/protobuf/ListFieldSchemas.java \
core/src/main/java/com/google/protobuf/LongArrayList.java \
core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java \
core/src/main/java/com/google/protobuf/MapEntryLite.java \
core/src/main/java/com/google/protobuf/MapFieldLite.java \
core/src/main/java/com/google/protobuf/MapFieldSchema.java \
core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java \
core/src/main/java/com/google/protobuf/MapFieldSchemas.java \
core/src/main/java/com/google/protobuf/MessageInfo.java \
core/src/main/java/com/google/protobuf/MessageInfoFactory.java \
core/src/main/java/com/google/protobuf/MessageLite.java \
core/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java \
core/src/main/java/com/google/protobuf/MessageLiteToString.java \
core/src/main/java/com/google/protobuf/MessageSchema.java \
core/src/main/java/com/google/protobuf/MessageSetSchema.java \
core/src/main/java/com/google/protobuf/MutabilityOracle.java \
core/src/main/java/com/google/protobuf/NewInstanceSchema.java \
core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java \
core/src/main/java/com/google/protobuf/NewInstanceSchemas.java \
core/src/main/java/com/google/protobuf/OneofInfo.java \
core/src/main/java/com/google/protobuf/Parser.java \
core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java \
core/src/main/java/com/google/protobuf/ProtoSyntax.java \
core/src/main/java/com/google/protobuf/Protobuf.java \
core/src/main/java/com/google/protobuf/ProtobufArrayList.java \
core/src/main/java/com/google/protobuf/ProtocolStringList.java \
core/src/main/java/com/google/protobuf/RawMessageInfo.java \
core/src/main/java/com/google/protobuf/Reader.java \
core/src/main/java/com/google/protobuf/RopeByteString.java \
core/src/main/java/com/google/protobuf/RuntimeVersion.java \
core/src/main/java/com/google/protobuf/Schema.java \
core/src/main/java/com/google/protobuf/SchemaFactory.java \
core/src/main/java/com/google/protobuf/SchemaUtil.java \
core/src/main/java/com/google/protobuf/SmallSortedMap.java \
core/src/main/java/com/google/protobuf/StructuralMessageInfo.java \
core/src/main/java/com/google/protobuf/TextFormatEscaper.java \
core/src/main/java/com/google/protobuf/UninitializedMessageException.java \
core/src/main/java/com/google/protobuf/UnknownFieldSchema.java \
core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java \
core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java \
core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java \
core/src/main/java/com/google/protobuf/UnsafeByteOperations.java \
core/src/main/java/com/google/protobuf/UnsafeUtil.java \
core/src/main/java/com/google/protobuf/Utf8.java \
core/src/main/java/com/google/protobuf/WireFormat.java \
core/src/main/java/com/google/protobuf/Writer.java \
lite/src/main/java/com/google/protobuf/
protoc \
--java_out=lite:lite/src/main/java \
--proto_path=../src \
--proto_path=core/src/main/resources/google/protobuf \
../src/google/protobuf/any.proto \
../src/google/protobuf/api.proto \
../src/google/protobuf/descriptor.proto \
../src/google/protobuf/duration.proto \
../src/google/protobuf/empty.proto \
../src/google/protobuf/field_mask.proto \
../src/google/protobuf/source_context.proto \
../src/google/protobuf/struct.proto \
../src/google/protobuf/timestamp.proto \
../src/google/protobuf/type.proto \
../src/google/protobuf/wrappers.proto
cp \
../src/google/protobuf/any.proto \
../src/google/protobuf/api.proto \
../src/google/protobuf/descriptor.proto \
../src/google/protobuf/duration.proto \
../src/google/protobuf/empty.proto \
../src/google/protobuf/field_mask.proto \
../src/google/protobuf/source_context.proto \
../src/google/protobuf/struct.proto \
../src/google/protobuf/timestamp.proto \
../src/google/protobuf/type.proto \
../src/google/protobuf/wrappers.proto \
lite/src/main/resources/google/protobuf/
%{mvn_build} -f -- -Dprotoc=$(type -p protoc)
popd
%install
pushd java
%mvn_install
%fdupes -s %{buildroot}%{_javadocdir}
%files -f java/.mfiles
%license LICENSE
%files bom -f java/.mfiles-bom
%files parent -f java/.mfiles-parent
%files javadoc -f java/.mfiles-javadoc
%license LICENSE
%changelog

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>4.28.3</version>
</parent>
<artifactId>protobuf-javalite</artifactId>
<packaging>jar</packaging>
<name>Protocol Buffers [Lite]</name>
<description>
Lite version of Protocol Buffers library. This version is optimized for code size, but does
not guarantee API/ABI stability.
</description>
<dependencies>
</dependencies>
<build>
<plugins>
<!-- OSGI bundle configuration -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Automatic-Module-Name>com.google.protobuf</Automatic-Module-Name> <!-- Java9+ Jigsaw module name -->
<Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
<Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
<Export-Package>com.google.protobuf;version=${project.version}</Export-Package>
<Import-Package>sun.misc;resolution:=optional,*</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

3
protobuf-rpmlintrc Normal file
View File

@@ -0,0 +1,3 @@
addFilter("shlib-policy-name-error")
addFilter("env-script-interpreter")
addFilter("spurious-executable-perm")

View File

@@ -1,286 +1,22 @@
-------------------------------------------------------------------
Mon Oct 28 08:20:17 UTC 2024 - Dirk Müller <dmueller@suse.com>
Tue Jun 17 08:01:50 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
- python: switch to pypi package to get the cythonized component
- drop python-protobuf-setup_py.patch (obsolete)
- Add fix-options-parsing-bug.patch to backport changes required for CVE fix
- Add CVE-2025-4565.patch to fix parsing of untrusted Protocol Buffers
data containing an arbitrary number of recursive groups or messages
can lead to crash due to RecursionError (bsc#1244663, CVE-2025-4565)
-------------------------------------------------------------------
Sat Oct 26 08:40:48 UTC 2024 - Jan Engelhardt <jengelh@inai.de>
Fri Feb 7 08:31:31 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
- Add versionize-shlibs.patch, delete static-utf8-ranges.patch
* Build the libutf8_range and libutf8_validity as shared library
to conform to SLPP
- Add patch to fix use-after-free vulnerability in C++ JSON parser
* CVE-2024-2410.patch (bsc#1223947, CVE-2024-2410)
-------------------------------------------------------------------
Fri Oct 25 15:24:11 UTC 2024 - Dirk Müller <dmueller@suse.com>
Tue Oct 15 06:15:25 UTC 2024 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
- update to 28.3:
* Fix packed reflection handling bug in edition 2023.
* Mute the minor version warning
* Populate Kotlin Manifest Files
* Re-export includingDefaultValueFields in deprecated state for
important Cloud customer. (https://github.com/protocolbuffers
/protobuf/commit/3b62d78dc70d2b43af5998d427452246279363c7)
* Cherrypick restoration of mutableCopy helpers (https://github
.com/protocolbuffers/protobuf/commit/3ea568a9b6107ebf0d617c47
6f53a31490fd3182)
* Mute the minor version warning
-------------------------------------------------------------------
Thu Oct 24 20:56:51 UTC 2024 - Fridrich Strba <fstrba@suse.com>
- Added patch: static-utf8-ranges.patch
* Build the libutf8_range and libutf8_validity as static library
to avoid installcheck failures
-------------------------------------------------------------------
Wed Oct 23 08:44:06 UTC 2024 - Fridrich Strba <fstrba@suse.com>
- Java: fix generating proper maven descriptor for protoc on aarch64
- Java: rename global variable buildarch -> protoc_arch to avoid
name clash on sle15
-------------------------------------------------------------------
Mon Oct 21 20:55:21 UTC 2024 - Fridrich Strba <fstrba@suse.com>
- Java: mimic the bazel build and build also the protobuf-javalite
artifact
-------------------------------------------------------------------
Mon Oct 21 13:27:27 UTC 2024 - Dirk Müller <dmueller@suse.com>
- Python: keep building for 15.4+
-------------------------------------------------------------------
Mon Oct 21 11:34:51 UTC 2024 - Fridrich Strba <fstrba@suse.com>
- Java: add maven artifact metadata for the protoc binary
* make the main package archful, since the protoc artifact
metadata declares the architecture of the binary
-------------------------------------------------------------------
Sat Oct 19 17:03:05 UTC 2024 - Fridrich Strba <fstrba@suse.com>
- Python: Generate the headers that the Cython native library needs
to build
- Added patch:
* python-protobuf-setup_py.patch
+ make the bitrotten setup.py find the source files for the
C native library
+ Modify the code so that the build works on python 3.6 too
-------------------------------------------------------------------
Tue Oct 15 13:49:20 UTC 2024 - Fridrich Strba <fstrba@suse.com>
- Splitting the java and python parts into separate packages
* allows much more readable and simple spec files
* allows disabling bindings separately from the main package
- Build protobuf-java with the upstream version that is currently
4.28.2
- Add a pre_checkin.sh script to synchronize the changes files
-------------------------------------------------------------------
Mon Oct 7 10:46:17 UTC 2024 - Adrian Schröter <adrian@suse.de>
- update to 28.2
C++: Fix cord handling in DynamicMessage and oneofs
Java: Add recursion check when parsing unknown fields
- python packages became arch dependend
-------------------------------------------------------------------
Sun Aug 11 09:49:53 UTC 2024 - Andreas Stieger <andreas.stieger@gmx.de>
- tweak and correct how minimum version of abseil is specified
(20230125 to 20230125.3)
- Remove explicit requirements of the protobuf-devel package, as
the they are autogenerated when needed
-------------------------------------------------------------------
Fri Aug 2 16:42:09 UTC 2024 - Andreas Stieger <andreas.stieger@gmx.de>
- update to 25.4:
* Java: Check that size is non-negative when reading string or
bytes in StreamDecoder
* Java: Add Automatic-Module-Name
* PHP: Regen stale files
* Ruby C-Extension: Regen stale files
-------------------------------------------------------------------
Sat Mar 9 20:36:14 UTC 2024 - Andreas Stieger <andreas.stieger@gmx.de>
- update to 25.3:
* Possibly breaking changes to: C++, Java, PHP, Python, Ruby
* message.UnknownFields() is deprecated in pure Python and C++
extensions, it will be removed in v26. Use the new
UnknownFieldSet(message) support in unknown_fields.py as a
replacement
- make python and java packages noarch
- drop add-missing-stdint-header.patch no longer required
-------------------------------------------------------------------
Fri Mar 8 16:25:26 UTC 2024 - Andreas Stieger <andreas.stieger@gmx.de>
- update to 25.2:
* Only substitute prefixes during installation setup
* Register a shutdown delete for C++ feature defaults
-------------------------------------------------------------------
Tue Jan 2 13:52:00 UTC 2024 - Dirk Müller <dmueller@suse.com>
- update to 25.1:
* Raise warnings for deprecated python syntax usages
* Add support for extensions in CRuby, JRuby, and FFI Ruby
* Add support for options in CRuby, JRuby and FFI (#14594)
- update to 25.0:
* Implement proto2/proto3 with editions
* Defines Protobuf compiler version strings as macros and
separates out suffix string definition.
* Add utf8_validation feature back to the global feature set.
* Setting up version updater to prepare for poison pills and
embedding version info into C++, Python and Java gencode.
* Merge the protobuf and upb Bazel repos
* Editions: Introduce functionality to protoc for generating
edition feature set defaults.
* Editions: Migrate edition strings to enum in C++ code.
* Create a reflection helper for ExtensionIdentifier.
* Editions: Provide an API for C++ generators to specify their
features.
* Editions: Refactor feature resolution to use an intermediate
message.
* Publish extension declarations with declaration
verifications.
* Editions: Stop propagating partially resolved feature sets to
plugins.
* Editions: Migrate string_field_validation to a C++ feature
* Editions: Include defaults for any features in the generated
pool.
* Protoc: parser rejects explicit use of map_entry option
* Protoc: validate that reserved range start is before end
* Protoc: support identifiers as reserved names in addition to
string literals (only in editions)
* Drop support for Bazel 5.
* Allow code generators to specify whether or not they support
editions.
# C++
* Set `PROTOBUF_EXPORT` on
`InternalOutOfLineDeleteMessageLite()`
* Update stale checked-in files
* Apply PROTOBUF_NOINLINE to declarations of some functions
that want it.
* Implement proto2/proto3 with editions
* Make JSON UTF-8 boundary check inclusive of the largest
possible UTF-8 character.
* Reduce `Map::size_type` to 32-bits. Protobuf containers can't
have more than that
* Defines Protobuf compiler version strings as macros and
separates out suffix string definition.
* Add `ABSL_ATTRIBUTE_LIFETIME_BOUND` attribute on generated
oneof accessors.
* Fix bug in reflection based Swap of map fields.
* Add utf8_validation feature back to the global feature set.
* Setting up version updater to prepare for poison pills and
embedding version info into C++, Python and Java gencode.
* Add prefetching to arena allocations.
* Add `ABSL_ATTRIBUTE_LIFETIME_BOUND` attribute on generated
repeated and map field accessors.
* Editions: Migrate edition strings to enum in C++ code.
* Create a reflection helper for ExtensionIdentifier.
* Editions: Provide an API for C++ generators to specify their
features.
* Add `ABSL_ATTRIBUTE_LIFETIME_BOUND` attribute on generated
string field accessors.
* Editions: Refactor feature resolution to use an intermediate
message.
* Fixes for 32-bit MSVC.
* Publish extension declarations with declaration
verifications.
* Export the constants in protobuf's any.h to support DLL
builds.
* Implement AbslStringify for the Descriptor family of types.
* Add `ABSL_ATTRIBUTE_LIFETIME_BOUND` attribute on generated
message field accessors.
* Editions: Stop propagating partially resolved feature sets to
plugins.
* Editions: Migrate string_field_validation to a C++ feature
* Editions: Include defaults for any features in the generated
pool.
* Introduce C++ feature for UTF8 validation.
* Protoc: validate that reserved range start is before end
* Remove option to disable the table-driven parser in protoc.
* Lock down ctype=CORD in proto file.
* Support split repeated fields.
* In OSS mode omit some extern template specializations.
* Allow code generators to specify whether or not they support
editions.
# Java
* Implement proto2/proto3 with editions
* Remove synthetic oneofs from Java gencode field accessor
tables.
* Timestamps.parse: Add error handling for invalid
hours/minutes in the timezone offset.
* Defines Protobuf compiler version strings as macros and
separates out suffix string definition.
* Add `ABSL_ATTRIBUTE_LIFETIME_BOUND` attribute on generated
oneof accessors.
* Add missing debugging version info to Protobuf Java gencode
when multiple files are generated.
* Fix a bad cast in putBuilderIfAbsent when already present due
to using the result of put() directly (which is null if it
currently has no value)
* Setting up version updater to prepare for poison pills and
embedding version info into C++, Python and Java gencode.
* Fix a NPE in putBuilderIfAbsent due to using the result of
put() directly (which is null if it currently has no value)
* Update Kotlin compiler to escape package names
* Add MapFieldBuilder and change codegen to generate it and the
put{field}BuilderIfAbsent method.
* Introduce recursion limit in Java text format parsing
* Consider the protobuf.Any invalid if typeUrl.split("/")
returns an empty array.
* Mark `FieldDescriptor.hasOptionalKeyword()` as deprecated.
* Fixed Python memory leak in map lookup.
* Loosen upb for json name conflict check in proto2 between
json name and field
* Defines Protobuf compiler version strings as macros and
separates out suffix string definition.
* Add `ABSL_ATTRIBUTE_LIFETIME_BOUND` attribute on generated
oneof accessors.
* Ensure Timestamp.ToDatetime(tz) has correct offset
* Do not check required field for upb python MergeFrom
* Setting up version updater to prepare for poison pills and
embedding version info into C++, Python and Java gencode.
* Merge the protobuf and upb Bazel repos
* Comparing a proto message with an object of unknown returns
NotImplemented
* Emit __slots__ in pyi output as a tuple rather than a list
for --pyi_out.
* Fix a bug that strips options from descriptor.proto in
Python.
* Raise warings for message.UnknownFields() usages and navigate
to the new add
* Add protobuf python keyword support in path for stub
generator.
* Add tuple support to set Struct
* ### Python C-Extension (Default)
* Comparing a proto message with an object of unknown returns
NotImplemented
* Check that ffi-compiler loads before using it to define
tasks.
# UPB (Python/PHP/Ruby C-Extension)
* Include .inc files directly instead of through a filegroup
* Loosen upb for json name conflict check in proto2 between
json name and field
* Add utf8_validation feature back to the global feature set.
* Do not check required field for upb python MergeFrom
* Merge the protobuf and upb Bazel repos
* Added malloc_trim() calls to Python allocator so RSS will
decrease when memory is freed
* Upb: fix a Python memory leak in ByteSize()
* Support ASAN detection on clang
* Upb: bugfix for importing a proto3 enum from within a proto2
file
* Expose methods needed by Ruby FFI using UPB_API
* Fix `PyUpb_Message_MergeInternal` segfault
- Add patch to fix StackOverflow vulnerability in Protocol Buffers
* CVE-2024-7254.patch (bsc#1230778, CVE-2024-7254)
-------------------------------------------------------------------
Thu Dec 21 13:53:29 UTC 2023 - Dirk Müller <dmueller@suse.com>

View File

@@ -1,8 +1,7 @@
#
# spec file for package protobuf
#
# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2024 Andreas Stieger <Andreas.Stieger@gmx.de>
# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,108 +16,65 @@
#
%{!?make_build:%global make_build make %{?_smp_mflags}}
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define tarname protobuf
# see cmake/abseil-cpp.cmake and src/google/protobuf/port_def.inc
%define abseil_min_version 20230125.3
%global sover 28_3_0
%if 0%{?gcc_version} < 11
%define with_gcc 11
%endif
%define extra_java_flags -source 8 -target 8
# requires gmock, which is not yet in the distribution
%bcond_with check
%global protoc_arch %{_arch}
%ifarch x86_64 %{?x86_64}
%global protoc_arch x86_64
%endif
%ifarch ppc
%global protoc_arch ppc_32
%endif
%ifarch ppc64
%global protoc_arch ppc_64
%endif
%ifarch ppc64le
%global protoc_arch ppcle_64
%endif
%ifarch %{ix86}
%global protoc_arch x86_32
%endif
%ifarch ia64
%global protoc_arch itanium_64
%endif
%ifarch s390
%global protoc_arch s390_32
%endif
%ifarch s390x
%global protoc_arch s390_64
%endif
%ifarch %{arm}
%global protoc_arch arm_32
%endif
%ifarch aarch64 %{arm64}
%global protoc_arch aarch_64
%endif
# 32 bit sparc, optimized for v9
%ifarch sparcv9
%global protoc_arch sparc_32
%endif
# 64 bit sparc
%ifarch sparc64
%global protoc_arch sparc_64
%endif
%bcond_without java
%bcond_without python3
%{?sle15_python_module_pythons}
Name: protobuf
Version: 28.3
Version: 23.4
%global sover 23_4_0
Release: 0
Summary: Protocol Buffers - Google's data interchange format
License: BSD-3-Clause
Group: Development/Libraries/C and C++
URL: https://github.com/protocolbuffers/protobuf
Source0: https://github.com/protocolbuffers/protobuf/releases/download/v%{version}/%{tarname}-%{version}.tar.gz
Source1: baselibs.conf
Patch1: versionize-shlibs.patch
Source0: https://github.com/protocolbuffers/protobuf/archive/v%{version}.tar.gz#/%{tarname}-%{version}.tar.gz
Source1: manifest.txt.in
Source2: baselibs.conf
Source1000: %{name}-rpmlintrc
Patch0: add-missing-stdint-header.patch
# PATCH-FIX-UPSTREAM - Fix StackOverflow vulnerability in Protocol Buffers (CVE-2024-7254)
Patch1: CVE-2024-7254.patch
# PATCH-FIX-UPSTREAM - Fix use-after-free vulnerability in C++ JSON parser (CVE-2024-2410)
Patch2: CVE-2024-2410.patch
# PATCH-FIX-UPSTREAM - Backport changes from 25.x branch required to apply fix for CVE-2025-4565
Patch3: fix-options-parsing-bug.patch
# PATCH-FIX-UPSTREAM - Fix parsing of untrusted Protocol Buffers data containing an arbitrary
# number of recursive groups or messages can lead to crash due to RecursionError (CVE-2025-4565)
Patch4: CVE-2025-4565.patch
BuildRequires: %{python_module abseil}
BuildRequires: %{python_module devel >= 3.7}
BuildRequires: %{python_module python-dateutil}
BuildRequires: %{python_module setuptools}
BuildRequires: abseil-cpp-devel >= 20230125
BuildRequires: cmake
BuildRequires: fdupes
BuildRequires: gcc%{?with_gcc}-c++
BuildRequires: gcc-c++
BuildRequires: pkgconfig
BuildRequires: python-rpm-macros
# see cmake/abseil-cpp.cmake
BuildRequires: pkgconfig(absl_absl_check) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_absl_log) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_algorithm) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_base) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_bind_front) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_bits) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_btree) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_cleanup) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_cord) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_core_headers) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_debugging) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_die_if_null) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_dynamic_annotations) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_flags) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_flat_hash_map) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_flat_hash_set) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_function_ref) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_hash) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_layout) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_log_initialize) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_log_severity) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_memory) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_node_hash_map) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_node_hash_set) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_optional) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_span) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_status) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_statusor) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_strings) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_synchronization) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_time) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_type_traits) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_utility) >= %{abseil_min_version}
BuildRequires: pkgconfig(absl_variant) >= %{abseil_min_version}
BuildRequires: pkgconfig(zlib)
%if %{with check}
BuildRequires: libgmock-devel >= 1.7.0
%endif
%if %{with java}
BuildRequires: java-devel >= 1.8
BuildRequires: javapackages-local >= 6
%endif
%if 0%{?suse_version} >= 1500
# generate subpackages for every python3 flavor
%define python_subpackage_only 1
%python_subpackages
%else
# same "defaults" for all distributions, used in files section
%define python_files() -n python3-%{**}
%define python_sitelib %{python3_sitelib}
%endif
%description
Protocol Buffers are a way of encoding structured data in an efficient yet
@@ -152,49 +108,94 @@ Protocol Buffers are a way of encoding structured data in an efficient yet
extensible format. Google uses Protocol Buffers for almost all of its internal
RPC protocols and file formats.
%package -n libutf8_range-%{sover}
Summary: UTF-8 validation libraries from Protobuf
Group: System/Libraries
%description -n libutf8_range-%{sover}
UTF-8 string validation library with optional SIMD acceleration (armv8a NEON,
SSE4 and AVX2).
%package devel
Summary: Header files, libraries and development documentation for %{name}
Group: Development/Libraries/C and C++
Requires: libprotobuf%{sover} = %{version}
Requires: libprotobuf-lite%{sover} = %{version}
Requires: libutf8_range-%{sover} = %{version}
Requires: abseil-cpp-devel >= 20230125
Requires: gcc-c++
Requires: libprotobuf%{sover} = %{VERSION}
Requires: libprotobuf-lite%{sover}
Requires: pkgconfig(zlib)
Conflicts: protobuf2-devel
Conflicts: protobuf21-devel
Provides: libprotobuf-devel = %{version}
# Not generated automatically without javapackages-local as dependency
Provides: mvn(com.google.protobuf:protoc:exe:linux-%{protoc_arch}:)
Provides: libprotobuf-devel = %{VERSION}
%description devel
Protocol Buffers are a way of encoding structured data in an efficient yet
extensible format. Google uses Protocol Buffers for almost all of its internal
RPC protocols and file formats.
%prep
%autosetup -p1 -n %{tarname}-%{version}
%if 0%{?python_subpackage_only}
%package -n python-%{name}
Version: 4.%{VERSION}
Summary: Python Bindings for Google Protocol Buffers
Group: Development/Libraries/Python
%description -n python-%{name}
This package contains the Python bindings for Google Protocol Buffers.
%else
%package -n python3-%{name}
Version: 4.%{VERSION}
Summary: Python3 Bindings for Google Protocol Buffers
Group: Development/Libraries/Python
%description -n python3-%{name}
This package contains the Python bindings for Google Protocol Buffers.
%endif
%package -n %{name}-java
Summary: Java Bindings for Google Protocol Buffers
Group: Development/Libraries/Java
Requires: java >= 1.6.0
%description -n %{name}-java
This package contains the Java bindings for Google Protocol Buffers.
%prep
%autosetup -p1 -n %{tarname}-%{VERSION}
# python module have their own version specified in python/google/protobuf/__init__.py
grep -qF "'4.%{VERSION}'" python/google/protobuf/__init__.py
# The previous blank line is crucial for older system being able
# to use the autosetup macro
mkdir gmock
%if %{with python3}
# only needed for test suite which we don't call anyways.
# googleapis is broken on sle12
sed -i '/apputils/d' python/setup.py
sed -i '/google_test_dir/d' python/setup.py
%endif
# kill shebang that we do not really want
sed -i -e '/env python/d' python/google/protobuf/internal/*.py
%build
%global _lto_cflags %{_lto_cflags} -ffat-lto-objects
# tests are not part of offical tar ball
%if 0%{?with_gcc}
export CXX=g++-%{with_gcc}
export CC=gcc-%{with_gcc}
%endif
%cmake \
-Dprotobuf_BUILD_TESTS=OFF \
-Dprotobuf_ABSL_PROVIDER=package
%cmake_build
%if %{with java}
pushd ../java
../build/protoc --java_out=core/src/main/java -I../src ../src/google/protobuf/descriptor.proto
mkdir classes
javac %{extra_java_flags} -d classes core/src/main/java/com/google/protobuf/*.java
sed -e 's/@VERSION@/%{version}/' < %{SOURCE1} > manifest.txt
jar cfm %{name}-java-%{version}.jar manifest.txt -C classes com
popd
%endif
pushd ../python
export PROTOC=../build/protoc
%python_build
popd
%if %{with check}
%check
%make_build check
@@ -203,79 +204,47 @@ export CC=gcc-%{with_gcc}
%install
%cmake_install
install -Dm 0644 editors/proto.vim %{buildroot}%{_datadir}/vim/site/syntax/proto.vim
# manual ln that we could not manage to get into versionize-shlibs.patch
ln -s libutf8_range-%{version}.0.so %{buildroot}/%{_libdir}/libutf8_range.so
ln -s libutf8_validity-%{version}.0.so %{buildroot}/%{_libdir}/libutf8_validity.so
# create maven metadata for the protoc executable
install -dm 0755 %{buildroot}%{_datadir}/maven-metadata
cat <<__PROTOBUF__ >>%{buildroot}%{_datadir}/maven-metadata/%{name}-protoc.xml
<metadata xmlns="http://fedorahosted.org/xmvn/METADATA/2.3.0">
<artifacts>
<artifact>
<groupId>com.google.protobuf</groupId>
<artifactId>protoc</artifactId>
<extension>exe</extension>
<classifier>linux-%{protoc_arch}</classifier>
<version>4.%{version}</version>
<path>%{_bindir}/protoc</path>
</artifact>
</artifacts>
</metadata>
__PROTOBUF__
%if %{with java}
pushd java
install -d -m 0755 %{buildroot}%{_javadir}
install -p -m 0644 %{name}-java-%{version}.jar %{buildroot}%{_javadir}/%{name}-java.jar
ln -s %{name}-java.jar %{buildroot}%{_javadir}/%{name}.jar
install -d -m 0755 %{buildroot}%{_mavenpomdir}
%{mvn_install_pom} core/pom.xml %{buildroot}%{_mavenpomdir}/%{name}-java.pom
%add_maven_depmap %{name}-java.pom %{name}-java.jar
popd
%endif
pushd python
export PROTOC=../build/protoc
%python_install
popd
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%fdupes %{buildroot}%{_prefix}
# SLE12 does not define this macro
%if %{undefined ldconfig_scriptlets}
%post -n libprotobuf%{sover} -p /sbin/ldconfig
%postun -n libprotobuf%{sover} -p /sbin/ldconfig
%post -n libprotoc%{sover} -p /sbin/ldconfig
%postun -n libprotoc%{sover} -p /sbin/ldconfig
%post -n libprotobuf-lite%{sover} -p /sbin/ldconfig
%postun -n libprotobuf-lite%{sover} -p /sbin/ldconfig
%post -n libutf8_range-%{sover} -p /sbin/ldconfig
%postun -n libutf8_range-%{sover} -p /sbin/ldconfig
%else
%ldconfig_scriptlets -n libprotobuf%{sover}
%ldconfig_scriptlets -n libprotoc%{sover}
%ldconfig_scriptlets -n libprotobuf-lite%{sover}
%ldconfig_scriptlets -n libutf8_range-%{sover}
%endif
%files -n libprotobuf%{sover}
%license LICENSE
%{_libdir}/libprotobuf.so.%{version}.0
%{_libdir}/libprotobuf.so.%{VERSION}.0
%files -n libprotoc%{sover}
%license LICENSE
%{_libdir}/libprotoc.so.%{version}.0
%{_libdir}/libprotoc.so.%{VERSION}.0
%files -n libprotobuf-lite%{sover}
%license LICENSE
%{_libdir}/libprotobuf-lite.so.%{version}.0
%files -n libutf8_range-%{sover}
%license LICENSE
%{_libdir}/libutf8_range-%{version}.0.so
%{_libdir}/libutf8_validity-%{version}.0.so
%{_libdir}/libprotobuf-lite.so.%{VERSION}.0
%files devel
%license LICENSE
%doc CONTRIBUTORS.txt README.md
%{_bindir}/protoc*
%{_includedir}/google
%dir %{_includedir}/java
%dir %{_includedir}/java/core
%dir %{_includedir}/java/core/src
%dir %{_includedir}/java/core/src/main
%dir %{_includedir}/java/core/src/main/resources
%dir %{_includedir}/java/core/src/main/resources/
%dir %{_includedir}/java/core/src/main/resources/google
%dir %{_includedir}/java/core/src/main/resources/google/protobuf
%{_includedir}/java/core/src/main/resources/google/protobuf/java_features.proto
%{_includedir}/upb
%{_includedir}/upb_generator
%{_includedir}/*.h
%{_libdir}/cmake/protobuf
%{_libdir}/cmake/utf8_range
@@ -283,10 +252,22 @@ __PROTOBUF__
%{_libdir}/libprotobuf-lite.so
%{_libdir}/libprotobuf.so
%{_libdir}/libprotoc.so
%{_libdir}/libupb.a
%{_libdir}/libutf8_range.so
%{_libdir}/libutf8_validity.so
%{_libdir}/libutf8_range.a
%{_libdir}/libutf8_validity.a
%{_datadir}/vim
%{_datadir}/maven-metadata
%if %{with java}
%files -n %{name}-java -f java/.mfiles
%{_javadir}/%{name}.jar
%endif
%if %{with python3}
%files %{python_files %{name}}
%license LICENSE
%dir %{python_sitelib}/google
%{python_sitelib}/google/protobuf
%{python_sitelib}/protobuf*nspkg.pth
%{python_sitelib}/protobuf*info
%endif
%changelog

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +0,0 @@
#
# spec file for package python-protobuf
#
# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2024 Andreas Stieger <Andreas.Stieger@gmx.de>
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
%define baseversion 28.3
%{?sle15_python_module_pythons}
Name: python-protobuf
Version: 5.%{baseversion}
Release: 0
Summary: Python Bindings for Google Protocol Buffers
License: BSD-3-Clause
Group: Development/Libraries/Python
URL: https://github.com/protocolbuffers/protobuf
Source0: https://files.pythonhosted.org/packages/source/p/protobuf/protobuf-%{version}.tar.gz
BuildRequires: %{python_module devel}
BuildRequires: %{python_module pip}
BuildRequires: %{python_module python-dateutil}
BuildRequires: %{python_module setuptools}
BuildRequires: %{python_module wheel}
BuildRequires: fdupes
%python_subpackages
%description
Protocol Buffers are a way of encoding structured data in an efficient yet
extensible format. Google uses Protocol Buffers for almost all of its internal
RPC protocols and file formats.
This package contains the Python bindings for Google Protocol Buffers.
%prep
%autosetup -p1 -n protobuf-%{version}
# The previous blank line is crucial for older system being able
# to use the autosetup macro
grep -qF "'%{version}'" google/protobuf/__init__.py
# kill shebang that we do not really want
sed -i -e '/env python/d' google/protobuf/internal/*.py
%build
%pyproject_wheel
%install
%pyproject_install
%python_expand %fdupes %{buildroot}%{$python_sitearch}
%fdupes %{buildroot}%{_prefix}
%files %{python_files}
%license LICENSE
%{python_sitearch}/google
%{python_sitearch}/protobuf*nspkg.pth
%{python_sitearch}/protobuf-%{version}.dist-info
%changelog

View File

@@ -1,32 +0,0 @@
From: Jan Engelhardt <jengelh@inai.de>
Date: 2024-10-28 10:10:20.918922623 +0100
References: https://github.com/protocolbuffers/protobuf/pull/19009
Unversioned libraries are strongly discouraged. Use
https://en.opensuse.org/openSUSE:Shared_library_packaging_policy#When_there_is_no_versioning
method 1 to remedy. Though utf8_range has a version of its own ("1.0"
visible through the .pc file) and gets third_party/-like treatment,
protobuf is the authoritative repository for it, using the protobuf
version for our SONAME seems acceptable.
This openSUSE patch follows SLPP's naming provisions and so is
slightly different from PR19009 while the PR is unmerged.
---
third_party/utf8_range/CMakeLists.txt | 8 ++++++++
1 file changed, 8 insertions(+)
Index: protobuf-28.3/third_party/utf8_range/CMakeLists.txt
===================================================================
--- protobuf-28.3.orig/third_party/utf8_range/CMakeLists.txt
+++ protobuf-28.3/third_party/utf8_range/CMakeLists.txt
@@ -19,6 +19,9 @@ add_library (utf8_range
# A heavier-weight C++ wrapper that supports Abseil.
add_library (utf8_validity utf8_validity.cc utf8_range.c)
+set_target_properties(utf8_range PROPERTIES OUTPUT_NAME ${LIB_PREFIX}utf8_range-${protobuf_VERSION})
+set_target_properties(utf8_validity PROPERTIES OUTPUT_NAME ${LIB_PREFIX}utf8_validity-${protobuf_VERSION})
+
# Load Abseil dependency.
if (NOT TARGET absl::strings)
if (NOT ABSL_ROOT_DIR)