diff --git a/0001-add-secure-compile-option-in-Makefile.patch b/0001-add-secure-compile-option-in-Makefile.patch deleted file mode 100644 index 988ba4334d481993d49a6dbce0eb2beabea2317d..0000000000000000000000000000000000000000 --- a/0001-add-secure-compile-option-in-Makefile.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/src/Makefile.am b/src/Makefile.am -index f1099d9..9b7053b 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -19,6 +19,7 @@ PTHREAD_DEF = - endif - - PROTOBUF_VERSION = 25:0:0 -+PROTOBUF_OPT_FLAG += -Wl,-z,now - - if GCC - # Turn on all warnings except for sign comparison (we ignore sign comparison diff --git a/0002-add-secure-compile-fs-check-in-Makefile.patch b/0002-add-secure-compile-fs-check-in-Makefile.patch deleted file mode 100644 index 9a5ff529883142f31d3f38c4e7c3c5214b7866eb..0000000000000000000000000000000000000000 --- a/0002-add-secure-compile-fs-check-in-Makefile.patch +++ /dev/null @@ -1,26 +0,0 @@ -From dddceb14106499f9fca17e75cdce458a205b102c Mon Sep 17 00:00:00 2001 -From: haozi007 -Date: Sat, 20 Feb 2021 16:52:15 +0800 -Subject: [PATCH] add secure compile fs check in Makefile - -Signed-off-by: haozi007 ---- - src/Makefile.am | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/Makefile.am b/src/Makefile.am -index 9b7053b..e447b05 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -19,7 +19,7 @@ PTHREAD_DEF = - endif - - PROTOBUF_VERSION = 25:0:0 --PROTOBUF_OPT_FLAG += -Wl,-z,now -+PROTOBUF_OPT_FLAG += -Wl,-z,now -fstack-check - - if GCC - # Turn on all warnings except for sign comparison (we ignore sign comparison --- -2.25.1 - diff --git a/0003-fix-CVE-2021-22570.patch b/0003-fix-CVE-2021-22570.patch deleted file mode 100644 index fa6fb403ccfbb0154bb52f73de3df61526ad0d6c..0000000000000000000000000000000000000000 --- a/0003-fix-CVE-2021-22570.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 5afdc4d13ac997204873e734b20c30b6efc253d1 Mon Sep 17 00:00:00 2001 -From: wangxiaochao -Date: Fri, 18 Mar 2022 14:46:35 +0800 -Subject: [PATCH] fix CVE-2021-22570 - -Signed-off-by: wangxiaochao - ---- - src/google/protobuf/descriptor.cc | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc -index 8998e1b..e6f7ec2 100644 ---- a/src/google/protobuf/descriptor.cc -+++ b/src/google/protobuf/descriptor.cc -@@ -2626,6 +2626,8 @@ void Descriptor::DebugString(int depth, std::string* contents, - const Descriptor::ReservedRange* range = reserved_range(i); - if (range->end == range->start + 1) { - strings::SubstituteAndAppend(contents, "$0, ", range->start); -+ } else if (range->end > FieldDescriptor::kMaxNumber) { -+ strings::SubstituteAndAppend(contents, "$0 to max, ", range->start); - } else { - strings::SubstituteAndAppend(contents, "$0 to $1, ", range->start, - range->end - 1); -@@ -2829,6 +2831,8 @@ void EnumDescriptor::DebugString( - const EnumDescriptor::ReservedRange* range = reserved_range(i); - if (range->end == range->start) { - strings::SubstituteAndAppend(contents, "$0, ", range->start); -+ } else if (range->end == INT_MAX) { -+ strings::SubstituteAndAppend(contents, "$0 to max, ", range->start); - } else { - strings::SubstituteAndAppend(contents, "$0 to $1, ", range->start, - range->end); -@@ -4019,6 +4023,11 @@ bool DescriptorBuilder::AddSymbol(const std::string& full_name, - // Use its file as the parent instead. - if (parent == nullptr) parent = file_; - -+ if (full_name.find('\0') != std::string::npos) { -+ AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, -+ "\"" + full_name + "\" contains null character."); -+ return false; -+ } - if (tables_->AddSymbol(full_name, symbol)) { - if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) { - // This is only possible if there was already an error adding something of -@@ -4059,6 +4068,11 @@ bool DescriptorBuilder::AddSymbol(const std::string& full_name, - void DescriptorBuilder::AddPackage(const std::string& name, - const Message& proto, - const FileDescriptor* file) { -+ if (name.find('\0') != std::string::npos) { -+ AddError(name, proto, DescriptorPool::ErrorCollector::NAME, -+ "\"" + name + "\" contains null character."); -+ return; -+ } - if (tables_->AddSymbol(name, Symbol(file))) { - // Success. Also add parent package, if any. - std::string::size_type dot_pos = name.find_last_of('.'); -@@ -4372,6 +4386,12 @@ FileDescriptor* DescriptorBuilder::BuildFileImpl( - } - result->pool_ = pool_; - -+ if (result->name().find('\0') != std::string::npos) { -+ AddError(result->name(), proto, DescriptorPool::ErrorCollector::NAME, -+ "\"" + result->name() + "\" contains null character."); -+ return nullptr; -+ } -+ - // Add to tables. - if (!tables_->AddFile(result)) { - AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, --- -2.25.1 - diff --git a/0004-Improve-performance-of-parsing-unknown-fields-in-Jav.patch b/0004-Improve-performance-of-parsing-unknown-fields-in-Jav.patch deleted file mode 100644 index a56f88d9a402fa1d9ee2bd5e7c370aaa9d05b2ad..0000000000000000000000000000000000000000 --- a/0004-Improve-performance-of-parsing-unknown-fields-in-Jav.patch +++ /dev/null @@ -1,1272 +0,0 @@ -From 8890b0a81e2f4b1de4a33cc6d81aba07655bde1a Mon Sep 17 00:00:00 2001 -From: wangxiaochao -Date: Thu, 24 Mar 2022 20:54:36 +0800 -Subject: [PATCH] Improve performance of parsing unknown fields in Java - -Signed-off-by: wangxiaochao - ---- - Makefile.am | 1 + - .../com/google/protobuf/UnknownFieldSet.java | 427 +++++++++--------- - .../UnknownFieldSetPerformanceTest.java | 78 ++++ - .../google/protobuf/UnknownFieldSetTest.java | 171 ++++++- - java/lite/pom.xml | 3 +- - 5 files changed, 466 insertions(+), 214 deletions(-) - create mode 100644 java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java - -diff --git a/Makefile.am b/Makefile.am -index 4fc706b..908c2d2 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -487,6 +487,7 @@ java_EXTRA_DIST= - java/core/src/test/java/com/google/protobuf/TypeRegistryTest.java \ - java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java \ - java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java \ -+ java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java \ - java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \ - java/core/src/test/java/com/google/protobuf/Utf8Test.java \ - java/core/src/test/java/com/google/protobuf/Utf8Utils.java \ -diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java -index ba2f9df..5c482d6 100644 ---- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java -+++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java -@@ -43,13 +43,13 @@ import java.util.Map; - import java.util.TreeMap; - - /** -- * {@code UnknownFieldSet} is used to keep track of fields which were seen when parsing a protocol -+ * {@code UnknownFieldSet} keeps track of fields which were seen when parsing a protocol - * message but whose field numbers or types are unrecognized. This most frequently occurs when new - * fields are added to a message type and then messages containing those fields are read by old - * software that was compiled before the new types were added. - * - *

Every {@link Message} contains an {@code UnknownFieldSet} (and every {@link Message.Builder} -- * contains an {@link Builder}). -+ * contains a {@link Builder}). - * - *

Most users will never need to use this class. - * -@@ -57,9 +57,13 @@ import java.util.TreeMap; - */ - public final class UnknownFieldSet implements MessageLite { - -- private UnknownFieldSet() { -- fields = null; -- fieldsDescending = null; -+ private final TreeMap fields; -+ -+ /** -+ * Construct an {@code UnknownFieldSet} around the given map. -+ */ -+ UnknownFieldSet(TreeMap fields) { -+ this.fields = fields; - } - - /** Create a new {@link Builder}. */ -@@ -68,7 +72,7 @@ public final class UnknownFieldSet implements MessageLite { - } - - /** Create a new {@link Builder} and initialize it to be a copy of {@code copyFrom}. */ -- public static Builder newBuilder(final UnknownFieldSet copyFrom) { -+ public static Builder newBuilder(UnknownFieldSet copyFrom) { - return newBuilder().mergeFrom(copyFrom); - } - -@@ -83,25 +87,11 @@ public final class UnknownFieldSet implements MessageLite { - } - - private static final UnknownFieldSet defaultInstance = -- new UnknownFieldSet( -- Collections.emptyMap(), Collections.emptyMap()); -- -- /** -- * Construct an {@code UnknownFieldSet} around the given map. The map is expected to be immutable. -- */ -- UnknownFieldSet(final Map fields, final Map fieldsDescending) { -- this.fields = fields; -- this.fieldsDescending = fieldsDescending; -- } -- -- private final Map fields; -- -- /** A copy of {@link #fields} who's iterator order is reversed. */ -- private final Map fieldsDescending; -+ new UnknownFieldSet(new TreeMap()); - - - @Override -- public boolean equals(final Object other) { -+ public boolean equals(Object other) { - if (this == other) { - return true; - } -@@ -110,29 +100,33 @@ public final class UnknownFieldSet implements MessageLite { - - @Override - public int hashCode() { -+ if (fields.isEmpty()) { // avoid allocation of iterator. -+ // This optimization may not be helpful but it is needed for the allocation tests to pass. -+ return 0; -+ } - return fields.hashCode(); - } - - /** Get a map of fields in the set by number. */ - public Map asMap() { -- return fields; -+ return (Map) fields.clone(); - } - - /** Check if the given field number is present in the set. */ -- public boolean hasField(final int number) { -+ public boolean hasField(int number) { - return fields.containsKey(number); - } - - /** Get a field by number. Returns an empty field if not present. Never returns {@code null}. */ -- public Field getField(final int number) { -- final Field result = fields.get(number); -+ public Field getField(int number) { -+ Field result = fields.get(number); - return (result == null) ? Field.getDefaultInstance() : result; - } - - /** Serializes the set and writes it to {@code output}. */ - @Override -- public void writeTo(final CodedOutputStream output) throws IOException { -- for (final Map.Entry entry : fields.entrySet()) { -+ public void writeTo(CodedOutputStream output) throws IOException { -+ for (Map.Entry entry : fields.entrySet()) { - Field field = entry.getValue(); - field.writeTo(entry.getKey(), output); - } -@@ -154,10 +148,10 @@ public final class UnknownFieldSet implements MessageLite { - @Override - public ByteString toByteString() { - try { -- final ByteString.CodedBuilder out = ByteString.newCodedBuilder(getSerializedSize()); -+ ByteString.CodedBuilder out = ByteString.newCodedBuilder(getSerializedSize()); - writeTo(out.getCodedOutput()); - return out.build(); -- } catch (final IOException e) { -+ } catch (IOException e) { - throw new RuntimeException( - "Serializing to a ByteString threw an IOException (should never happen).", e); - } -@@ -170,12 +164,12 @@ public final class UnknownFieldSet implements MessageLite { - @Override - public byte[] toByteArray() { - try { -- final byte[] result = new byte[getSerializedSize()]; -- final CodedOutputStream output = CodedOutputStream.newInstance(result); -+ byte[] result = new byte[getSerializedSize()]; -+ CodedOutputStream output = CodedOutputStream.newInstance(result); - writeTo(output); - output.checkNoSpaceLeft(); - return result; -- } catch (final IOException e) { -+ } catch (IOException e) { - throw new RuntimeException( - "Serializing to a byte array threw an IOException (should never happen).", e); - } -@@ -186,16 +180,16 @@ public final class UnknownFieldSet implements MessageLite { - * {@link #writeTo(CodedOutputStream)}. - */ - @Override -- public void writeTo(final OutputStream output) throws IOException { -- final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); -+ public void writeTo(OutputStream output) throws IOException { -+ CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); - writeTo(codedOutput); - codedOutput.flush(); - } - - @Override - public void writeDelimitedTo(OutputStream output) throws IOException { -- final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); -- codedOutput.writeRawVarint32(getSerializedSize()); -+ CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); -+ codedOutput.writeUInt32NoTag(getSerializedSize()); - writeTo(codedOutput); - codedOutput.flush(); - } -@@ -204,15 +198,17 @@ public final class UnknownFieldSet implements MessageLite { - @Override - public int getSerializedSize() { - int result = 0; -- for (final Map.Entry entry : fields.entrySet()) { -- result += entry.getValue().getSerializedSize(entry.getKey()); -+ if (!fields.isEmpty()) { -+ for (Map.Entry entry : fields.entrySet()) { -+ result += entry.getValue().getSerializedSize(entry.getKey()); -+ } - } - return result; - } - - /** Serializes the set and writes it to {@code output} using {@code MessageSet} wire format. */ -- public void writeAsMessageSetTo(final CodedOutputStream output) throws IOException { -- for (final Map.Entry entry : fields.entrySet()) { -+ public void writeAsMessageSetTo(CodedOutputStream output) throws IOException { -+ for (Map.Entry entry : fields.entrySet()) { - entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), output); - } - } -@@ -221,7 +217,7 @@ public final class UnknownFieldSet implements MessageLite { - void writeTo(Writer writer) throws IOException { - if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) { - // Write fields in descending order. -- for (Map.Entry entry : fieldsDescending.entrySet()) { -+ for (Map.Entry entry : fields.descendingMap().entrySet()) { - entry.getValue().writeTo(entry.getKey(), writer); - } - } else { -@@ -233,15 +229,15 @@ public final class UnknownFieldSet implements MessageLite { - } - - /** Serializes the set and writes it to {@code writer} using {@code MessageSet} wire format. */ -- void writeAsMessageSetTo(final Writer writer) throws IOException { -+ void writeAsMessageSetTo(Writer writer) throws IOException { - if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) { - // Write fields in descending order. -- for (final Map.Entry entry : fieldsDescending.entrySet()) { -+ for (Map.Entry entry : fields.descendingMap().entrySet()) { - entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), writer); - } - } else { - // Write fields in ascending order. -- for (final Map.Entry entry : fields.entrySet()) { -+ for (Map.Entry entry : fields.entrySet()) { - entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), writer); - } - } -@@ -250,7 +246,7 @@ public final class UnknownFieldSet implements MessageLite { - /** Get the number of bytes required to encode this set using {@code MessageSet} wire format. */ - public int getSerializedSizeAsMessageSet() { - int result = 0; -- for (final Map.Entry entry : fields.entrySet()) { -+ for (Map.Entry entry : fields.entrySet()) { - result += entry.getValue().getSerializedSizeAsMessageSetExtension(entry.getKey()); - } - return result; -@@ -264,23 +260,23 @@ public final class UnknownFieldSet implements MessageLite { - } - - /** Parse an {@code UnknownFieldSet} from the given input stream. */ -- public static UnknownFieldSet parseFrom(final CodedInputStream input) throws IOException { -+ public static UnknownFieldSet parseFrom(CodedInputStream input) throws IOException { - return newBuilder().mergeFrom(input).build(); - } - - /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */ -- public static UnknownFieldSet parseFrom(final ByteString data) -+ public static UnknownFieldSet parseFrom(ByteString data) - throws InvalidProtocolBufferException { - return newBuilder().mergeFrom(data).build(); - } - - /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */ -- public static UnknownFieldSet parseFrom(final byte[] data) throws InvalidProtocolBufferException { -+ public static UnknownFieldSet parseFrom(byte[] data) throws InvalidProtocolBufferException { - return newBuilder().mergeFrom(data).build(); - } - - /** Parse an {@code UnknownFieldSet} from {@code input} and return it. */ -- public static UnknownFieldSet parseFrom(final InputStream input) throws IOException { -+ public static UnknownFieldSet parseFrom(InputStream input) throws IOException { - return newBuilder().mergeFrom(input).build(); - } - -@@ -309,64 +305,43 @@ public final class UnknownFieldSet implements MessageLite { - // This constructor should never be called directly (except from 'create'). - private Builder() {} - -- private Map fields; -- -- // Optimization: We keep around a builder for the last field that was -- // modified so that we can efficiently add to it multiple times in a -- // row (important when parsing an unknown repeated field). -- private int lastFieldNumber; -- private Field.Builder lastField; -+ private TreeMap fieldBuilders = new TreeMap<>(); - - private static Builder create() { -- Builder builder = new Builder(); -- builder.reinitialize(); -- return builder; -+ return new Builder(); - } - - /** - * Get a field builder for the given field number which includes any values that already exist. - */ -- private Field.Builder getFieldBuilder(final int number) { -- if (lastField != null) { -- if (number == lastFieldNumber) { -- return lastField; -- } -- // Note: addField() will reset lastField and lastFieldNumber. -- addField(lastFieldNumber, lastField.build()); -- } -+ private Field.Builder getFieldBuilder(int number) { - if (number == 0) { - return null; - } else { -- final Field existing = fields.get(number); -- lastFieldNumber = number; -- lastField = Field.newBuilder(); -- if (existing != null) { -- lastField.mergeFrom(existing); -+ Field.Builder builder = fieldBuilders.get(number); -+ if (builder == null) { -+ builder = Field.newBuilder(); -+ fieldBuilders.put(number, builder); - } -- return lastField; -+ return builder; - } - } - - /** - * Build the {@link UnknownFieldSet} and return it. -- * -- *

Once {@code build()} has been called, the {@code Builder} will no longer be usable. -- * Calling any method after {@code build()} will result in undefined behavior and can cause a -- * {@code NullPointerException} to be thrown. - */ - @Override - public UnknownFieldSet build() { -- getFieldBuilder(0); // Force lastField to be built. -- final UnknownFieldSet result; -- if (fields.isEmpty()) { -+ UnknownFieldSet result; -+ if (fieldBuilders.isEmpty()) { - result = getDefaultInstance(); - } else { -- Map descendingFields = null; -- descendingFields = -- Collections.unmodifiableMap(((TreeMap) fields).descendingMap()); -- result = new UnknownFieldSet(Collections.unmodifiableMap(fields), descendingFields); -+ TreeMap fields = new TreeMap<>(); -+ for (Map.Entry entry : fieldBuilders.entrySet()) { -+ fields.put(entry.getKey(), entry.getValue().build()); -+ } -+ result = new UnknownFieldSet(fields); - } -- fields = null; - return result; - } - -@@ -378,11 +353,13 @@ public final class UnknownFieldSet implements MessageLite { - - @Override - public Builder clone() { -- getFieldBuilder(0); // Force lastField to be built. -- Map descendingFields = null; -- descendingFields = -- Collections.unmodifiableMap(((TreeMap) fields).descendingMap()); -- return UnknownFieldSet.newBuilder().mergeFrom(new UnknownFieldSet(fields, descendingFields)); -+ Builder clone = UnknownFieldSet.newBuilder(); -+ for (Map.Entry entry : fieldBuilders.entrySet()) { -+ Integer key = entry.getKey(); -+ Field.Builder value = entry.getValue(); -+ clone.fieldBuilders.put(key, value.clone()); -+ } -+ return clone; - } - - @Override -@@ -390,31 +367,24 @@ public final class UnknownFieldSet implements MessageLite { - return UnknownFieldSet.getDefaultInstance(); - } - -- private void reinitialize() { -- fields = Collections.emptyMap(); -- lastFieldNumber = 0; -- lastField = null; -- } -- - /** Reset the builder to an empty set. */ - @Override - public Builder clear() { -- reinitialize(); -+ fieldBuilders = new TreeMap<>(); - return this; - } - -- /** Clear fields from the set with a given field number. */ -- public Builder clearField(final int number) { -- if (number == 0) { -- throw new IllegalArgumentException("Zero is not a valid field number."); -- } -- if (lastField != null && lastFieldNumber == number) { -- // Discard this. -- lastField = null; -- lastFieldNumber = 0; -+ /** -+ * Clear fields from the set with a given field number. -+ * -+ * @throws IllegalArgumentException if number is not positive -+ */ -+ public Builder clearField(int number) { -+ if (number <= 0) { -+ throw new IllegalArgumentException(number + " is not a valid field number."); - } -- if (fields.containsKey(number)) { -- fields.remove(number); -+ if (fieldBuilders.containsKey(number)) { -+ fieldBuilders.remove(number); - } - return this; - } -@@ -423,9 +393,9 @@ public final class UnknownFieldSet implements MessageLite { - * Merge the fields from {@code other} into this set. If a field number exists in both sets, - * {@code other}'s values for that field will be appended to the values in this set. - */ -- public Builder mergeFrom(final UnknownFieldSet other) { -+ public Builder mergeFrom(UnknownFieldSet other) { - if (other != getDefaultInstance()) { -- for (final Map.Entry entry : other.fields.entrySet()) { -+ for (Map.Entry entry : other.fields.entrySet()) { - mergeField(entry.getKey(), entry.getValue()); - } - } -@@ -435,10 +405,12 @@ public final class UnknownFieldSet implements MessageLite { - /** - * Add a field to the {@code UnknownFieldSet}. If a field with the same number already exists, - * the two are merged. -+ * -+ * @throws IllegalArgumentException if number is not positive - */ -- public Builder mergeField(final int number, final Field field) { -- if (number == 0) { -- throw new IllegalArgumentException("Zero is not a valid field number."); -+ public Builder mergeField(int number, final Field field) { -+ if (number <= 0) { -+ throw new IllegalArgumentException(number + " is not a valid field number."); - } - if (hasField(number)) { - getFieldBuilder(number).mergeFrom(field); -@@ -454,10 +426,12 @@ public final class UnknownFieldSet implements MessageLite { - /** - * Convenience method for merging a new field containing a single varint value. This is used in - * particular when an unknown enum value is encountered. -+ * -+ * @throws IllegalArgumentException if number is not positive - */ -- public Builder mergeVarintField(final int number, final int value) { -- if (number == 0) { -- throw new IllegalArgumentException("Zero is not a valid field number."); -+ public Builder mergeVarintField(int number, int value) { -+ if (number <= 0) { -+ throw new IllegalArgumentException(number + " is not a valid field number."); - } - getFieldBuilder(number).addVarint(value); - return this; -@@ -467,40 +441,33 @@ public final class UnknownFieldSet implements MessageLite { - * Convenience method for merging a length-delimited field. - * - *

For use by generated code only. -+ * -+ * @throws IllegalArgumentException if number is not positive - */ -- public Builder mergeLengthDelimitedField(final int number, final ByteString value) { -- if (number == 0) { -- throw new IllegalArgumentException("Zero is not a valid field number."); -+ public Builder mergeLengthDelimitedField(int number, ByteString value) { -+ if (number <= 0) { -+ throw new IllegalArgumentException(number + " is not a valid field number."); - } - getFieldBuilder(number).addLengthDelimited(value); - return this; - } - - /** Check if the given field number is present in the set. */ -- public boolean hasField(final int number) { -- if (number == 0) { -- throw new IllegalArgumentException("Zero is not a valid field number."); -- } -- return number == lastFieldNumber || fields.containsKey(number); -+ public boolean hasField(int number) { -+ return fieldBuilders.containsKey(number); - } - - /** - * Add a field to the {@code UnknownFieldSet}. If a field with the same number already exists, - * it is removed. -+ * -+ * @throws IllegalArgumentException if number is not positive - */ -- public Builder addField(final int number, final Field field) { -- if (number == 0) { -- throw new IllegalArgumentException("Zero is not a valid field number."); -- } -- if (lastField != null && lastFieldNumber == number) { -- // Discard this. -- lastField = null; -- lastFieldNumber = 0; -+ public Builder addField(int number, Field field) { -+ if (number <= 0) { -+ throw new IllegalArgumentException(number + " is not a valid field number."); - } -- if (fields.isEmpty()) { -- fields = new TreeMap(); -- } -- fields.put(number, field); -+ fieldBuilders.put(number, Field.newBuilder(field)); - return this; - } - -@@ -509,15 +476,18 @@ public final class UnknownFieldSet implements MessageLite { - * changes may or may not be reflected in this map. - */ - public Map asMap() { -- getFieldBuilder(0); // Force lastField to be built. -+ TreeMap fields = new TreeMap<>(); -+ for (Map.Entry entry : fieldBuilders.entrySet()) { -+ fields.put(entry.getKey(), entry.getValue().build()); -+ } - return Collections.unmodifiableMap(fields); - } - - /** Parse an entire message from {@code input} and merge its fields into this set. */ - @Override -- public Builder mergeFrom(final CodedInputStream input) throws IOException { -+ public Builder mergeFrom(CodedInputStream input) throws IOException { - while (true) { -- final int tag = input.readTag(); -+ int tag = input.readTag(); - if (tag == 0 || !mergeFieldFrom(tag, input)) { - break; - } -@@ -531,8 +501,8 @@ public final class UnknownFieldSet implements MessageLite { - * @param tag The field's tag number, which was already parsed. - * @return {@code false} if the tag is an end group tag. - */ -- public boolean mergeFieldFrom(final int tag, final CodedInputStream input) throws IOException { -- final int number = WireFormat.getTagFieldNumber(tag); -+ public boolean mergeFieldFrom(int tag, CodedInputStream input) throws IOException { -+ int number = WireFormat.getTagFieldNumber(tag); - switch (WireFormat.getTagWireType(tag)) { - case WireFormat.WIRETYPE_VARINT: - getFieldBuilder(number).addVarint(input.readInt64()); -@@ -544,7 +514,7 @@ public final class UnknownFieldSet implements MessageLite { - getFieldBuilder(number).addLengthDelimited(input.readBytes()); - return true; - case WireFormat.WIRETYPE_START_GROUP: -- final Builder subBuilder = newBuilder(); -+ Builder subBuilder = newBuilder(); - input.readGroup(number, subBuilder, ExtensionRegistry.getEmptyRegistry()); - getFieldBuilder(number).addGroup(subBuilder.build()); - return true; -@@ -563,15 +533,15 @@ public final class UnknownFieldSet implements MessageLite { - * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}. - */ - @Override -- public Builder mergeFrom(final ByteString data) throws InvalidProtocolBufferException { -+ public Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException { - try { -- final CodedInputStream input = data.newCodedInput(); -+ CodedInputStream input = data.newCodedInput(); - mergeFrom(input); - input.checkLastTagWas(0); - return this; -- } catch (final InvalidProtocolBufferException e) { -+ } catch (InvalidProtocolBufferException e) { - throw e; -- } catch (final IOException e) { -+ } catch (IOException e) { - throw new RuntimeException( - "Reading from a ByteString threw an IOException (should never happen).", e); - } -@@ -582,15 +552,15 @@ public final class UnknownFieldSet implements MessageLite { - * is just a small wrapper around {@link #mergeFrom(CodedInputStream)}. - */ - @Override -- public Builder mergeFrom(final byte[] data) throws InvalidProtocolBufferException { -+ public Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException { - try { -- final CodedInputStream input = CodedInputStream.newInstance(data); -+ CodedInputStream input = CodedInputStream.newInstance(data); - mergeFrom(input); - input.checkLastTagWas(0); - return this; -- } catch (final InvalidProtocolBufferException e) { -+ } catch (InvalidProtocolBufferException e) { - throw e; -- } catch (final IOException e) { -+ } catch (IOException e) { - throw new RuntimeException( - "Reading from a byte array threw an IOException (should never happen).", e); - } -@@ -601,8 +571,8 @@ public final class UnknownFieldSet implements MessageLite { - * This is just a small wrapper around {@link #mergeFrom(CodedInputStream)}. - */ - @Override -- public Builder mergeFrom(final InputStream input) throws IOException { -- final CodedInputStream codedInput = CodedInputStream.newInstance(input); -+ public Builder mergeFrom(InputStream input) throws IOException { -+ CodedInputStream codedInput = CodedInputStream.newInstance(input); - mergeFrom(codedInput); - codedInput.checkLastTagWas(0); - return this; -@@ -610,12 +580,12 @@ public final class UnknownFieldSet implements MessageLite { - - @Override - public boolean mergeDelimitedFrom(InputStream input) throws IOException { -- final int firstByte = input.read(); -+ int firstByte = input.read(); - if (firstByte == -1) { - return false; - } -- final int size = CodedInputStream.readRawVarint32(firstByte, input); -- final InputStream limitedInput = new LimitedInputStream(input, size); -+ int size = CodedInputStream.readRawVarint32(firstByte, input); -+ InputStream limitedInput = new LimitedInputStream(input, size); - mergeFrom(limitedInput); - return true; - } -@@ -644,7 +614,7 @@ public final class UnknownFieldSet implements MessageLite { - @Override - public Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException { - try { -- final CodedInputStream input = CodedInputStream.newInstance(data, off, len); -+ CodedInputStream input = CodedInputStream.newInstance(data, off, len); - mergeFrom(input); - input.checkLastTagWas(0); - return this; -@@ -718,7 +688,7 @@ public final class UnknownFieldSet implements MessageLite { - } - - /** Construct a new {@link Builder} and initialize it to a copy of {@code copyFrom}. */ -- public static Builder newBuilder(final Field copyFrom) { -+ public static Builder newBuilder(Field copyFrom) { - return newBuilder().mergeFrom(copyFrom); - } - -@@ -758,7 +728,7 @@ public final class UnknownFieldSet implements MessageLite { - } - - @Override -- public boolean equals(final Object other) { -+ public boolean equals(Object other) { - if (this == other) { - return true; - } -@@ -785,7 +755,7 @@ public final class UnknownFieldSet implements MessageLite { - public ByteString toByteString(int fieldNumber) { - try { - // TODO(lukes): consider caching serialized size in a volatile long -- final ByteString.CodedBuilder out = -+ ByteString.CodedBuilder out = - ByteString.newCodedBuilder(getSerializedSize(fieldNumber)); - writeTo(fieldNumber, out.getCodedOutput()); - return out.build(); -@@ -796,40 +766,40 @@ public final class UnknownFieldSet implements MessageLite { - } - - /** Serializes the field, including field number, and writes it to {@code output}. */ -- public void writeTo(final int fieldNumber, final CodedOutputStream output) throws IOException { -- for (final long value : varint) { -+ public void writeTo(int fieldNumber, CodedOutputStream output) throws IOException { -+ for (long value : varint) { - output.writeUInt64(fieldNumber, value); - } -- for (final int value : fixed32) { -+ for (int value : fixed32) { - output.writeFixed32(fieldNumber, value); - } -- for (final long value : fixed64) { -+ for (long value : fixed64) { - output.writeFixed64(fieldNumber, value); - } -- for (final ByteString value : lengthDelimited) { -+ for (ByteString value : lengthDelimited) { - output.writeBytes(fieldNumber, value); - } -- for (final UnknownFieldSet value : group) { -+ for (UnknownFieldSet value : group) { - output.writeGroup(fieldNumber, value); - } - } - - /** Get the number of bytes required to encode this field, including field number. */ -- public int getSerializedSize(final int fieldNumber) { -+ public int getSerializedSize(int fieldNumber) { - int result = 0; -- for (final long value : varint) { -+ for (long value : varint) { - result += CodedOutputStream.computeUInt64Size(fieldNumber, value); - } -- for (final int value : fixed32) { -+ for (int value : fixed32) { - result += CodedOutputStream.computeFixed32Size(fieldNumber, value); - } -- for (final long value : fixed64) { -+ for (long value : fixed64) { - result += CodedOutputStream.computeFixed64Size(fieldNumber, value); - } -- for (final ByteString value : lengthDelimited) { -+ for (ByteString value : lengthDelimited) { - result += CodedOutputStream.computeBytesSize(fieldNumber, value); - } -- for (final UnknownFieldSet value : group) { -+ for (UnknownFieldSet value : group) { - result += CodedOutputStream.computeGroupSize(fieldNumber, value); - } - return result; -@@ -839,15 +809,15 @@ public final class UnknownFieldSet implements MessageLite { - * Serializes the field, including field number, and writes it to {@code output}, using {@code - * MessageSet} wire format. - */ -- public void writeAsMessageSetExtensionTo(final int fieldNumber, final CodedOutputStream output) -+ public void writeAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output) - throws IOException { -- for (final ByteString value : lengthDelimited) { -+ for (ByteString value : lengthDelimited) { - output.writeRawMessageSetExtension(fieldNumber, value); - } - } - - /** Serializes the field, including field number, and writes it to {@code writer}. */ -- void writeTo(final int fieldNumber, final Writer writer) throws IOException { -+ void writeTo(int fieldNumber, Writer writer) throws IOException { - writer.writeInt64List(fieldNumber, varint, false); - writer.writeFixed32List(fieldNumber, fixed32, false); - writer.writeFixed64List(fieldNumber, fixed64, false); -@@ -872,7 +842,7 @@ public final class UnknownFieldSet implements MessageLite { - * Serializes the field, including field number, and writes it to {@code writer}, using {@code - * MessageSet} wire format. - */ -- private void writeAsMessageSetExtensionTo(final int fieldNumber, final Writer writer) -+ private void writeAsMessageSetExtensionTo(int fieldNumber, Writer writer) - throws IOException { - if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) { - // Write in descending field order. -@@ -882,7 +852,7 @@ public final class UnknownFieldSet implements MessageLite { - } - } else { - // Write in ascending field order. -- for (final ByteString value : lengthDelimited) { -+ for (ByteString value : lengthDelimited) { - writer.writeMessageSetItem(fieldNumber, value); - } - } -@@ -892,9 +862,9 @@ public final class UnknownFieldSet implements MessageLite { - * Get the number of bytes required to encode this field, including field number, using {@code - * MessageSet} wire format. - */ -- public int getSerializedSizeAsMessageSetExtension(final int fieldNumber) { -+ public int getSerializedSizeAsMessageSetExtension(int fieldNumber) { - int result = 0; -- for (final ByteString value : lengthDelimited) { -+ for (ByteString value : lengthDelimited) { - result += CodedOutputStream.computeRawMessageSetExtensionSize(fieldNumber, value); - } - return result; -@@ -912,52 +882,85 @@ public final class UnknownFieldSet implements MessageLite { - *

Use {@link Field#newBuilder()} to construct a {@code Builder}. - */ - public static final class Builder { -- // This constructor should never be called directly (except from 'create'). -- private Builder() {} -+ // This constructor should only be called directly from 'create' and 'clone'. -+ private Builder() { -+ result = new Field(); -+ } - - private static Builder create() { - Builder builder = new Builder(); -- builder.result = new Field(); - return builder; - } - - private Field result; - -+ @Override -+ public Builder clone() { -+ Field copy = new Field(); -+ if (result.varint == null) { -+ copy.varint = null; -+ } else { -+ copy.varint = new ArrayList<>(result.varint); -+ } -+ if (result.fixed32 == null) { -+ copy.fixed32 = null; -+ } else { -+ copy.fixed32 = new ArrayList<>(result.fixed32); -+ } -+ if (result.fixed64 == null) { -+ copy.fixed64 = null; -+ } else { -+ copy.fixed64 = new ArrayList<>(result.fixed64); -+ } -+ if (result.lengthDelimited == null) { -+ copy.lengthDelimited = null; -+ } else { -+ copy.lengthDelimited = new ArrayList<>(result.lengthDelimited); -+ } -+ if (result.group == null) { -+ copy.group = null; -+ } else { -+ copy.group = new ArrayList<>(result.group); -+ } -+ -+ Builder clone = new Builder(); -+ clone.result = copy; -+ return clone; -+ } -+ - /** -- * Build the field. After {@code build()} has been called, the {@code Builder} is no longer -- * usable. Calling any other method will result in undefined behavior and can cause a {@code -- * NullPointerException} to be thrown. -+ * Build the field. - */ - public Field build() { -+ Field built = new Field(); - if (result.varint == null) { -- result.varint = Collections.emptyList(); -+ built.varint = Collections.emptyList(); - } else { -- result.varint = Collections.unmodifiableList(result.varint); -+ built.varint = Collections.unmodifiableList(new ArrayList<>(result.varint)); - } - if (result.fixed32 == null) { -- result.fixed32 = Collections.emptyList(); -+ built.fixed32 = Collections.emptyList(); - } else { -- result.fixed32 = Collections.unmodifiableList(result.fixed32); -+ built.fixed32 = Collections.unmodifiableList(new ArrayList<>(result.fixed32)); - } - if (result.fixed64 == null) { -- result.fixed64 = Collections.emptyList(); -+ built.fixed64 = Collections.emptyList(); - } else { -- result.fixed64 = Collections.unmodifiableList(result.fixed64); -+ built.fixed64 = Collections.unmodifiableList(new ArrayList<>(result.fixed64)); - } - if (result.lengthDelimited == null) { -- result.lengthDelimited = Collections.emptyList(); -+ built.lengthDelimited = Collections.emptyList(); - } else { -- result.lengthDelimited = Collections.unmodifiableList(result.lengthDelimited); -+ built.lengthDelimited = Collections.unmodifiableList( -+ new ArrayList<>(result.lengthDelimited)); - } - if (result.group == null) { -- result.group = Collections.emptyList(); -+ built.group = Collections.emptyList(); - } else { -- result.group = Collections.unmodifiableList(result.group); -+ built.group = Collections.unmodifiableList(new ArrayList<>(result.group)); - } - -- final Field returnMe = result; -- result = null; -- return returnMe; -+ return built; - } - - /** Discard the field's contents. */ -@@ -970,7 +973,7 @@ public final class UnknownFieldSet implements MessageLite { - * Merge the values in {@code other} into this field. For each list of values, {@code other}'s - * values are append to the ones in this field. - */ -- public Builder mergeFrom(final Field other) { -+ public Builder mergeFrom(Field other) { - if (!other.varint.isEmpty()) { - if (result.varint == null) { - result.varint = new ArrayList(); -@@ -985,19 +988,19 @@ public final class UnknownFieldSet implements MessageLite { - } - if (!other.fixed64.isEmpty()) { - if (result.fixed64 == null) { -- result.fixed64 = new ArrayList(); -+ result.fixed64 = new ArrayList<>(); - } - result.fixed64.addAll(other.fixed64); - } - if (!other.lengthDelimited.isEmpty()) { - if (result.lengthDelimited == null) { -- result.lengthDelimited = new ArrayList(); -+ result.lengthDelimited = new ArrayList<>(); - } - result.lengthDelimited.addAll(other.lengthDelimited); - } - if (!other.group.isEmpty()) { - if (result.group == null) { -- result.group = new ArrayList(); -+ result.group = new ArrayList<>(); - } - result.group.addAll(other.group); - } -@@ -1005,45 +1008,45 @@ public final class UnknownFieldSet implements MessageLite { - } - - /** Add a varint value. */ -- public Builder addVarint(final long value) { -+ public Builder addVarint(long value) { - if (result.varint == null) { -- result.varint = new ArrayList(); -+ result.varint = new ArrayList<>(); - } - result.varint.add(value); - return this; - } - - /** Add a fixed32 value. */ -- public Builder addFixed32(final int value) { -+ public Builder addFixed32(int value) { - if (result.fixed32 == null) { -- result.fixed32 = new ArrayList(); -+ result.fixed32 = new ArrayList<>(); - } - result.fixed32.add(value); - return this; - } - - /** Add a fixed64 value. */ -- public Builder addFixed64(final long value) { -+ public Builder addFixed64(long value) { - if (result.fixed64 == null) { -- result.fixed64 = new ArrayList(); -+ result.fixed64 = new ArrayList<>(); - } - result.fixed64.add(value); - return this; - } - - /** Add a length-delimited value. */ -- public Builder addLengthDelimited(final ByteString value) { -+ public Builder addLengthDelimited(ByteString value) { - if (result.lengthDelimited == null) { -- result.lengthDelimited = new ArrayList(); -+ result.lengthDelimited = new ArrayList<>(); - } - result.lengthDelimited.add(value); - return this; - } - - /** Add an embedded group. */ -- public Builder addGroup(final UnknownFieldSet value) { -+ public Builder addGroup(UnknownFieldSet value) { - if (result.group == null) { -- result.group = new ArrayList(); -+ result.group = new ArrayList<>(); - } - result.group.add(value); - return this; -diff --git a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java -new file mode 100644 -index 0000000..6ce0fc7 ---- /dev/null -+++ b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java -@@ -0,0 +1,78 @@ -+// Protocol Buffers - Google's data interchange format -+// Copyright 2008 Google Inc. All rights reserved. -+// https://developers.google.com/protocol-buffers/ -+// -+// Redistribution and use in source and binary forms, with or without -+// modification, are permitted provided that the following conditions are -+// met: -+// -+// * Redistributions of source code must retain the above copyright -+// notice, this list of conditions and the following disclaimer. -+// * Redistributions in binary form must reproduce the above -+// copyright notice, this list of conditions and the following disclaimer -+// in the documentation and/or other materials provided with the -+// distribution. -+// * Neither the name of Google Inc. nor the names of its -+// contributors may be used to endorse or promote products derived from -+// this software without specific prior written permission. -+// -+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ -+package com.google.protobuf; -+ -+import static com.google.common.truth.Truth.assertThat; -+ -+import java.io.ByteArrayInputStream; -+import java.io.IOException; -+import java.io.InputStream; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.junit.runners.JUnit4; -+ -+@RunWith(JUnit4.class) -+public final class UnknownFieldSetPerformanceTest { -+ -+ private static byte[] generateBytes(int length) { -+ assertThat(length % 4).isEqualTo(0); -+ byte[] input = new byte[length]; -+ for (int i = 0; i < length; i += 4) { -+ input[i] = (byte) 0x08; // field 1, wiretype 0 -+ input[i + 1] = (byte) 0x08; // field 1, payload 8 -+ input[i + 2] = (byte) 0x20; // field 4, wiretype 0 -+ input[i + 3] = (byte) 0x20; // field 4, payload 32 -+ } -+ return input; -+ } -+ -+ @Test -+ // This is a performance test. Failure here is a timeout. -+ public void testAlternatingFieldNumbers() throws IOException { -+ byte[] input = generateBytes(800000); -+ InputStream in = new ByteArrayInputStream(input); -+ UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder(); -+ CodedInputStream codedInput = CodedInputStream.newInstance(in); -+ builder.mergeFrom(codedInput); -+ } -+ -+ @Test -+ // This is a performance test. Failure here is a timeout. -+ public void testAddField() { -+ UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder(); -+ for (int i = 1; i <= 100000; i++) { -+ UnknownFieldSet.Field field = UnknownFieldSet.Field.newBuilder().addFixed32(i).build(); -+ builder.addField(i, field); -+ } -+ UnknownFieldSet fieldSet = builder.build(); -+ assertThat(fieldSet.getField(100000).getFixed32List().get(0)).isEqualTo(100000); -+ } -+} -diff --git a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java -index c7eb57c..3e1e928 100644 ---- a/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java -+++ b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java -@@ -30,6 +30,9 @@ - - package com.google.protobuf; - -+import static com.google.common.truth.Truth.assertThat; -+import static com.google.common.truth.Truth.assertWithMessage; -+ - import protobuf_unittest.UnittestProto; - import protobuf_unittest.UnittestProto.ForeignEnum; - import protobuf_unittest.UnittestProto.TestAllExtensions; -@@ -39,8 +42,10 @@ import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions; - import protobuf_unittest.UnittestProto.TestPackedExtensions; - import protobuf_unittest.UnittestProto.TestPackedTypes; - import proto3_unittest.UnittestProto3; -+import java.util.List; - import java.util.Arrays; - import java.util.Map; -+import org.junit.Assert; - import junit.framework.TestCase; - - /** -@@ -58,7 +63,7 @@ public class UnknownFieldSetTest extends TestCase { - unknownFields = emptyMessage.getUnknownFields(); - } - -- UnknownFieldSet.Field getField(String name) { -+ private UnknownFieldSet.Field getField(String name) { - Descriptors.FieldDescriptor field = descriptor.findFieldByName(name); - assertNotNull(field); - return unknownFields.getField(field.getNumber()); -@@ -97,6 +102,161 @@ public class UnknownFieldSetTest extends TestCase { - - // ================================================================= - -+ public void testFieldBuildersAreReusable() { -+ UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder(); -+ fieldBuilder.addFixed32(10); -+ UnknownFieldSet.Field first = fieldBuilder.build(); -+ UnknownFieldSet.Field second = fieldBuilder.build(); -+ fieldBuilder.addFixed32(11); -+ UnknownFieldSet.Field third = fieldBuilder.build(); -+ -+ assertThat(first).isEqualTo(second); -+ assertThat(first).isNotEqualTo(third); -+ } -+ -+ public void testClone() { -+ UnknownFieldSet.Builder unknownSetBuilder = UnknownFieldSet.newBuilder(); -+ UnknownFieldSet.Field.Builder fieldBuilder = UnknownFieldSet.Field.newBuilder(); -+ fieldBuilder.addFixed32(10); -+ unknownSetBuilder.addField(8, fieldBuilder.build()); -+ // necessary to call clone twice to expose the bug -+ UnknownFieldSet.Builder clone1 = unknownSetBuilder.clone(); -+ UnknownFieldSet.Builder clone2 = unknownSetBuilder.clone(); // failure is a NullPointerException -+ assertThat(clone1).isNotSameInstanceAs(clone2); -+ } -+ -+ public void testClone_lengthDelimited() { -+ UnknownFieldSet.Builder destUnknownFieldSet = -+ UnknownFieldSet.newBuilder() -+ .addField(997, UnknownFieldSet.Field.newBuilder().addVarint(99).build()) -+ .addField( -+ 999, -+ UnknownFieldSet.Field.newBuilder() -+ .addLengthDelimited(ByteString.copyFromUtf8("some data")) -+ .addLengthDelimited(ByteString.copyFromUtf8("some more data")) -+ .build()); -+ UnknownFieldSet clone = destUnknownFieldSet.clone().build(); -+ assertThat(clone.getField(997)).isNotNull(); -+ UnknownFieldSet.Field field999 = clone.getField(999); -+ List lengthDelimited = field999.getLengthDelimitedList(); -+ assertThat(lengthDelimited.get(0).toStringUtf8()).isEqualTo("some data"); -+ assertThat(lengthDelimited.get(1).toStringUtf8()).isEqualTo("some more data"); -+ -+ UnknownFieldSet clone2 = destUnknownFieldSet.clone().build(); -+ assertThat(clone2.getField(997)).isNotNull(); -+ UnknownFieldSet.Field secondField = clone2.getField(999); -+ List lengthDelimited2 = secondField.getLengthDelimitedList(); -+ assertThat(lengthDelimited2.get(0).toStringUtf8()).isEqualTo("some data"); -+ assertThat(lengthDelimited2.get(1).toStringUtf8()).isEqualTo("some more data"); -+ } -+ -+ public void testReuse() { -+ UnknownFieldSet.Builder builder = -+ UnknownFieldSet.newBuilder() -+ .addField(997, UnknownFieldSet.Field.newBuilder().addVarint(99).build()) -+ .addField( -+ 999, -+ UnknownFieldSet.Field.newBuilder() -+ .addLengthDelimited(ByteString.copyFromUtf8("some data")) -+ .addLengthDelimited(ByteString.copyFromUtf8("some more data")) -+ .build()); -+ -+ UnknownFieldSet fieldSet1 = builder.build(); -+ UnknownFieldSet fieldSet2 = builder.build(); -+ builder.addField(1000, UnknownFieldSet.Field.newBuilder().addVarint(-90).build()); -+ UnknownFieldSet fieldSet3 = builder.build(); -+ -+ assertThat(fieldSet1).isEqualTo(fieldSet2); -+ assertThat(fieldSet1).isNotEqualTo(fieldSet3); -+ } -+ -+ @SuppressWarnings("ModifiedButNotUsed") -+ public void testAddField_zero() { -+ UnknownFieldSet.Field field = getField("optional_int32"); -+ try { -+ UnknownFieldSet.newBuilder().addField(0, field); -+ Assert.fail(); -+ } catch (IllegalArgumentException expected) { -+ assertThat(expected).hasMessageThat().isEqualTo("0 is not a valid field number."); -+ } -+ } -+ -+ @SuppressWarnings("ModifiedButNotUsed") -+ public void testAddField_negative() { -+ UnknownFieldSet.Field field = getField("optional_int32"); -+ try { -+ UnknownFieldSet.newBuilder().addField(-2, field); -+ Assert.fail(); -+ } catch (IllegalArgumentException expected) { -+ assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); -+ } -+ } -+ -+ @SuppressWarnings("ModifiedButNotUsed") -+ public void testClearField_negative() { -+ try { -+ UnknownFieldSet.newBuilder().clearField(-28); -+ Assert.fail(); -+ } catch (IllegalArgumentException expected) { -+ assertThat(expected).hasMessageThat().isEqualTo("-28 is not a valid field number."); -+ } -+ } -+ -+ @SuppressWarnings("ModifiedButNotUsed") -+ public void testMergeField_negative() { -+ UnknownFieldSet.Field field = getField("optional_int32"); -+ try { -+ UnknownFieldSet.newBuilder().mergeField(-2, field); -+ Assert.fail(); -+ } catch (IllegalArgumentException expected) { -+ assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); -+ } -+ } -+ -+ @SuppressWarnings("ModifiedButNotUsed") -+ public void testMergeVarintField_negative() { -+ try { -+ UnknownFieldSet.newBuilder().mergeVarintField(-2, 78); -+ Assert.fail(); -+ } catch (IllegalArgumentException expected) { -+ assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); -+ } -+ } -+ -+ @SuppressWarnings("ModifiedButNotUsed") -+ public void testHasField_negative() { -+ assertThat(UnknownFieldSet.newBuilder().hasField(-2)).isFalse(); -+ } -+ -+ @SuppressWarnings("ModifiedButNotUsed") -+ public void testMergeLengthDelimitedField_negative() { -+ ByteString byteString = ByteString.copyFromUtf8("some data"); -+ try { -+ UnknownFieldSet.newBuilder().mergeLengthDelimitedField(-2, byteString); -+ Assert.fail(); -+ } catch (IllegalArgumentException expected) { -+ assertThat(expected).hasMessageThat().isEqualTo("-2 is not a valid field number."); -+ } -+ } -+ -+ public void testAddField() { -+ UnknownFieldSet.Field field = getField("optional_int32"); -+ UnknownFieldSet fieldSet = UnknownFieldSet.newBuilder().addField(1, field).build(); -+ assertThat(fieldSet.getField(1)).isEqualTo(field); -+ } -+ -+ public void testAddField_withReplacement() { -+ UnknownFieldSet.Field first = UnknownFieldSet.Field.newBuilder().addFixed32(56).build(); -+ UnknownFieldSet.Field second = UnknownFieldSet.Field.newBuilder().addFixed32(25).build(); -+ UnknownFieldSet fieldSet = UnknownFieldSet.newBuilder() -+ .addField(1, first) -+ .addField(1, second) -+ .build(); -+ List list = fieldSet.getField(1).getFixed32List(); -+ assertThat(list).hasSize(1); -+ assertThat(list.get(0)).isEqualTo(25); -+ } -+ - public void testVarint() throws Exception { - UnknownFieldSet.Field field = getField("optional_int32"); - assertEquals(1, field.getVarintList().size()); -@@ -173,6 +333,15 @@ public class UnknownFieldSetTest extends TestCase { - assertEquals("1: 1\n2: 2\n3: 3\n3: 4\n", destination.toString()); - } - -+ public void testAsMap() throws Exception { -+ UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder().mergeFrom(unknownFields); -+ Map mapFromBuilder = builder.asMap(); -+ assertThat(mapFromBuilder).isNotEmpty(); -+ UnknownFieldSet fields = builder.build(); -+ Map mapFromFieldSet = fields.asMap(); -+ assertThat(mapFromFieldSet).containsExactlyEntriesIn(mapFromBuilder); -+ } -+ - public void testClear() throws Exception { - UnknownFieldSet fields = UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build(); - assertTrue(fields.asMap().isEmpty()); -diff --git a/java/lite/pom.xml b/java/lite/pom.xml -index 104c5c1..d095483 100644 ---- a/java/lite/pom.xml -+++ b/java/lite/pom.xml -@@ -232,7 +232,8 @@ - TestUtil.java - TypeRegistryTest.java - UnknownEnumValueTest.java -- UnknownFieldSetLiteTest.java -+ UnknownFieldSetLiteTest.java -+ UnknownFieldSetPerformanceTest.java - UnknownFieldSetTest.java - WellKnownTypesTest.java - WireFormatTest.java --- -2.30.0 - diff --git a/5ec7f0c4a113e2f18ac2c6cc7df51ad6afc24081.zip b/5ec7f0c4a113e2f18ac2c6cc7df51ad6afc24081.zip new file mode 100644 index 0000000000000000000000000000000000000000..a1463746e9071cb7b6ea11dcd6bc8e9fea988936 Binary files /dev/null and b/5ec7f0c4a113e2f18ac2c6cc7df51ad6afc24081.zip differ diff --git a/disable-tests-on-32-bit-systems.patch b/disable-tests-on-32-bit-systems.patch new file mode 100644 index 0000000000000000000000000000000000000000..cf1973424a6137ba93a6d5fc03272d5e03e8eb89 --- /dev/null +++ b/disable-tests-on-32-bit-systems.patch @@ -0,0 +1,76 @@ +--- src/google/protobuf/any_test.cc 2021-10-22 08:52:03.604280348 +0200 ++++ src/google/protobuf/any_test.cc.orig 2021-10-22 08:51:46.935156306 +0200 +@@ -60,13 +60,6 @@ + EXPECT_EQ(12345, submessage.int32_value()); + } + +-TEST(AnyTest, TestPackFromSerializationExceedsSizeLimit) { +- protobuf_unittest::TestAny submessage; +- submessage.mutable_text()->resize(INT_MAX, 'a'); +- protobuf_unittest::TestAny message; +- EXPECT_FALSE(message.mutable_any_value()->PackFrom(submessage)); +-} +- + TEST(AnyTest, TestUnpackWithTypeMismatch) { + protobuf_unittest::TestAny payload; + payload.set_int32_value(13); +--- src/google/protobuf/arena_unittest.cc 2021-10-22 08:52:37.804534886 +0200 ++++ src/google/protobuf/arena_unittest.cc.orig 2021-10-22 08:51:55.150217437 +0200 +@@ -1341,34 +1341,6 @@ + // Align n to next multiple of 8 + uint64_t Align8(uint64_t n) { return (n + 7) & -8; } + +-TEST(ArenaTest, SpaceAllocated_and_Used) { +- Arena arena_1; +- EXPECT_EQ(0, arena_1.SpaceAllocated()); +- EXPECT_EQ(0, arena_1.SpaceUsed()); +- EXPECT_EQ(0, arena_1.Reset()); +- Arena::CreateArray(&arena_1, 320); +- // Arena will allocate slightly more than 320 for the block headers. +- EXPECT_LE(320, arena_1.SpaceAllocated()); +- EXPECT_EQ(Align8(320), arena_1.SpaceUsed()); +- EXPECT_LE(320, arena_1.Reset()); +- +- // Test with initial block. +- std::vector arena_block(1024); +- ArenaOptions options; +- options.start_block_size = 256; +- options.max_block_size = 8192; +- options.initial_block = &arena_block[0]; +- options.initial_block_size = arena_block.size(); +- Arena arena_2(options); +- EXPECT_EQ(1024, arena_2.SpaceAllocated()); +- EXPECT_EQ(0, arena_2.SpaceUsed()); +- EXPECT_EQ(1024, arena_2.Reset()); +- Arena::CreateArray(&arena_2, 55); +- EXPECT_EQ(1024, arena_2.SpaceAllocated()); +- EXPECT_EQ(Align8(55), arena_2.SpaceUsed()); +- EXPECT_EQ(1024, arena_2.Reset()); +-} +- + TEST(ArenaTest, BlockSizeDoubling) { + Arena arena; + EXPECT_EQ(0, arena.SpaceUsed()); +@@ -1368,22 +1396,6 @@ + } + } + +-TEST(ArenaTest, BlockSizeSmallerThanAllocation) { +- for (size_t i = 0; i <= 8; ++i) { +- ArenaOptions opt; +- opt.start_block_size = opt.max_block_size = i; +- Arena arena(opt); +- +- *Arena::Create(&arena) = 42; +- EXPECT_GE(arena.SpaceAllocated(), 8); +- EXPECT_EQ(8, arena.SpaceUsed()); +- +- *Arena::Create(&arena) = 42; +- EXPECT_GE(arena.SpaceAllocated(), 16); +- EXPECT_EQ(16, arena.SpaceUsed()); +- } +-} +- + TEST(ArenaTest, GetArenaShouldReturnTheArenaForArenaAllocatedMessages) { + Arena arena; + ArenaMessage* message = Arena::CreateMessage(&arena); diff --git a/ftdetect-proto.vim b/ftdetect-proto.vim new file mode 100644 index 0000000000000000000000000000000000000000..e9b063e8a9504dccda06427210f8848ef819a480 --- /dev/null +++ b/ftdetect-proto.vim @@ -0,0 +1,4 @@ +augroup filetype + au! BufRead,BufNewFile *.proto setfiletype proto +augroup end + diff --git a/protobuf-3.14-disable-IoTest.LargeOutput.patch b/protobuf-3.14-disable-IoTest.LargeOutput.patch new file mode 100644 index 0000000000000000000000000000000000000000..eea2849ec09911c657c9710f4c4a375f31ed4c10 --- /dev/null +++ b/protobuf-3.14-disable-IoTest.LargeOutput.patch @@ -0,0 +1,25 @@ +--- a/src/google/protobuf/io/zero_copy_stream_unittest.cc.orig 2021-01-12 12:25:18.471517830 +0100 ++++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc 2021-01-12 12:25:42.022696126 +0100 +@@ -712,22 +712,6 @@ + } + } + +-// Verifies that outputs up to kint32max can be created. +-TEST_F(IoTest, LargeOutput) { +- std::string str; +- StringOutputStream output(&str); +- void* unused_data; +- int size; +- // Repeatedly calling Next should eventually grow the buffer to kint32max. +- do { +- EXPECT_TRUE(output.Next(&unused_data, &size)); +- } while (str.size() < std::numeric_limits::max()); +- // Further increases should be possible. +- output.Next(&unused_data, &size); +- EXPECT_GT(size, 0); +-} +- +- + // To test files, we create a temporary file, write, read, truncate, repeat. + TEST_F(IoTest, FileIo) { + std::string filename = TestTempDir() + "/zero_copy_stream_test_file"; diff --git a/protobuf-all-3.14.0.tar.gz b/protobuf-3.19.4-all.tar.gz similarity index 38% rename from protobuf-all-3.14.0.tar.gz rename to protobuf-3.19.4-all.tar.gz index 3c6f0b8506f4b14e9c377a181d8572551c297e35..c65bee8069ecdc7b85170af7049957dc58766177 100644 Binary files a/protobuf-all-3.14.0.tar.gz and b/protobuf-3.19.4-all.tar.gz differ diff --git a/protobuf-3.19.4-jre17-add-opens.patch b/protobuf-3.19.4-jre17-add-opens.patch new file mode 100644 index 0000000000000000000000000000000000000000..2d159fa6771d398d610538a35a1fe19da9c38488 --- /dev/null +++ b/protobuf-3.19.4-jre17-add-opens.patch @@ -0,0 +1,10 @@ +--- protobuf-3.19.4/java/pom.xml.jre17 2022-02-13 11:45:39.367028268 +0900 ++++ protobuf-3.19.4/java/pom.xml 2022-02-13 12:43:18.212542147 +0900 +@@ -37,6 +37,7 @@ + src/test/proto + ${project.build.directory}/generated-sources + ${project.build.directory}/generated-test-sources ++ --add-opens java.base/java.lang=ALL-UNNAMED + + + diff --git a/protobuf.spec b/protobuf.spec index 0be0c02461164b7c38501b5adc613dad0f99a373..00ffb935dc41dee5d7ab1f227e89aee8068d76da 100644 --- a/protobuf.spec +++ b/protobuf.spec @@ -1,58 +1,92 @@ # Build -python subpackage %bcond_without python # Build -java subpackage +%ifarch %{java_arches} %bcond_without java +%else +%bcond_with java +%endif #global rcver rc2 Summary: Protocol Buffers - Google's data interchange format Name: protobuf -Version: 3.14.0 -Release: 4 +Version: 3.19.4 +Release: 5 License: BSD URL: https://github.com/protocolbuffers/protobuf -Source: https://github.com/protocolbuffers/protobuf/releases/download/v%{version}%{?rcver}/%{name}-all-%{version}%{?rcver}.tar.gz -Source1: protobuf-init.el - -Patch9000: 0001-add-secure-compile-option-in-Makefile.patch -Patch9001: 0002-add-secure-compile-fs-check-in-Makefile.patch -Patch9002: 0003-fix-CVE-2021-22570.patch -Patch9003: 0004-Improve-performance-of-parsing-unknown-fields-in-Jav.patch - -BuildRequires: make autoconf automake emacs gcc-c++ libtool pkgconfig zlib-devel +Source: https://github.com/protocolbuffers/protobuf/archive/v%{version}%{?rcver}/%{name}-%{version}%{?rcver}-all.tar.gz +Source1: ftdetect-proto.vim +Source2: protobuf-init.el +# For tests (using exactly the same version as the release) +Source3: https://github.com/google/googletest/archive/5ec7f0c4a113e2f18ac2c6cc7df51ad6afc24081.zip + +# https://github.com/protocolbuffers/protobuf/issues/8082 +Patch1: protobuf-3.14-disable-IoTest.LargeOutput.patch +# Disable tests that are failing on 32bit systems +Patch2: disable-tests-on-32-bit-systems.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2051202 +# java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) +# throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @12d5624a +# at com.google.protobuf.ServiceTest.testGetPrototype(ServiceTest.java:107) +Patch3: protobuf-3.19.4-jre17-add-opens.patch + +BuildRequires: make +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: emacs +BuildRequires: gcc-c++ +BuildRequires: libtool +BuildRequires: pkgconfig +BuildRequires: zlib-devel + +%ifnarch %{java_arches} +Obsoletes: %{name}-java-util < 3.19.4-4 +Obsoletes: %{name}-javadoc < 3.19.4-4 +Obsoletes: %{name}-parent < 3.19.4-4 +Obsoletes: %{name}-bom < 3.19.4-4 +Obsoletes: %{name}-javalite < 3.19.4-4 +%endif %description - -Protocol Buffers (a.k.a., protobuf) are Google's language-neutral, -platform-neutral, extensible mechanism for serializing structured data. -You can find protobuf's documentation on the Google Developers site. +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. + +Protocol buffers are a flexible, efficient, automated mechanism for +serializing structured data – think XML, but smaller, faster, and +simpler. You define how you want your data to be structured once, then +you can use special generated source code to easily write and read +your structured data to and from a variety of data streams and using a +variety of languages. You can even update your data structure without +breaking deployed programs that are compiled against the "old" format. %package compiler -Summary: Protocol Buffers compiler +Summary: Protocol Buffers compiler Requires: %{name} = %{version}-%{release} -Obsoletes: protobuf-emacs < %{version} -Obsoletes: protobuf-emacs-el < %{version} -Requires: emacs-filesystem >= %{_emacs_version} %description compiler -This package containers Protocol Buffers compiler for all programming languages. - +This package contains Protocol Buffers compiler for all programming +languages %package devel Summary: Protocol Buffers C++ headers and libraries Requires: %{name} = %{version}-%{release} Requires: %{name}-compiler = %{version}-%{release} -Requires: zlib-devel pkgconfig vim-enhanced -Provides: %{name}-static -Provides: %{name}-vim -Obsoletes: %{name}-static < %{version} -Obsoletes: %{name}-vim < %{version} - +Requires: zlib-devel +Requires: pkgconfig %description devel This package contains Protocol Buffers compiler for all languages and C++ headers and libraries +%package static +Summary: Static development files for %{name} +Requires: %{name}-devel = %{version}-%{release} + +%description static +Static libraries for Protocol Buffers + %package lite Summary: Protocol Buffers LITE_RUNTIME libraries @@ -67,8 +101,6 @@ lacks descriptors, reflection, and some other features. Summary: Protocol Buffers LITE_RUNTIME development libraries Requires: %{name}-devel = %{version}-%{release} Requires: %{name}-lite = %{version}-%{release} -Provides: %{name}-lite-static -Obsoletes: %{name}-lite-static < %{version} %description lite-devel This package contains development libraries built with @@ -78,6 +110,18 @@ The "optimize_for = LITE_RUNTIME" option causes the compiler to generate code which only depends libprotobuf-lite, which is much smaller than libprotobuf but lacks descriptors, reflection, and some other features. +%package lite-static +Summary: Static development files for %{name}-lite +Requires: %{name}-devel = %{version}-%{release} + +%description lite-static +This package contains static development libraries built with +optimize_for = LITE_RUNTIME. + +The "optimize_for = LITE_RUNTIME" option causes the compiler to generate code +which only depends libprotobuf-lite, which is much smaller than libprotobuf but +lacks descriptors, reflection, and some other features. + %if %{with python} %package -n python%{python3_pkgversion}-%{name} Summary: Python 3 bindings for Google Protocol Buffers @@ -86,8 +130,8 @@ BuildRequires: python%{python3_pkgversion}-devel BuildRequires: python%{python3_pkgversion}-setuptools BuildRequires: python%{python3_pkgversion}-wheel Requires: python%{python3_pkgversion}-six >= 1.9 -Conflicts: %{name}-compiler > %{version}-%{release} -Conflicts: %{name}-compiler < %{version}-%{release} +Conflicts: %{name}-compiler > %{version} +Conflicts: %{name}-compiler < %{version} Provides: %{name}-python3 = %{version}-%{release} %{?python_provide:%python_provide python%{python3_pkgversion}-%{name}} @@ -95,6 +139,15 @@ Provides: %{name}-python3 = %{version}-%{release} This package contains Python 3 libraries for Google Protocol Buffers %endif +%package vim +Summary: Vim syntax highlighting for Google Protocol Buffers descriptions +BuildArch: noarch +Requires: vim-enhanced + +%description vim +This package contains syntax highlighting for Google Protocol Buffers +descriptions in Vim editor + %if %{with java} %package java @@ -103,12 +156,16 @@ BuildArch: noarch BuildRequires: maven-local BuildRequires: mvn(com.google.code.gson:gson) BuildRequires: mvn(com.google.guava:guava) +BuildRequires: mvn(com.google.guava:guava-testlib) +BuildRequires: mvn(com.google.truth:truth) BuildRequires: mvn(junit:junit) BuildRequires: mvn(org.apache.felix:maven-bundle-plugin) BuildRequires: mvn(org.apache.maven.plugins:maven-antrun-plugin) BuildRequires: mvn(org.apache.maven.plugins:maven-source-plugin) BuildRequires: mvn(org.codehaus.mojo:build-helper-maven-plugin) BuildRequires: mvn(org.easymock:easymock) +Conflicts: %{name}-compiler > %{version} +Conflicts: %{name}-compiler < %{version} Obsoletes: %{name}-javanano < 3.6.0 %description java @@ -152,34 +209,42 @@ Protocol Buffer BOM POM. %endif +%package emacs +Summary: Emacs mode for Google Protocol Buffers descriptions +BuildArch: noarch +Requires: emacs-filesystem >= %{_emacs_version} +Obsoletes: protobuf-emacs-el < 3.6.1-4 + +%description emacs +This package contains syntax highlighting for Google Protocol Buffers +descriptions in the Emacs editor. + %prep -%setup -q -n %{name}-%{version}%{?rcver} -%autopatch -p1 +%setup -q -n %{name}-%{version}%{?rcver} -a 3 +%ifarch %{ix86} armv7hl +# IoTest.LargeOutput fails on 32bit arches +# https://github.com/protocolbuffers/protobuf/issues/8082 +%patch1 -p1 +# Need to disable more tests that fail on 32bit arches only +%patch2 -p0 +%endif +%patch3 -p1 -b .jre17 +mv googletest-5ec7f0c4a113e2f18ac2c6cc7df51ad6afc24081/* third_party/googletest/ find -name \*.cc -o -name \*.h | xargs chmod -x chmod 644 examples/* %if %{with java} -#%pom_remove_dep com.google.truth:truth java/pom.xml -#%pom_remove_dep org.easymock:easymockclassextension java/pom.xml java/*/pom.xml -%pom_remove_dep org.easymock:easymockclassextension java/pom.xml java/core/pom.xml java/lite/pom.xml java/util/pom.xml -%pom_remove_dep com.google.truth:truth java/pom.xml java/util/pom.xml java/lite/pom.xml java/core/pom.xml %pom_remove_dep com.google.errorprone:error_prone_annotations java/util/pom.xml -%pom_remove_dep com.google.guava:guava-testlib java/pom.xml java/util/pom.xml - -# These use easymockclassextension -rm java/core/src/test/java/com/google/protobuf/ServiceTest.java - -#rm -r java/core/src/test - -# These use truth or error_prone_annotations or guava-testlib -rm java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java -rm java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java -rm java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java -rm java/core/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java -rm java/core/src/test/java/com/google/protobuf/TextFormatTest.java -rm java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java -rm java/core/src/test/java/com/google/protobuf/UnknownFieldSetPerformanceTest.java -rm -r java/util/src/test/java/com/google/protobuf/util -rm -r java/util/src/main/java/com/google/protobuf/util +%pom_remove_dep com.google.j2objc:j2objc-annotations java/util/pom.xml + +# Remove annotation libraries we don't have +annotations=$( + find -name '*.java' | + xargs grep -h -e '^import com\.google\.errorprone\.annotation' \ + -e '^import com\.google\.j2objc\.annotations' | + sort -u | sed 's/.*\.\([^.]*\);/\1/' | paste -sd\| +) +find -name '*.java' | xargs sed -ri \ + "s/^import .*\.($annotations);//;s/@($annotations)"'\>\s*(\((("[^"]*")|([^)]*))\))?//g' # Make OSGi dependency on sun.misc package optional %pom_xpath_inject "pom:configuration/pom:instructions" "sun.misc;resolution:=optional,*" java/core @@ -188,12 +253,12 @@ rm -r java/util/src/main/java/com/google/protobuf/util %mvn_file :protobuf-java:jar: %{name}/%{name}-java %{name} # This test is incredibly slow on arm -# https://github.com/protocolbuffers/protobuf/issues/2389 -%ifarch %{arm} +# https://github.com/google/protobuf/issues/2389 +%ifarch %{arm} s390x mv java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java \ java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java.slow mv java/core/src/test/java/com/google/protobuf/DecodeUtf8Test.java \ - java/core/src/test/java/com/google/protobuf/DecodeUtf8Test.java.slow + java/core/src/test/java/com/google/protobuf/DecodeUtf8Test.java.slow %endif %endif @@ -204,7 +269,13 @@ iconv -f iso8859-1 -t utf-8 CONTRIBUTORS.txt > CONTRIBUTORS.txt.utf8 mv CONTRIBUTORS.txt.utf8 CONTRIBUTORS.txt export PTHREAD_LIBS="-lpthread" ./autogen.sh -%configure +%configure + +# -Wno-error=type-limits: +# https://bugzilla.redhat.com/show_bug.cgi?id=1838470 +# https://github.com/protocolbuffers/protobuf/issues/7514 +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95148 +# (also set in %%check) %make_build CXXFLAGS="%{build_cxxflags} -Wno-error=type-limits" %if %{with python} @@ -214,6 +285,11 @@ popd %endif %if %{with java} +%ifarch %ix86 s390x %{arm} +export MAVEN_OPTS=-Xmx1024m +%endif +%pom_disable_module kotlin java/pom.xml +%pom_disable_module kotlin-lite java/pom.xml %mvn_build -s -- -f java/pom.xml %endif @@ -236,12 +312,12 @@ find %{buildroot} -type f -name "*.la" -exec rm -f {} \; %if %{with python} pushd python -#python ./setup.py install --root=%{buildroot} --single-version-externally-managed --record=INSTALLED_FILES --optimize=1 %py3_install find %{buildroot}%{python3_sitelib} -name \*.py | xargs sed -i -e '1{\@^#!@d}' popd %endif +install -p -m 644 -D %{SOURCE1} %{buildroot}%{_datadir}/vim/vimfiles/ftdetect/proto.vim install -p -m 644 -D editors/proto.vim %{buildroot}%{_datadir}/vim/vimfiles/syntax/proto.vim %if %{with java} @@ -252,7 +328,7 @@ mkdir -p %{buildroot}%{_emacs_sitelispdir}/%{name} install -p -m 0644 editors/protobuf-mode.el %{buildroot}%{_emacs_sitelispdir}/%{name} install -p -m 0644 editors/protobuf-mode.elc %{buildroot}%{_emacs_sitelispdir}/%{name} mkdir -p %{buildroot}%{_emacs_sitestartdir} -install -p -m 0644 %{SOURCE1} %{buildroot}%{_emacs_sitestartdir} +install -p -m 0644 %{SOURCE2} %{buildroot}%{_emacs_sitestartdir} %ldconfig_scriptlets %ldconfig_scriptlets lite @@ -261,16 +337,13 @@ install -p -m 0644 %{SOURCE1} %{buildroot}%{_emacs_sitestartdir} %files %doc CHANGES.txt CONTRIBUTORS.txt README.md %license LICENSE -%{_libdir}/libprotobuf.so.25* +%{_libdir}/libprotobuf.so.30* %files compiler -%{_bindir}/protoc -%{_libdir}/libprotoc.so.25* -%{_emacs_sitelispdir}/%{name}/ -%{_emacs_sitestartdir}/protobuf-init.el -%license LICENSE %doc README.md - +%license LICENSE +%{_bindir}/protoc +%{_libdir}/libprotoc.so.30* %files devel %dir %{_includedir}/google @@ -279,16 +352,23 @@ install -p -m 0644 %{SOURCE1} %{buildroot}%{_emacs_sitestartdir} %{_libdir}/libprotoc.so %{_libdir}/pkgconfig/protobuf.pc %doc examples/add_person.cc examples/addressbook.proto examples/list_people.cc examples/Makefile examples/README.md + +%files emacs +%{_emacs_sitelispdir}/%{name}/ +%{_emacs_sitestartdir}/protobuf-init.el + +%files static %{_libdir}/libprotobuf.a %{_libdir}/libprotoc.a -%{_datadir}/vim/vimfiles/syntax/proto.vim - + %files lite -%{_libdir}/libprotobuf-lite.so.25* +%{_libdir}/libprotobuf-lite.so.30* %files lite-devel %{_libdir}/libprotobuf-lite.so %{_libdir}/pkgconfig/protobuf-lite.pc + +%files lite-static %{_libdir}/libprotobuf-lite.a %if %{with python} @@ -301,6 +381,10 @@ install -p -m 0644 %{SOURCE1} %{buildroot}%{_emacs_sitestartdir} %doc examples/add_person.py examples/list_people.py examples/addressbook.proto %endif +%files vim +%{_datadir}/vim/vimfiles/ftdetect/proto.vim +%{_datadir}/vim/vimfiles/syntax/proto.vim + %if %{with java} %files java -f .mfiles-protobuf-java %doc examples/AddPerson.java examples/ListPeople.java @@ -322,96 +406,329 @@ install -p -m 0644 %{SOURCE1} %{buildroot}%{_emacs_sitestartdir} %license LICENSE %endif + %changelog -* Wed Apr 27 2022 wangxiaochao - 3.14.0-4 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC: Improve performance of parsing unknown fields in Java - -* Fri Mar 18 2022 wangxiaochao - 3.14.0-3 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC: fix CVE-2021-22570 - -* Thu Mar 10 2022 wangxiaochao - 3.14.0-2 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC: fix mainline compile failed - -* Fri Jul 30 2021 liyanan - 3.14.0-1 -- update to 3.14.0 - -* Mon Apr 26 2021 haozi007 - 3.12.3-16 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: split compiler from devel - -* Sat Feb 20 2021 haozi007 - 3.12.3-15 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: add fstack check - -* Tue Sep 1 2020 wutao - 3.12.3-14 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: enhance java function and fix build errors - -* Sat Aug 29 2020 openEuler Buildteam - 3.12.3-13 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC: remove Conflicts - -* Fri Aug 28 2020 openEuler Buildteam - 3.12.3-12 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC: invalid version of Conflicts - -* Thu Jul 23 2020 openEuler Buildteam - 3.12.3-11 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: drop python2-protobuf and refactor .spec file - -* Thu Jul 16 2020 openEuler Buildteam - 3.12.3-10 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC:upgrade from 3.9.0 to 3.12.3 - -* Wed Apr 08 2020 openEuler Buildteam - 3.9.0-9 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC: remove unnecessary files - -* Thu Dec 12 2019 openEuler Buildteam - 3.9.0-8.h3 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC:add bind now secure compile option - -* Wed Nov 27 2019 openEuler Buildteam - 3.9.0-8.h2 -- Type:enhancement -- ID:NA -- SUG:NA -- DESC:compatible to centos 7.5 - -* Tue Nov 26 2019 openEuler Buildteam - 3.9.0-8.h1 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC:upgrade from 3.5.0 to 3.9.0 - -* Fri Nov 01 2019 openEuler Buildteam - 3.5.0-8.h1 -- Type:bugfix -- ID:NA -- SUG:NA -- DESC:change patch's names according to new rules +* Fri Jul 22 2022 liksh - 3.19.4-5 +- rebuild for openEuler openstack yoga + +* Wed Jul 06 2022 Benjamin A. Beasley - 3.19.4-4 +- Exclude java subpackages on non-java arches (fix RHBZ#2104092) +- Obsolete java subpackages on non-java arches + +* Mon Jun 13 2022 Python Maint - 3.19.4-3 +- Rebuilt for Python 3.11 + +* Sun Feb 13 2022 Mamoru TASAKA - 3.19.4-2 +- Add some --add-opens option for java17 +- Restrict heap usage for mvn also on %%ix86 + +* Mon Feb 07 2022 Orion Poplawski - 3.19.4-1 +- Update to 3.19.4 + +* Sat Feb 05 2022 Jiri Vanek - 3.19.0-4 +- Rebuilt for java-17-openjdk as system jdk + +* Fri Jan 21 2022 Fedora Release Engineering - 3.19.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Wed Nov 10 2021 Orion Poplawski - 3.19.0-2 +- Re-enable java + +* Wed Oct 27 2021 Major Hayden - 3.19.0-1 +- Update to 3.19.1 + +* Fri Oct 22 2021 Adrian Reber - 3.18.1-2 +- Disable tests that fail on 32bit arches + +* Thu Oct 14 2021 Orion Poplawski - 3.18.1-1 +- Update to 3.18.1 + +* Fri Jul 23 2021 Fedora Release Engineering - 3.14.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Fri Jun 04 2021 Python Maint - 3.14.0-5 +- Rebuilt for Python 3.10 + +* Thu May 06 2021 Adrian Reber - 3.14.0-4 +- Reintroduce the emacs subpackage to avoid file conflicts between + protobuf-compiler.x86_64 and protobuf-compiler.i686 + +* Tue Mar 30 2021 Jonathan Wakely - 3.14.0-3 +- Rebuilt for removed libstdc++ symbol (#1937698) + +* Wed Jan 27 2021 Fedora Release Engineering - 3.14.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Mon Jan 04 2021 Adrian Reber - 3.14.0-1 +- Update to 3.14.0 + +* Wed Aug 26 2020 Charalampos Stratakis - 3.13.0-1 +- Update to 3.13.0 + +* Sat Aug 01 2020 Fedora Release Engineering - 3.12.3-4 +- Second attempt - Rebuilt for + https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jul 28 2020 Fedora Release Engineering - 3.12.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Sat Jul 11 2020 Jiri Vanek - 3.12.3-2 +- Rebuilt for JDK-11, see https://fedoraproject.org/wiki/Changes/Java11 + +* Fri Jun 19 2020 Adrian Reber - 3.12.3-2 +- Update to 3.12.3 + +* Tue May 26 2020 Miro Hrončok - 3.11.4-2 +- Rebuilt for Python 3.9 + +* Tue Mar 31 2020 Adrian Reber - 3.11.4-1 +- Update to 3.11.4 + +* Thu Jan 30 2020 Fedora Release Engineering - 3.11.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Dec 18 2019 Adrian Reber - 3.11.2-1 +- Update to 3.11.2 + +* Tue Nov 19 2019 Miro Hrončok - 3.6.1-9 +- Drop python2-protobuf (#1765879) + +* Sat Oct 26 2019 Orion Poplawski - 3.6.1-8 +- Drop obsolete BR on python-google-apputils + +* Thu Oct 03 2019 Miro Hrončok - 3.6.1-7 +- Rebuilt for Python 3.8.0rc1 (#1748018) + +* Mon Aug 19 2019 Miro Hrončok - 3.6.1-6 +- Rebuilt for Python 3.8 + +* Fri Jul 26 2019 Fedora Release Engineering - 3.6.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Wed May 8 2019 Orion Poplawski - 3.6.1-4 +- Update emacs packaging to comply with guidelines + +* Wed Feb 27 2019 Orion Poplawski - 3.6.1-3 +- Update googletest to 1.8.1 to re-enable tests + +* Sat Feb 02 2019 Fedora Release Engineering - 3.6.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Tue Oct 23 2018 Felix Kaechele - 3.6.1-1 +- update to 3.6.1 +- obsolete javanano subpackage; discontinued upstream + +* Fri Jul 27 2018 Igor Gnatenko - 3.5.0-8 +- Rebuild for new binutils + +* Fri Jul 13 2018 Fedora Release Engineering - 3.5.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Jun 19 2018 Miro Hrončok - 3.5.0-6 +- Rebuilt for Python 3.7 + +* Wed Feb 21 2018 Iryna Shcherbina - 3.5.0-5 +- Update Python 2 dependency declarations to new packaging standards + (See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3) + +* Fri Feb 09 2018 Igor Gnatenko - 3.5.0-4 +- Escape macros in %%changelog + +* Fri Feb 09 2018 Fedora Release Engineering - 3.5.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Fri Feb 02 2018 Igor Gnatenko - 3.5.0-2 +- Switch to %%ldconfig_scriptlets + +* Thu Nov 23 2017 Igor Gnatenko - 3.5.0-1 +- Update to 3.5.0 + +* Mon Nov 13 2017 Igor Gnatenko - 3.4.1-1 +- Update to 3.4.1 + +* Thu Aug 03 2017 Fedora Release Engineering - 3.3.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 3.3.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue Jun 27 2017 Mat Booth - 3.3.1-2 +- Make OSGi dependency on sun.misc package optional. This package is not + available in all execution environments and will not be available in Java 9. + +* Mon Jun 12 2017 Orion Poplawski - 3.3.1-1 +- Update to 3.3.1 + +* Mon May 15 2017 Fedora Release Engineering - 3.2.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_27_Mass_Rebuild + +* Sat Feb 11 2017 Fedora Release Engineering - 3.2.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Jan 27 2017 Orion Poplawski - 3.2.0-1 +- Update to 3.2.0 final + +* Mon Jan 23 2017 Orion Poplawski - 3.2.0-0.1.rc2 +- Update to 3.2.0rc2 + +* Mon Dec 19 2016 Miro Hrončok - 3.1.0-6 +- Rebuild for Python 3.6 + +* Sat Nov 19 2016 Orion Poplawski - 3.1.0-5 +- Disable slow test on arm + +* Fri Nov 18 2016 Orion Poplawski - 3.1.0-4 +- Ship python 3 module + +* Fri Nov 18 2016 Orion Poplawski - 3.1.0-3 +- Fix jar file compat symlink + +* Fri Nov 18 2016 Orion Poplawski - 3.1.0-2 +- Add needed python requirement + +* Fri Nov 04 2016 Orion Poplawski - 3.1.0-2 +- Make various sub-packages noarch + +* Fri Nov 04 2016 gil cattaneo 3.1.0-2 +- enable javanano +- minor changes to adapt to current guidelines + +* Fri Nov 04 2016 Orion Poplawski - 3.1.0-1 +- Update to 3.1.0 + +* Tue Jul 19 2016 Fedora Release Engineering - 2.6.1-5 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Thu Feb 04 2016 Fedora Release Engineering - 2.6.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jan 20 2016 Orion Poplawski - 2.6.1-3 +- Tests no longer segfaulting on arm + +* Thu Jun 18 2015 Fedora Release Engineering - 2.6.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Mon Apr 6 2015 Orion Poplawski - 2.6.1-1 +- Update to 2.6.1 +- New URL +- Cleanup spec +- Add patch to fix emacs compilation with emacs 24.4 +- Drop java-fixes patch, use pom macros instead +- Add BR on python-google-apputils and mvn(org.easymock:easymock) +- Run make check +- Make -static require -devel (bug #1067475) + +* Thu Mar 26 2015 Kalev Lember - 2.6.0-4 +- Rebuilt for GCC 5 ABI change + +* Sat Feb 21 2015 Till Maas - 2.6.0-3 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + +* Wed Dec 17 2014 Peter Lemenkov - 2.6.0-2 +- Added missing Requires zlib-devel to protobuf-devel (see rhbz #1173343). See + also rhbz #732087. + +* Sun Oct 19 2014 Conrad Meyer - 2.6.0-1 +- Bump to upstream release 2.6.0 (rh# 1154474). +- Rebase 'java fixes' patch on 2.6.0 pom.xml. +- Drop patch #3 (fall back to generic GCC atomics if no specialized atomics + exist, e.g. AArch64 GCC); this has been upstreamed. + +* Sun Oct 19 2014 Conrad Meyer - 2.5.0-11 +- protobuf-emacs requires emacs(bin), not emacs (rh# 1154456) + +* Sun Aug 17 2014 Fedora Release Engineering - 2.5.0-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Mon Jun 16 2014 Mikolaj Izdebski - 2.5.0-9 +- Update to current Java packaging guidelines + +* Sat Jun 07 2014 Fedora Release Engineering - 2.5.0-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue Mar 04 2014 Stanislav Ochotnicky - 2.5.0-7 +- Use Requires: java-headless rebuild (#1067528) + +* Thu Dec 12 2013 Conrad Meyer - 2.5.0-6 +- BR python-setuptools-devel -> python-setuptools + +* Sun Aug 04 2013 Fedora Release Engineering - 2.5.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Thu May 16 2013 Dan Horák - 2.5.0-4 +- export the new generic atomics header (rh #926374) + +* Mon May 6 2013 Stanislav Ochotnicky - 2.5.0-3 +- Add support for generic gcc atomic operations (rh #926374) + +* Sat Apr 27 2013 Conrad Meyer - 2.5.0-2 +- Remove changelog history from before 2010 +- This spec already runs autoreconf -fi during %%build, but bump build for + rhbz #926374 + +* Sat Mar 9 2013 Conrad Meyer - 2.5.0-1 +- Bump to latest upstream (#883822) +- Rebase gtest, maven patches on 2.5.0 + +* Tue Feb 26 2013 Conrad Meyer - 2.4.1-12 +- Nuke BR on maven-doxia, maven-doxia-sitetools (#915620) + +* Thu Feb 14 2013 Fedora Release Engineering - 2.4.1-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Wed Feb 06 2013 Java SIG - 2.4.1-10 +- Update for https://fedoraproject.org/wiki/Fedora_19_Maven_Rebuild +- Replace maven BuildRequires with maven-local + +* Sun Jan 20 2013 Conrad Meyer - 2.4.1-9 +- Fix packaging bug, -emacs-el subpackage should depend on -emacs subpackage of + the same version (%%version), not the emacs version number... + +* Thu Jan 17 2013 Tim Niemueller - 2.4.1-8 +- Added sub-package for Emacs editing mode + +* Sat Jul 21 2012 Fedora Release Engineering - 2.4.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Mar 19 2012 Dan Horák - 2.4.1-6 +- disable test-suite until g++ 4.7 issues are resolved + +* Mon Mar 19 2012 Stanislav Ochotnicky - 2.4.1-5 +- Update to latest java packaging guidelines + +* Tue Feb 28 2012 Fedora Release Engineering - 2.4.1-4 +- Rebuilt for c++ ABI breakage + +* Sat Jan 14 2012 Fedora Release Engineering - 2.4.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Sep 27 2011 Pierre-Yves Chibon - 2.4.1-2 +- Adding zlib-devel as BR (rhbz: #732087) + +* Thu Jun 09 2011 BJ Dierkes - 2.4.1-1 +- Latest sources from upstream. +- Rewrote Patch2 as protobuf-2.4.1-java-fixes.patch + +* Wed Feb 09 2011 Fedora Release Engineering - 2.3.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Jan 13 2011 Stanislav Ochotnicky - 2.3.0-6 +- Fix java subpackage bugs #669345 and #669346 +- Use new maven plugin names +- Use mavenpomdir macro for pom installation + +* Mon Jul 26 2010 David Malcolm - 2.3.0-5 +- generalize hardcoded reference to 2.6 in python subpackage %%files manifest + +* Wed Jul 21 2010 David Malcolm - 2.3.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Thu Jul 15 2010 James Laska - 2.3.0-3 +- Correct use of %%bcond macros + +* Wed Jul 14 2010 James Laska - 2.3.0-2 +- Enable python and java sub-packages + +* Tue May 4 2010 Conrad Meyer - 2.3.0-1 +- bump to 2.3.0