diff options
| author | Ari Parkkila <ari.parkkila@qt.io> | 2025-08-19 12:22:16 +0300 |
|---|---|---|
| committer | Ari Parkkila <ari.parkkila@qt.io> | 2025-08-20 10:47:19 +0300 |
| commit | e24900fa2dc599f390ac89118834d7e13261c1d4 (patch) | |
| tree | 7cc86015d63da43e8c019c77d9e9040c7b038e76 | |
| parent | df86e9d3670b3ed6a5c7f420bb9edc4815c05de7 (diff) | |
Add protobuf 4.25.3 as workaround
The meta-openembbeded layer updated protobuf to 4.25.8 but
qcom-sensors-core has binary dependency to version 4.25.3
so add that as workaround until fixed upstream.
Fixes: QTBUG-139276
Change-Id: I6e51b7d91d74f6aa083ade1511a5dfaa480fd7c8
Reviewed-by: Samuli Piippo <samuli.piippo@qt.io>
8 files changed, 1227 insertions, 0 deletions
diff --git a/recipes-devtools/protobuf/protobuf-c/0001-Makefile.am-do-not-compile-the-code-which-was-genera.patch b/recipes-devtools/protobuf/protobuf-c/0001-Makefile.am-do-not-compile-the-code-which-was-genera.patch new file mode 100644 index 0000000..896a568 --- /dev/null +++ b/recipes-devtools/protobuf/protobuf-c/0001-Makefile.am-do-not-compile-the-code-which-was-genera.patch @@ -0,0 +1,106 @@ +From 62b2fd0a150133b6439f6537cb1762d35f5790ee Mon Sep 17 00:00:00 2001 +From: Xiangyu Chen <xiangyu.chen@windriver.com> +Date: Fri, 31 Mar 2023 16:02:50 +0800 +Subject: [PATCH] Makefile.am: do not compile the code which was generated from + test-full.proto in protobuf-c-native + +Those code was auto generated by protoc command with test-full.proto, those code are not compatible +with protobuf 4.22.x, so temporarily disable compile those code until protobuf-c upstream adapt +the test-full.proto with latest version protobuf. + +Upstream-Status: Inappropriate [oe specific] + +Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com> +--- + Makefile.am | 75 ----------------------------------------------------- + 1 file changed, 75 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index ff12664..7412aef 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -136,81 +136,6 @@ else + + LOG_COMPILER = $(VALGRIND) + +-check_PROGRAMS += \ +- t/generated-code/test-generated-code \ +- t/generated-code2/test-generated-code2 \ +- t/generated-code3/test-generated-code3 \ +- t/version/version +- +-TESTS += \ +- t/generated-code/test-generated-code \ +- t/generated-code2/test-generated-code2 \ +- t/generated-code3/test-generated-code3 \ +- t/version/version +- +-t_generated_code_test_generated_code_SOURCES = \ +- t/generated-code/test-generated-code.c \ +- t/test.pb-c.c +-t_generated_code_test_generated_code_LDADD = \ +- protobuf-c/libprotobuf-c.la +- +-t_generated_code2_test_generated_code2_SOURCES = \ +- t/generated-code2/test-generated-code2.c \ +- t/test-full.pb-c.c \ +- t/test-optimized.pb-c.c +-t_generated_code2_test_generated_code2_LDADD = \ +- protobuf-c/libprotobuf-c.la +- +-t_generated_code3_test_generated_code3_CPPFLAGS = \ +- -DPROTO3 +- +-t_generated_code3_test_generated_code3_SOURCES = \ +- t/generated-code/test-generated-code.c \ +- t/test-proto3.pb-c.c +- +-t_generated_code3_test_generated_code3_LDADD = \ +- protobuf-c/libprotobuf-c.la +- +-noinst_PROGRAMS += \ +- t/generated-code2/cxx-generate-packed-data +- +-t_generated_code2_cxx_generate_packed_data_SOURCES = \ +- t/generated-code2/cxx-generate-packed-data.cc \ +- t/test-full.pb.cc \ +- protobuf-c/protobuf-c.pb.cc +-$(t_generated_code2_cxx_generate_packed_data_OBJECTS): t/test-full.pb.h +-t_generated_code2_cxx_generate_packed_data_CXXFLAGS = \ +- $(AM_CXXFLAGS) \ +- $(protobuf_CFLAGS) +-t_generated_code2_cxx_generate_packed_data_LDADD = \ +- $(protobuf_LIBS) +- +-t/test.pb-c.c t/test.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/test.proto +- $(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/test.proto +- +-t/test-optimized.pb-c.c t/test-optimized.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/test-optimized.proto +- $(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/test-optimized.proto +- +-t/test-full.pb-c.c t/test-full.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/test-full.proto +- $(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/test-full.proto +- +-t/test-full.pb.cc t/test-full.pb.h: @PROTOC@ $(top_srcdir)/t/test-full.proto +- $(AM_V_GEN)@PROTOC@ -I$(top_srcdir) --cpp_out=$(top_builddir) $(top_srcdir)/t/test-full.proto +- +-t/test-proto3.pb-c.c t/test-proto3.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/test-proto3.proto +- $(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/test-proto3.proto +- +-t/generated-code2/test-full-cxx-output.inc: t/generated-code2/cxx-generate-packed-data$(EXEEXT) +- $(AM_V_GEN)$(top_builddir)/t/generated-code2/cxx-generate-packed-data$(EXEEXT) > $(top_builddir)/t/generated-code2/test-full-cxx-output.inc +- +-BUILT_SOURCES += \ +- t/test.pb-c.c t/test.pb-c.h \ +- t/test-full.pb-c.c t/test-full.pb-c.h \ +- t/test-optimized.pb-c.c t/test-optimized.pb-c.h \ +- t/test-full.pb.cc t/test-full.pb.h \ +- t/test-proto3.pb-c.c t/test-proto3.pb-c.h \ +- t/generated-code2/test-full-cxx-output.inc +- + t_version_version_SOURCES = \ + t/version/version.c + t_version_version_LDADD = \ +-- +2.34.1 + diff --git a/recipes-devtools/protobuf/protobuf-c_1.5.0.bb b/recipes-devtools/protobuf/protobuf-c_1.5.0.bb new file mode 100644 index 0000000..24de6b8 --- /dev/null +++ b/recipes-devtools/protobuf/protobuf-c_1.5.0.bb @@ -0,0 +1,38 @@ +SUMMARY = "Protocol Buffers - structured data serialisation mechanism" +DESCRIPTION = "This is protobuf-c, a C implementation of the Google Protocol Buffers data \ +serialization format. It includes libprotobuf-c, a pure C library that \ +implements protobuf encoding and decoding, and protoc-c, a code generator that \ +converts Protocol Buffer .proto files to C descriptor code, based on the \ +original protoc. protobuf-c formerly included an RPC implementation; that code \ +has been split out into the protobuf-c-rpc project." +HOMEPAGE = "https://github.com/protobuf-c/protobuf-c" +SECTION = "console/tools" +LICENSE = "BSD-2-Clause" +LIC_FILES_CHKSUM = "file://LICENSE;md5=d11077c6a2b5d2e64b9f32b61a9b78ba" + +DEPENDS = "protobuf-native protobuf" + +SRC_URI = "git://github.com/protobuf-c/protobuf-c.git;branch=master;protocol=https" +SRC_URI:append:class-native = " file://0001-Makefile.am-do-not-compile-the-code-which-was-genera.patch" + +SRCREV = "8c201f6e47a53feaab773922a743091eb6c8972a" + +S = "${WORKDIR}/git" + +inherit autotools pkgconfig + +export PROTOC = "${STAGING_BINDIR_NATIVE}/protoc" + +# After several fix attempts there is still a race between generating +# t.test-full.pb.h and compiling cxx_generate_packed_data.c despite +# BUILT_SOURCES and explicit dependencies. +PARALLEL_MAKE = "" + +PACKAGE_BEFORE_PN = "${PN}-compiler" + +FILES:${PN}-compiler = "${bindir}" + +RDEPENDS:${PN}-compiler = "protobuf-compiler" +RDEPENDS:${PN}-dev += "${PN}-compiler" + +BBCLASSEXTEND = "native nativesdk" diff --git a/recipes-devtools/protobuf/protobuf/0001-Add-recursion-check-when-parsing-unknown-fields-in-J.patch b/recipes-devtools/protobuf/protobuf/0001-Add-recursion-check-when-parsing-unknown-fields-in-J.patch new file mode 100644 index 0000000..2f14620 --- /dev/null +++ b/recipes-devtools/protobuf/protobuf/0001-Add-recursion-check-when-parsing-unknown-fields-in-J.patch @@ -0,0 +1,794 @@ +From 9f182ae260cc60e8cc5417abbe9481821642afa0 Mon Sep 17 00:00:00 2001 +From: Protobuf Team Bot <protobuf-github-bot@google.com> +Date: Tue, 17 Sep 2024 12:03:36 -0700 +Subject: [PATCH] Add recursion check when parsing unknown fields in Java. + +PiperOrigin-RevId: 675657198 + +CVE: CVE-2024-7254 + +Upstream-Status: Backport [ac9fb5b4c71b0dd80985b27684e265d1f03abf46] + +The original patch is adjusted to fit for the current version. + +Signed-off-by: Chen Qi <Qi.Chen@windriver.com> +--- + .../com/google/protobuf/ArrayDecoders.java | 28 +++ + .../com/google/protobuf/CodedInputStream.java | 72 +++++- + .../com/google/protobuf/MessageSchema.java | 9 +- + .../com/google/protobuf/MessageSetSchema.java | 2 +- + .../google/protobuf/UnknownFieldSchema.java | 28 ++- + .../google/protobuf/CodedInputStreamTest.java | 159 ++++++++++++ + .../java/com/google/protobuf/LiteTest.java | 232 ++++++++++++++++++ + 7 files changed, 514 insertions(+), 16 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 f3241de50..0f3d7de0d 100644 +--- a/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java ++++ b/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java +@@ -26,6 +26,10 @@ final class ArrayDecoders { + + private ArrayDecoders() { + } ++ static final int DEFAULT_RECURSION_LIMIT = 100; ++ ++ @SuppressWarnings("NonFinalStaticField") ++ private static volatile int recursionLimit = DEFAULT_RECURSION_LIMIT; + + /** + * A helper used to return multiple values in a Java function. Java doesn't natively support +@@ -38,6 +42,7 @@ final class ArrayDecoders { + public long long1; + public Object object1; + public final ExtensionRegistryLite extensionRegistry; ++ public int recursionDepth; + + Registers() { + this.extensionRegistry = ExtensionRegistryLite.getEmptyRegistry(); +@@ -245,7 +250,10 @@ final class ArrayDecoders { + if (length < 0 || length > limit - position) { + throw InvalidProtocolBufferException.truncatedMessage(); + } ++ registers.recursionDepth++; ++ checkRecursionLimit(registers.recursionDepth); + schema.mergeFrom(msg, data, position, position + length, registers); ++ registers.recursionDepth--; + registers.object1 = msg; + return position + length; + } +@@ -263,8 +271,11 @@ final class ArrayDecoders { + // A group field must has a MessageSchema (the only other subclass of Schema is MessageSetSchema + // and it can't be used in group fields). + final MessageSchema messageSchema = (MessageSchema) schema; ++ registers.recursionDepth++; ++ checkRecursionLimit(registers.recursionDepth); + final int endPosition = + messageSchema.parseMessage(msg, data, position, limit, endGroup, registers); ++ registers.recursionDepth--; + registers.object1 = msg; + return endPosition; + } +@@ -1025,6 +1036,8 @@ final class ArrayDecoders { + final UnknownFieldSetLite child = UnknownFieldSetLite.newInstance(); + final int endGroup = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP; + int lastTag = 0; ++ registers.recursionDepth++; ++ checkRecursionLimit(registers.recursionDepth); + while (position < limit) { + position = decodeVarint32(data, position, registers); + lastTag = registers.int1; +@@ -1033,6 +1046,7 @@ final class ArrayDecoders { + } + position = decodeUnknownField(lastTag, data, position, limit, child, registers); + } ++ registers.recursionDepth--; + if (position > limit || lastTag != endGroup) { + throw InvalidProtocolBufferException.parseFailure(); + } +@@ -1079,4 +1093,18 @@ final class ArrayDecoders { + throw InvalidProtocolBufferException.invalidTag(); + } + } ++ ++ /** ++ * Set the maximum recursion limit that ArrayDecoders will allow. An exception will be thrown if ++ * the depth of the message exceeds this limit. ++ */ ++ public static void setRecursionLimit(int limit) { ++ recursionLimit = limit; ++ } ++ ++ private static void checkRecursionLimit(int depth) throws InvalidProtocolBufferException { ++ if (depth >= recursionLimit) { ++ throw InvalidProtocolBufferException.recursionLimitExceeded(); ++ } ++ } + } +diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +index 8f1ac736d..29256b4b3 100644 +--- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java ++++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +@@ -703,7 +703,14 @@ public abstract class CodedInputStream { + public void skipMessage() throws IOException { + while (true) { + final int tag = readTag(); +- if (tag == 0 || !skipField(tag)) { ++ if (tag == 0) { ++ return; ++ } ++ checkRecursionLimit(); ++ ++recursionDepth; ++ boolean fieldSkipped = skipField(tag); ++ --recursionDepth; ++ if (!fieldSkipped) { + return; + } + } +@@ -713,7 +720,14 @@ public abstract class CodedInputStream { + public void skipMessage(CodedOutputStream output) throws IOException { + while (true) { + final int tag = readTag(); +- if (tag == 0 || !skipField(tag, output)) { ++ if (tag == 0) { ++ return; ++ } ++ checkRecursionLimit(); ++ ++recursionDepth; ++ boolean fieldSkipped = skipField(tag, output); ++ --recursionDepth; ++ if (!fieldSkipped) { + return; + } + } +@@ -1415,7 +1429,14 @@ public abstract class CodedInputStream { + public void skipMessage() throws IOException { + while (true) { + final int tag = readTag(); +- if (tag == 0 || !skipField(tag)) { ++ if (tag == 0) { ++ return; ++ } ++ checkRecursionLimit(); ++ ++recursionDepth; ++ boolean fieldSkipped = skipField(tag); ++ --recursionDepth; ++ if (!fieldSkipped) { + return; + } + } +@@ -1425,7 +1446,14 @@ public abstract class CodedInputStream { + public void skipMessage(CodedOutputStream output) throws IOException { + while (true) { + final int tag = readTag(); +- if (tag == 0 || !skipField(tag, output)) { ++ if (tag == 0) { ++ return; ++ } ++ checkRecursionLimit(); ++ ++recursionDepth; ++ boolean fieldSkipped = skipField(tag, output); ++ --recursionDepth; ++ if (!fieldSkipped) { + return; + } + } +@@ -2180,7 +2208,14 @@ public abstract class CodedInputStream { + public void skipMessage() throws IOException { + while (true) { + final int tag = readTag(); +- if (tag == 0 || !skipField(tag)) { ++ if (tag == 0) { ++ return; ++ } ++ checkRecursionLimit(); ++ ++recursionDepth; ++ boolean fieldSkipped = skipField(tag); ++ --recursionDepth; ++ if (!fieldSkipped) { + return; + } + } +@@ -2190,7 +2225,14 @@ public abstract class CodedInputStream { + public void skipMessage(CodedOutputStream output) throws IOException { + while (true) { + final int tag = readTag(); +- if (tag == 0 || !skipField(tag, output)) { ++ if (tag == 0) { ++ return; ++ } ++ checkRecursionLimit(); ++ ++recursionDepth; ++ boolean fieldSkipped = skipField(tag, output); ++ --recursionDepth; ++ if (!fieldSkipped) { + return; + } + } +@@ -3298,7 +3340,14 @@ public abstract class CodedInputStream { + public void skipMessage() throws IOException { + while (true) { + final int tag = readTag(); +- if (tag == 0 || !skipField(tag)) { ++ if (tag == 0) { ++ return; ++ } ++ checkRecursionLimit(); ++ ++recursionDepth; ++ boolean fieldSkipped = skipField(tag); ++ --recursionDepth; ++ if (!fieldSkipped) { + return; + } + } +@@ -3308,7 +3357,14 @@ public abstract class CodedInputStream { + public void skipMessage(CodedOutputStream output) throws IOException { + while (true) { + final int tag = readTag(); +- if (tag == 0 || !skipField(tag, output)) { ++ if (tag == 0) { ++ return; ++ } ++ checkRecursionLimit(); ++ ++recursionDepth; ++ boolean fieldSkipped = skipField(tag, output); ++ --recursionDepth; ++ if (!fieldSkipped) { + return; + } + } +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 de3890f70..5ad6762b0 100644 +--- a/java/core/src/main/java/com/google/protobuf/MessageSchema.java ++++ b/java/core/src/main/java/com/google/protobuf/MessageSchema.java +@@ -3006,7 +3006,8 @@ final class MessageSchema<T> implements Schema<T> { + unknownFields = unknownFieldSchema.getBuilderFromMessage(message); + } + // Unknown field. +- if (unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) { ++ if (unknownFieldSchema.mergeOneFieldFrom( ++ unknownFields, reader, /* currentDepth= */ 0)) { + continue; + } + } +@@ -3381,7 +3382,8 @@ final class MessageSchema<T> implements Schema<T> { + if (unknownFields == null) { + unknownFields = unknownFieldSchema.getBuilderFromMessage(message); + } +- if (!unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) { ++ if (!unknownFieldSchema.mergeOneFieldFrom( ++ unknownFields, reader, /* currentDepth= */ 0)) { + return; + } + break; +@@ -3397,7 +3399,8 @@ final class MessageSchema<T> implements Schema<T> { + if (unknownFields == null) { + unknownFields = unknownFieldSchema.getBuilderFromMessage(message); + } +- if (!unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) { ++ if (!unknownFieldSchema.mergeOneFieldFrom( ++ unknownFields, reader, /* currentDepth= */ 0)) { + 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 eec3acd35..ec37d41f9 100644 +--- a/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java ++++ b/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java +@@ -278,7 +278,7 @@ final class MessageSetSchema<T> implements Schema<T> { + reader, extension, extensionRegistry, extensions); + return true; + } else { +- return unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader); ++ return unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader, /* currentDepth= */ 0); + } + } else { + return reader.skipField(); +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 c4ec645bf..0cdecd30e 100644 +--- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java ++++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java +@@ -13,6 +13,11 @@ import java.io.IOException; + @CheckReturnValue + abstract class UnknownFieldSchema<T, B> { + ++ static final int DEFAULT_RECURSION_LIMIT = 100; ++ ++ @SuppressWarnings("NonFinalStaticField") ++ private static volatile int recursionLimit = DEFAULT_RECURSION_LIMIT; ++ + /** Whether unknown fields should be dropped. */ + abstract boolean shouldDiscardUnknownFields(Reader reader); + +@@ -56,7 +61,8 @@ abstract class UnknownFieldSchema<T, B> { + abstract void makeImmutable(Object message); + + /** Merges one field into the unknown fields. */ +- final boolean mergeOneFieldFrom(B unknownFields, Reader reader) throws IOException { ++ final boolean mergeOneFieldFrom(B unknownFields, Reader reader, int currentDepth) ++ throws IOException { + int tag = reader.getTag(); + int fieldNumber = WireFormat.getTagFieldNumber(tag); + switch (WireFormat.getTagWireType(tag)) { +@@ -75,7 +81,12 @@ abstract class UnknownFieldSchema<T, B> { + case WireFormat.WIRETYPE_START_GROUP: + final B subFields = newBuilder(); + int endGroupTag = WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP); +- mergeFrom(subFields, reader); ++ currentDepth++; ++ if (currentDepth >= recursionLimit) { ++ throw InvalidProtocolBufferException.recursionLimitExceeded(); ++ } ++ mergeFrom(subFields, reader, currentDepth); ++ currentDepth--; + if (endGroupTag != reader.getTag()) { + throw InvalidProtocolBufferException.invalidEndTag(); + } +@@ -88,10 +99,11 @@ abstract class UnknownFieldSchema<T, B> { + } + } + +- final void mergeFrom(B unknownFields, Reader reader) throws IOException { ++ final void mergeFrom(B unknownFields, Reader reader, int currentDepth) ++ throws IOException { + while (true) { + if (reader.getFieldNumber() == Reader.READ_DONE +- || !mergeOneFieldFrom(unknownFields, reader)) { ++ || !mergeOneFieldFrom(unknownFields, reader, currentDepth)) { + break; + } + } +@@ -108,4 +120,12 @@ abstract class UnknownFieldSchema<T, B> { + abstract int getSerializedSizeAsMessageSet(T message); + + abstract int getSerializedSize(T unknowns); ++ ++ /** ++ * Set the maximum recursion limit that ArrayDecoders will allow. An exception will be thrown if ++ * the depth of the message exceeds this limit. ++ */ ++ public void setRecursionLimit(int limit) { ++ recursionLimit = limit; ++ } + } +diff --git a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java +index 2de3273e3..19a6b669d 100644 +--- a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java ++++ b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java +@@ -10,6 +10,10 @@ package com.google.protobuf; + import static com.google.common.truth.Truth.assertThat; + import static com.google.common.truth.Truth.assertWithMessage; + import static org.junit.Assert.assertArrayEquals; ++import static org.junit.Assert.assertThrows; ++ ++import com.google.common.primitives.Bytes; ++import map_test.MapTestProto.MapContainer; + import protobuf_unittest.UnittestProto.BoolMessage; + import protobuf_unittest.UnittestProto.Int32Message; + import protobuf_unittest.UnittestProto.Int64Message; +@@ -34,6 +38,13 @@ public class CodedInputStreamTest { + + private static final int DEFAULT_BLOCK_SIZE = 4096; + ++ private static final int GROUP_TAP = WireFormat.makeTag(3, WireFormat.WIRETYPE_START_GROUP); ++ ++ private static final byte[] NESTING_SGROUP = generateSGroupTags(); ++ ++ private static final byte[] NESTING_SGROUP_WITH_INITIAL_BYTES = generateSGroupTagsForMapField(); ++ ++ + private enum InputType { + ARRAY { + @Override +@@ -116,6 +127,17 @@ public class CodedInputStreamTest { + return bytes; + } + ++ private static byte[] generateSGroupTags() { ++ byte[] bytes = new byte[100000]; ++ Arrays.fill(bytes, (byte) GROUP_TAP); ++ return bytes; ++ } ++ ++ private static byte[] generateSGroupTagsForMapField() { ++ byte[] initialBytes = {18, 1, 75, 26, (byte) 198, (byte) 154, 12}; ++ return Bytes.concat(initialBytes, NESTING_SGROUP); ++ } ++ + /** + * An InputStream which limits the number of bytes it reads at a time. We use this to make sure + * that CodedInputStream doesn't screw up when reading in small blocks. +@@ -659,6 +681,143 @@ public class CodedInputStreamTest { + } + } + ++ @Test ++ public void testMaliciousRecursion_unknownFields() throws Exception { ++ Throwable thrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> TestRecursiveMessage.parseFrom(NESTING_SGROUP)); ++ ++ assertThat(thrown).hasMessageThat().contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testMaliciousRecursion_skippingUnknownField() throws Exception { ++ Throwable thrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> ++ DiscardUnknownFieldsParser.wrap(TestRecursiveMessage.parser()) ++ .parseFrom(NESTING_SGROUP)); ++ ++ assertThat(thrown).hasMessageThat().contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testMaliciousSGroupTagsWithMapField_fromInputStream() throws Exception { ++ Throwable parseFromThrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> ++ MapContainer.parseFrom( ++ new ByteArrayInputStream(NESTING_SGROUP_WITH_INITIAL_BYTES))); ++ Throwable mergeFromThrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> ++ MapContainer.newBuilder() ++ .mergeFrom(new ByteArrayInputStream(NESTING_SGROUP_WITH_INITIAL_BYTES))); ++ ++ assertThat(parseFromThrown) ++ .hasMessageThat() ++ .contains("Protocol message had too many levels of nesting"); ++ assertThat(mergeFromThrown) ++ .hasMessageThat() ++ .contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testMaliciousSGroupTags_inputStream_skipMessage() throws Exception { ++ ByteArrayInputStream inputSteam = new ByteArrayInputStream(NESTING_SGROUP); ++ CodedInputStream input = CodedInputStream.newInstance(inputSteam); ++ CodedOutputStream output = CodedOutputStream.newInstance(new byte[NESTING_SGROUP.length]); ++ ++ Throwable thrown = assertThrows(InvalidProtocolBufferException.class, input::skipMessage); ++ Throwable thrown2 = ++ assertThrows(InvalidProtocolBufferException.class, () -> input.skipMessage(output)); ++ ++ assertThat(thrown).hasMessageThat().contains("Protocol message had too many levels of nesting"); ++ assertThat(thrown2) ++ .hasMessageThat() ++ .contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testMaliciousSGroupTagsWithMapField_fromByteArray() throws Exception { ++ Throwable parseFromThrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> MapContainer.parseFrom(NESTING_SGROUP_WITH_INITIAL_BYTES)); ++ Throwable mergeFromThrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> MapContainer.newBuilder().mergeFrom(NESTING_SGROUP_WITH_INITIAL_BYTES)); ++ ++ assertThat(parseFromThrown) ++ .hasMessageThat() ++ .contains("the input ended unexpectedly in the middle of a field"); ++ assertThat(mergeFromThrown) ++ .hasMessageThat() ++ .contains("the input ended unexpectedly in the middle of a field"); ++ } ++ ++ @Test ++ public void testMaliciousSGroupTags_arrayDecoder_skipMessage() throws Exception { ++ CodedInputStream input = CodedInputStream.newInstance(NESTING_SGROUP); ++ CodedOutputStream output = CodedOutputStream.newInstance(new byte[NESTING_SGROUP.length]); ++ ++ Throwable thrown = assertThrows(InvalidProtocolBufferException.class, input::skipMessage); ++ Throwable thrown2 = ++ assertThrows(InvalidProtocolBufferException.class, () -> input.skipMessage(output)); ++ ++ assertThat(thrown).hasMessageThat().contains("Protocol message had too many levels of nesting"); ++ assertThat(thrown2) ++ .hasMessageThat() ++ .contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testMaliciousSGroupTagsWithMapField_fromByteBuffer() throws Exception { ++ Throwable thrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> MapContainer.parseFrom(ByteBuffer.wrap(NESTING_SGROUP_WITH_INITIAL_BYTES))); ++ ++ assertThat(thrown) ++ .hasMessageThat() ++ .contains("the input ended unexpectedly in the middle of a field"); ++ } ++ ++ @Test ++ public void testMaliciousSGroupTags_byteBuffer_skipMessage() throws Exception { ++ CodedInputStream input = InputType.NIO_DIRECT.newDecoder(NESTING_SGROUP); ++ CodedOutputStream output = CodedOutputStream.newInstance(new byte[NESTING_SGROUP.length]); ++ ++ Throwable thrown = assertThrows(InvalidProtocolBufferException.class, input::skipMessage); ++ Throwable thrown2 = ++ assertThrows(InvalidProtocolBufferException.class, () -> input.skipMessage(output)); ++ ++ assertThat(thrown).hasMessageThat().contains("Protocol message had too many levels of nesting"); ++ assertThat(thrown2) ++ .hasMessageThat() ++ .contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testMaliciousSGroupTags_iterableByteBuffer() throws Exception { ++ CodedInputStream input = InputType.ITER_DIRECT.newDecoder(NESTING_SGROUP); ++ CodedOutputStream output = CodedOutputStream.newInstance(new byte[NESTING_SGROUP.length]); ++ ++ Throwable thrown = assertThrows(InvalidProtocolBufferException.class, input::skipMessage); ++ Throwable thrown2 = ++ assertThrows(InvalidProtocolBufferException.class, () -> input.skipMessage(output)); ++ ++ assertThat(thrown).hasMessageThat().contains("Protocol message had too many levels of nesting"); ++ assertThat(thrown2) ++ .hasMessageThat() ++ .contains("Protocol message had too many levels of nesting"); ++ } ++ + private void checkSizeLimitExceeded(InvalidProtocolBufferException e) { + assertThat(e) + .hasMessageThat() +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 754ed7d5f..81be90bfd 100644 +--- a/java/lite/src/test/java/com/google/protobuf/LiteTest.java ++++ b/java/lite/src/test/java/com/google/protobuf/LiteTest.java +@@ -2459,6 +2459,211 @@ public class LiteTest { + } + } + ++ @Test ++ public void testParseFromInputStream_concurrent_nestingUnknownGroups() throws Exception { ++ int numThreads = 200; ++ ArrayList<Thread> threads = new ArrayList<>(); ++ ++ ByteString byteString = generateNestingGroups(99); ++ AtomicBoolean thrown = new AtomicBoolean(false); ++ ++ for (int i = 0; i < numThreads; i++) { ++ Thread thread = ++ new Thread( ++ () -> { ++ try { ++ TestAllTypesLite unused = TestAllTypesLite.parseFrom(byteString); ++ } catch (IOException e) { ++ if (e.getMessage().contains("Protocol message had too many levels of nesting")) { ++ thrown.set(true); ++ } ++ } ++ }); ++ thread.start(); ++ threads.add(thread); ++ } ++ ++ for (Thread thread : threads) { ++ thread.join(); ++ } ++ ++ assertThat(thrown.get()).isFalse(); ++ } ++ ++ @Test ++ public void testParseFromInputStream_nestingUnknownGroups() throws IOException { ++ ByteString byteString = generateNestingGroups(99); ++ ++ Throwable thrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, () -> TestAllTypesLite.parseFrom(byteString)); ++ assertThat(thrown) ++ .hasMessageThat() ++ .doesNotContain("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testParseFromInputStream_nestingUnknownGroups_exception() throws IOException { ++ ByteString byteString = generateNestingGroups(100); ++ ++ Throwable thrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, () -> TestAllTypesLite.parseFrom(byteString)); ++ assertThat(thrown).hasMessageThat().contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testParseFromInputStream_setRecursionLimit_exception() throws IOException { ++ ByteString byteString = generateNestingGroups(199); ++ UnknownFieldSchema<?, ?> schema = SchemaUtil.unknownFieldSetLiteSchema(); ++ schema.setRecursionLimit(200); ++ ++ Throwable thrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, () -> TestAllTypesLite.parseFrom(byteString)); ++ assertThat(thrown) ++ .hasMessageThat() ++ .doesNotContain("Protocol message had too many levels of nesting"); ++ schema.setRecursionLimit(UnknownFieldSchema.DEFAULT_RECURSION_LIMIT); ++ } ++ ++ @Test ++ public void testParseFromBytes_concurrent_nestingUnknownGroups() throws Exception { ++ int numThreads = 200; ++ ArrayList<Thread> threads = new ArrayList<>(); ++ ++ ByteString byteString = generateNestingGroups(99); ++ AtomicBoolean thrown = new AtomicBoolean(false); ++ ++ for (int i = 0; i < numThreads; i++) { ++ Thread thread = ++ new Thread( ++ () -> { ++ try { ++ // Should pass in byte[] instead of ByteString to go into ArrayDecoders. ++ TestAllTypesLite unused = TestAllTypesLite.parseFrom(byteString.toByteArray()); ++ } catch (InvalidProtocolBufferException e) { ++ if (e.getMessage().contains("Protocol message had too many levels of nesting")) { ++ thrown.set(true); ++ } ++ } ++ }); ++ thread.start(); ++ threads.add(thread); ++ } ++ ++ for (Thread thread : threads) { ++ thread.join(); ++ } ++ ++ assertThat(thrown.get()).isFalse(); ++ } ++ ++ @Test ++ public void testParseFromBytes_nestingUnknownGroups() throws IOException { ++ ByteString byteString = generateNestingGroups(99); ++ ++ Throwable thrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> TestAllTypesLite.parseFrom(byteString.toByteArray())); ++ assertThat(thrown) ++ .hasMessageThat() ++ .doesNotContain("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testParseFromBytes_nestingUnknownGroups_exception() throws IOException { ++ ByteString byteString = generateNestingGroups(100); ++ ++ Throwable thrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> TestAllTypesLite.parseFrom(byteString.toByteArray())); ++ assertThat(thrown).hasMessageThat().contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testParseFromBytes_setRecursionLimit_exception() throws IOException { ++ ByteString byteString = generateNestingGroups(199); ++ ArrayDecoders.setRecursionLimit(200); ++ ++ Throwable thrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> TestAllTypesLite.parseFrom(byteString.toByteArray())); ++ assertThat(thrown) ++ .hasMessageThat() ++ .doesNotContain("Protocol message had too many levels of nesting"); ++ ArrayDecoders.setRecursionLimit(ArrayDecoders.DEFAULT_RECURSION_LIMIT); ++ } ++ ++ @Test ++ public void testParseFromBytes_recursiveMessages() throws Exception { ++ byte[] data99 = makeRecursiveMessage(99).toByteArray(); ++ byte[] data100 = makeRecursiveMessage(100).toByteArray(); ++ ++ RecursiveMessage unused = RecursiveMessage.parseFrom(data99); ++ Throwable thrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, () -> RecursiveMessage.parseFrom(data100)); ++ assertThat(thrown).hasMessageThat().contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testParseFromBytes_recursiveKnownGroups() throws Exception { ++ byte[] data99 = makeRecursiveGroup(99).toByteArray(); ++ byte[] data100 = makeRecursiveGroup(100).toByteArray(); ++ ++ RecursiveGroup unused = RecursiveGroup.parseFrom(data99); ++ Throwable thrown = ++ assertThrows(InvalidProtocolBufferException.class, () -> RecursiveGroup.parseFrom(data100)); ++ assertThat(thrown).hasMessageThat().contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ @SuppressWarnings("ProtoParseFromByteString") ++ public void testMaliciousSGroupTagsWithMapField_fromByteArray() throws Exception { ++ ByteString byteString = generateNestingGroups(102); ++ ++ Throwable parseFromThrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> MapContainer.parseFrom(byteString.toByteArray())); ++ Throwable mergeFromThrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> MapContainer.newBuilder().mergeFrom(byteString.toByteArray())); ++ ++ assertThat(parseFromThrown) ++ .hasMessageThat() ++ .contains("Protocol message had too many levels of nesting"); ++ assertThat(mergeFromThrown) ++ .hasMessageThat() ++ .contains("Protocol message had too many levels of nesting"); ++ } ++ ++ @Test ++ public void testMaliciousSGroupTagsWithMapField_fromInputStream() throws Exception { ++ byte[] bytes = generateNestingGroups(101).toByteArray(); ++ ++ Throwable parseFromThrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> MapContainer.parseFrom(new ByteArrayInputStream(bytes))); ++ Throwable mergeFromThrown = ++ assertThrows( ++ InvalidProtocolBufferException.class, ++ () -> MapContainer.newBuilder().mergeFrom(new ByteArrayInputStream(bytes))); ++ ++ assertThat(parseFromThrown) ++ .hasMessageThat() ++ .contains("Protocol message had too many levels of nesting"); ++ assertThat(mergeFromThrown) ++ .hasMessageThat() ++ .contains("Protocol message had too many levels of nesting"); ++ } ++ + @Test + public void testParseFromByteBuffer_extensions() throws Exception { + TestAllExtensionsLite message = +@@ -2815,4 +3020,31 @@ public class LiteTest { + } + return false; + } ++ ++ private static ByteString generateNestingGroups(int num) throws IOException { ++ int groupTap = WireFormat.makeTag(3, WireFormat.WIRETYPE_START_GROUP); ++ ByteString.Output byteStringOutput = ByteString.newOutput(); ++ CodedOutputStream codedOutput = CodedOutputStream.newInstance(byteStringOutput); ++ for (int i = 0; i < num; i++) { ++ codedOutput.writeInt32NoTag(groupTap); ++ } ++ codedOutput.flush(); ++ return byteStringOutput.toByteString(); ++ } ++ ++ private static RecursiveMessage makeRecursiveMessage(int num) { ++ if (num == 0) { ++ return RecursiveMessage.getDefaultInstance(); ++ } else { ++ return RecursiveMessage.newBuilder().setRecurse(makeRecursiveMessage(num - 1)).build(); ++ } ++ } ++ ++ private static RecursiveGroup makeRecursiveGroup(int num) { ++ if (num == 0) { ++ return RecursiveGroup.getDefaultInstance(); ++ } else { ++ return RecursiveGroup.newBuilder().setRecurse(makeRecursiveGroup(num - 1)).build(); ++ } ++ } + } +-- +2.25.1 + diff --git a/recipes-devtools/protobuf/protobuf/0001-Fix-build-on-mips-clang.patch b/recipes-devtools/protobuf/protobuf/0001-Fix-build-on-mips-clang.patch new file mode 100644 index 0000000..9f6116c --- /dev/null +++ b/recipes-devtools/protobuf/protobuf/0001-Fix-build-on-mips-clang.patch @@ -0,0 +1,26 @@ +From 08e46feb6553af670754e65d94c3bb6fcd4e0cf9 Mon Sep 17 00:00:00 2001 +From: Khem Raj <raj.khem@gmail.com> +Date: Sun, 31 Oct 2021 23:39:44 -0700 +Subject: [PATCH] Fix build on mips/clang + +clang13 crashes on mips, until its fixed upstream disable tailcall on +mips + +https://bugs.llvm.org/show_bug.cgi?id=52367 + +Upstream-Status: Inappropriate [Clang workaround] +Signed-off-by: Khem Raj <raj.khem@gmail.com> +--- + src/google/protobuf/port_def.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/src/google/protobuf/port_def.inc ++++ b/src/google/protobuf/port_def.inc +@@ -255,6 +255,7 @@ + #error PROTOBUF_TAILCALL was previously defined + #endif + #if __has_cpp_attribute(clang::musttail) && !defined(__arm__) && \ ++ !defined(__mips__) && \ + !defined(_ARCH_PPC) && !defined(__wasm__) && \ + !(defined(_MSC_VER) && defined(_M_IX86)) && \ + !(defined(__NDK_MAJOR__) && __NDK_MAJOR <= 24) diff --git a/recipes-devtools/protobuf/protobuf/0001-examples-Makefile-respect-CXX-LDFLAGS-variables-fix-.patch b/recipes-devtools/protobuf/protobuf/0001-examples-Makefile-respect-CXX-LDFLAGS-variables-fix-.patch new file mode 100644 index 0000000..7c4bf26 --- /dev/null +++ b/recipes-devtools/protobuf/protobuf/0001-examples-Makefile-respect-CXX-LDFLAGS-variables-fix-.patch @@ -0,0 +1,61 @@ +From e3fa241637ab5a7fa78c0d474802134cff75f91e Mon Sep 17 00:00:00 2001 +From: Martin Jansa <Martin.Jansa@gmail.com> +Date: Fri, 28 Jun 2019 13:50:52 +0000 +Subject: [PATCH] examples/Makefile: respect CXX,LDFLAGS variables, fix build + with gold + +* move pkg-config call to separate variable, so that the final version + of the whole command so it's shown in log.do_compile_ptest_base +* add ../src/google/protobuf/.libs/timestamp.pb.o when linking + add_person_cpp otherwise it fails to link with gold: + i686-oe-linux-g++ -m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse --sysroot=core2-32-oe-linux/protobuf/3.8.0-r0/recipe-sysroot -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed add_person.cc addressbook.pb.cc -o add_person_cpp `pkg-config --cflags --libs protobuf` + /tmp/cccjSJQs.o:addressbook.pb.cc:scc_info_Person_addressbook_2eproto: error: undefined reference to 'scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto' + /tmp/cccjSJQs.o:addressbook.pb.cc:descriptor_table_addressbook_2eproto_deps: error: undefined reference to 'descriptor_table_google_2fprotobuf_2ftimestamp_2eproto' + collect2: error: ld returned 1 exit status + Makefile:43: recipe for target 'add_person_cpp' failed + +* and the same with list_people_cpp this time with pkg-config already through the variable: + i686-oe-linux-g++ -m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse --sysroot=core2-32-oe-linux/protobuf/3.8.0-r0/recipe-sysroot -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -pthread -Icore2-32-oe-linux/protobuf/3.8.0-r0/git/src -Lcore2-32-oe-linux/protobuf/3.8.0-r0/git/src/.libs -Lcore2-32-oe-linux/protobuf/3.8.0-r0/recipe-sysroot/usr/lib -lprotobuf list_people.cc addressbook.pb.cc -o list_people_cpp + /tmp/ccpaI5Su.o:addressbook.pb.cc:scc_info_Person_addressbook_2eproto: error: undefined reference to 'scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto' + /tmp/ccpaI5Su.o:addressbook.pb.cc:descriptor_table_addressbook_2eproto_deps: error: undefined reference to 'descriptor_table_google_2fprotobuf_2ftimestamp_2eproto' + collect2: error: ld returned 1 exit status + Makefile:49: recipe for target 'list_people_cpp' failed + +Upstream-Status: Pending +Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com> +Signed-off-by: Leon Anavi <leon.anavi@konsulko.com> + +--- + examples/Makefile | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/examples/Makefile b/examples/Makefile +index ef7a4ef58..7206e14e1 100644 +--- a/examples/Makefile ++++ b/examples/Makefile +@@ -2,6 +2,8 @@ + + .PHONY: all cpp java python clean + ++PROTOBUF := $(shell pkg-config --cflags --libs protobuf) ++ + all: cpp java python + + cpp: add_person_cpp list_people_cpp +@@ -41,11 +43,11 @@ protoc_middleman_dart: addressbook.proto + + add_person_cpp: add_person.cc protoc_middleman + pkg-config --cflags protobuf # fails if protobuf is not installed +- c++ -std=c++14 add_person.cc addressbook.pb.cc -o add_person_cpp `pkg-config --cflags --libs protobuf` ++ $(CXX) $(CXXFLAGS) $(LDFLAGS) ../src/google/protobuf/.libs/timestamp.pb.o $(PROTOBUF) add_person.cc addressbook.pb.cc -o add_person_cpp #$(CXX) -std=c++17 $(PROTOBUF) add_person.cc addressbook.pb.cc -o add_person_cpp + + list_people_cpp: list_people.cc protoc_middleman + pkg-config --cflags protobuf # fails if protobuf is not installed +- c++ -std=c++14 list_people.cc addressbook.pb.cc -o list_people_cpp `pkg-config --cflags --libs protobuf` ++ $(CXX) $(CXXFLAGS) $(LDFLAGS) ../src/google/protobuf/.libs/timestamp.pb.o $(PROTOBUF) list_people.cc addressbook.pb.cc -o list_people_cpp #$(CXX) -std=c++17 $(PROTOBUF) list_people.cc addressbook.pb.cc -o list_people_cpp + + add_person_dart: add_person.dart protoc_middleman_dart + +-- +2.34.1 + diff --git a/recipes-devtools/protobuf/protobuf/run-ptest b/recipes-devtools/protobuf/protobuf/run-ptest new file mode 100644 index 0000000..b3b2278 --- /dev/null +++ b/recipes-devtools/protobuf/protobuf/run-ptest @@ -0,0 +1,38 @@ +#!/bin/bash +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TEST_FILE="/tmp/test.data" + +RETVAL=0 +# Test every writing test application +for write_exe_full_path in ${DIR}/add_person_*; do + if [ -x "${write_exe_full_path}" ]; then + write_exe=`basename ${write_exe_full_path}` + echo "Generating new test file using ${write_exe}..." + printf "1234\nname\nname@example.com\n" | ${write_exe_full_path} "${TEST_FILE}" + RETVAL=$? + [ $RETVAL -eq 0 ] || exit $RETVAL + + # Test every reading test application + for read_exe_full_path in ${DIR}/list_people_*; do + read_exe=`basename ${read_exe_full_path}` + echo "Test: Write with ${write_exe}; Read with ${read_exe}..." + if [ -x "${read_exe_full_path}" ]; then + ${read_exe_full_path} "${TEST_FILE}" + RETVAL=$? + [ $RETVAL -eq 0 ] || exit $RETVAL + fi + done + + # Cleanup... + if [ -e "${TEST_FILE}" ]; then + rm "${TEST_FILE}" + fi + fi +done + +if [ $RETVAL -eq 0 ] ; then + echo "PASS: protobuf" +else + echo "FAIL: protobuf" +fi + diff --git a/recipes-devtools/protobuf/protobuf_4.25.3.bb b/recipes-devtools/protobuf/protobuf_4.25.3.bb new file mode 100644 index 0000000..acc35db --- /dev/null +++ b/recipes-devtools/protobuf/protobuf_4.25.3.bb @@ -0,0 +1,119 @@ +SUMMARY = "Protocol Buffers - structured data serialisation mechanism" +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." +HOMEPAGE = "https://github.com/google/protobuf" +SECTION = "console/tools" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://LICENSE;md5=37b5762e07f0af8c74ce80a8bda4266b" + +DEPENDS = "zlib abseil-cpp" +DEPENDS:append:class-target = " protobuf-native" + +SRCREV = "4a2aef570deb2bfb8927426558701e8bfc26f2a4" + +SRC_URI = "gitsm://github.com/protocolbuffers/protobuf.git;branch=25.x;protocol=https \ + file://run-ptest \ + file://0001-examples-Makefile-respect-CXX-LDFLAGS-variables-fix-.patch \ + file://0001-Add-recursion-check-when-parsing-unknown-fields-in-J.patch \ + " +SRC_URI:append:mips:toolchain-clang = " file://0001-Fix-build-on-mips-clang.patch " +SRC_URI:append:mipsel:toolchain-clang = " file://0001-Fix-build-on-mips-clang.patch " + +S = "${WORKDIR}/git" + +inherit cmake pkgconfig ptest + +PACKAGECONFIG ??= "" +PACKAGECONFIG:class-native ?= "compiler" +PACKAGECONFIG:class-nativesdk ?= "compiler" +PACKAGECONFIG[python] = ",," +PACKAGECONFIG[compiler] = "-Dprotobuf_BUILD_PROTOC_BINARIES=ON,-Dprotobuf_BUILD_PROTOC_BINARIES=OFF" + +EXTRA_OECMAKE += "\ + -Dprotobuf_BUILD_SHARED_LIBS=ON \ + -Dprotobuf_BUILD_LIBPROTOC=ON \ + -Dprotobuf_BUILD_TESTS=OFF \ + -Dprotobuf_BUILD_EXAMPLES=OFF \ + -Dprotobuf_ABSL_PROVIDER="package" \ +" + +TEST_SRC_DIR = "examples" +LANG_SUPPORT = "cpp ${@bb.utils.contains('PACKAGECONFIG', 'python', 'python', '', d)}" + +do_compile_ptest() { + mkdir -p "${B}/${TEST_SRC_DIR}" + + # Add the location of the cross-compiled header and library files + # which haven't been installed yet. + cp "${B}/protobuf.pc" "${B}/${TEST_SRC_DIR}/protobuf.pc" + cp ${S}/${TEST_SRC_DIR}/*.cc "${B}/${TEST_SRC_DIR}/" + cp ${S}/${TEST_SRC_DIR}/*.proto "${B}/${TEST_SRC_DIR}/" + cp ${S}/${TEST_SRC_DIR}/*.py "${B}/${TEST_SRC_DIR}/" + cp ${S}/${TEST_SRC_DIR}/Makefile "${B}/${TEST_SRC_DIR}/" + # Adapt protobuf.pc + sed -e 's|libdir=|libdir=${PKG_CONFIG_SYSROOT_DIR}|' -i "${B}/${TEST_SRC_DIR}/protobuf.pc" + sed -e 's|Cflags:|Cflags: -I${S}/src |' -i "${B}/${TEST_SRC_DIR}/protobuf.pc" + sed -e 's|Cflags:|Cflags: -I${WORKDIR}/recipe-sysroot${includedir} |' -i "${B}/${TEST_SRC_DIR}/protobuf.pc" + sed -e 's|Libs:|Libs: -L${B}|' -i "${B}/${TEST_SRC_DIR}/protobuf.pc" + sed -e 's|Libs:|Libs: -L${WORKDIR}/recipe-sysroot/usr/lib |' -i "${B}/${TEST_SRC_DIR}/protobuf.pc" + sed -e 's|Libs:|Libs: -labsl_log_internal_check_op |' -i "${B}/${TEST_SRC_DIR}/protobuf.pc" + sed -e 's|Libs:|Libs: -labsl_log_internal_message |' -i "${B}/${TEST_SRC_DIR}/protobuf.pc" + # Adapt uf8_range.pc + cp "${B}/third_party/utf8_range/utf8_range.pc" "${B}/${TEST_SRC_DIR}/utf8_range.pc" + sed -e 's|libdir=|libdir=${PKG_CONFIG_SYSROOT_DIR}|' -i "${B}/${TEST_SRC_DIR}/utf8_range.pc" + sed -e 's|Libs:|Libs= -L${B}/third_party/utf8_range |' -i "${B}/${TEST_SRC_DIR}/utf8_range.pc" + # Until out-of-tree build of examples is supported, we have to use this approach + sed -e 's|../src/google/protobuf/.libs/timestamp.pb.o|${B}/CMakeFiles/libprotobuf.dir/src/google/protobuf/timestamp.pb.cc.o|' -i "${B}/${TEST_SRC_DIR}/Makefile" + export PKG_CONFIG_PATH="${B}/${TEST_SRC_DIR}" + + # Save the pkgcfg sysroot variable, and update it to nothing so + # that it doesn't append the sysroot to the beginning of paths. + # The header and library files aren't installed to the target + # system yet. So the absolute paths were specified above. + save_pkg_config_sysroot_dir=$PKG_CONFIG_SYSROOT_DIR + export PKG_CONFIG_SYSROOT_DIR= + + # Compile the tests + for lang in ${LANG_SUPPORT}; do + oe_runmake -C "${B}/${TEST_SRC_DIR}" ${lang} + done + + # Restore the pkgconfig sysroot variable + export PKG_CONFIG_SYSROOT_DIR=$save_pkg_config_sysroot_dir +} + +do_install_ptest() { + local olddir=`pwd` + + cd "${S}/${TEST_SRC_DIR}" + install -d "${D}/${PTEST_PATH}" + for i in add_person* list_people*; do + if [ -x "$i" ]; then + install "$i" "${D}/${PTEST_PATH}" + fi + done + cp "${B}/${TEST_SRC_DIR}/addressbook_pb2.py" "${D}/${PTEST_PATH}" + cd "$olddir" +} + +PACKAGE_BEFORE_PN = "${PN}-compiler ${PN}-lite" + +FILES:${PN}-compiler = "${bindir} ${libdir}/libprotoc${SOLIBS}" +FILES:${PN}-lite = "${libdir}/libprotobuf-lite${SOLIBS}" + +# CMake requires protoc binary to exist in sysroot, even if it has wrong architecture. +SYSROOT_DIRS += "${bindir}" + +RDEPENDS:${PN}-compiler = "${PN}" +RDEPENDS:${PN}-dev += "${PN}-compiler" +RDEPENDS:${PN}-ptest = "bash ${@bb.utils.contains('PACKAGECONFIG', 'python', 'python3-protobuf', '', d)}" + +MIPS_INSTRUCTION_SET = "mips" + +BBCLASSEXTEND = "native nativesdk" + +LDFLAGS:append:arm = " -latomic" +LDFLAGS:append:mips = " -latomic" +LDFLAGS:append:powerpc = " -latomic" +LDFLAGS:append:mipsel = " -latomic" diff --git a/recipes-devtools/python/python3-protobuf_4.25.3.bb b/recipes-devtools/python/python3-protobuf_4.25.3.bb new file mode 100644 index 0000000..c234ce5 --- /dev/null +++ b/recipes-devtools/python/python3-protobuf_4.25.3.bb @@ -0,0 +1,45 @@ +DESCRIPTION = "Protocol Buffers" +HOMEPAGE = "https://developers.google.com/protocol-buffers/" +SECTION = "devel/python" + +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://PKG-INFO;beginline=8;endline=8;md5=53dbfa56f61b90215a9f8f0d527c043d" + +inherit pypi setuptools3 +SRC_URI[sha256sum] = "25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c" + +# http://errors.yoctoproject.org/Errors/Details/184715/ +# Can't find required file: ../src/google/protobuf/descriptor.proto +CLEANBROKEN = "1" + +UPSTREAM_CHECK_REGEX = "protobuf/(?P<pver>\d+(\.\d+)+)/" + +DEPENDS += "protobuf" + +RDEPENDS:${PN} += " \ + python3-datetime \ + python3-json \ + python3-logging \ + python3-netclient \ + python3-numbers \ + python3-pkgutil \ + python3-unittest \ +" + +# For usage in other recipies when compiling protobuf files (e.g. by grpcio-tools) +BBCLASSEXTEND = "native nativesdk" + +DISTUTILS_BUILD_ARGS += "--cpp_implementation" +DISTUTILS_INSTALL_ARGS += "--cpp_implementation" + +do_compile:prepend:class-native () { + export KOKORO_BUILD_NUMBER="1" +} + +do_install:append () { + # Remove useless and problematic .pth file. python3-protobuf is installed in the standard + # location of site packages. No need for such .pth file. + # NOTE: do not drop this removal until the following issue in upstream cpython is resolved: + # https://github.com/python/cpython/issues/122220 + rm -f ${D}${PYTHON_SITEPACKAGES_DIR}/protobuf-*-nspkg.pth +} |
