Fix parsing negative Int32Value that crosses segment boundary
diff --git a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
index 1fb3bb5..0ad286f 100644
--- a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
+++ b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
@@ -344,6 +344,25 @@
         }

 

         [Test]

+        public void ReadInt32Wrapper_VariableBlockSizes()

+        {

+            byte[] rawBytes = new byte[] { 202, 1, 11, 8, 254, 255, 255, 255, 255, 255, 255, 255, 255, 1 };

+

+            for (int blockSize = 1; blockSize <= rawBytes.Length; blockSize++)

+            {

+                ReadOnlySequence<byte> data = ReadOnlySequenceFactory.CreateWithContent(rawBytes, blockSize);

+                AssertReadFromParseContext(data, (ref ParseContext ctx) =>

+                {

+                    ctx.ReadTag();

+

+                    var value = ParsingPrimitivesWrappers.ReadInt32Wrapper(ref ctx);

+

+                    Assert.AreEqual(-2, value);

+                }, true);

+            }

+        }

+

+        [Test]

         public void ReadHugeBlob()

         {

             // Allocate and initialize a 1MB blob.

diff --git a/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs b/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs
index 1263064..629ec32 100644
--- a/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs
+++ b/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs
@@ -160,8 +160,11 @@
 
         internal static uint? ReadUInt32Wrapper(ref ReadOnlySpan<byte> buffer, ref ParserInternalState state)
         {
-            // length:1 + tag:1 + value:5(varint32-max) = 7 bytes
-            if (state.bufferPos + 7 <= state.bufferSize)
+            // field=1, type=varint = tag of 8
+            const int expectedTag = 8;
+            // length:1 + tag:1 + value:10(varint64-max) = 12 bytes
+            // Value can be 64 bits for negative integers
+            if (state.bufferPos + 12 <= state.bufferSize)
             {
                 // The entire wrapper message is already contained in `buffer`.
                 int pos0 = state.bufferPos;
@@ -177,8 +180,7 @@
                     return ReadUInt32WrapperSlow(ref buffer, ref state);
                 }
                 int finalBufferPos = state.bufferPos + length;
-                // field=1, type=varint = tag of 8
-                if (buffer[state.bufferPos++] != 8)
+                if (buffer[state.bufferPos++] != expectedTag)
                 {
                     state.bufferPos = pos0;
                     return ReadUInt32WrapperSlow(ref buffer, ref state);