github-advanced-security[bot] commented on code in PR #3857:
URL: https://github.com/apache/avro/pull/3857#discussion_r3564694903


##########
lang/csharp/src/apache/test/File/FileTests.cs:
##########
@@ -425,6 +425,109 @@
             Assert.Throws(typeof(AvroRuntimeException), action);
         }
 
+        /// <summary>
+        /// A block with a very high compression ratio can expand to far more 
memory
+        /// than its compressed size; decompressing such a block must be 
rejected once
+        /// its decompressed size would exceed the configured maximum.
+        /// </summary>
+        [Test]
+        public void TestDeflateDecompressionLimit()
+        {
+            var codec = new DeflateCodec();
+            byte[] big = new byte[4 * 1024 * 1024]; // 4 MiB of zeros, 
compresses tiny
+            byte[] compressed = codec.Compress(big);
+
+            var previous = 
Environment.GetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar);
+            
Environment.SetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar, "1048576"); 
// 1 MiB
+            try
+            {
+                Assert.Throws<AvroRuntimeException>(
+                    () => codec.Decompress(compressed, compressed.Length));
+            }
+            finally
+            {
+                
Environment.SetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar, previous);
+            }
+        }
+
+        [Test]
+        public void TestDeflateWithinDecompressionLimit()
+        {
+            var codec = new DeflateCodec();
+            byte[] payload = System.Text.Encoding.UTF8.GetBytes("hello world");
+            byte[] compressed = codec.Compress(payload);
+
+            var previous = 
Environment.GetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar);
+            
Environment.SetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar, "1048576"); 
// 1 MiB
+            try
+            {
+                byte[] result = codec.Decompress(compressed, 
compressed.Length);
+                Assert.AreEqual(payload, result);
+            }
+            finally
+            {
+                
Environment.SetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar, previous);
+            }
+        }
+
+        [Test]
+        public void TestCopyBoundedValidatesArguments()
+        {
+            using (var stream = new MemoryStream())
+            {
+                Assert.Throws<ArgumentNullException>(() => 
Codec.CopyBounded(null, stream, 10));
+                Assert.Throws<ArgumentNullException>(() => 
Codec.CopyBounded(stream, null, 10));
+                Assert.Throws<ArgumentOutOfRangeException>(() => 
Codec.CopyBounded(stream, stream, -1));
+            }
+        }
+
+        /// <summary>
+        /// The DataFileReader itself must reject a block whose decompressed 
size
+        /// exceeds the configured maximum. This covers the safeguard applied 
to
+        /// every codec that returns a fully materialized buffer (here the Null
+        /// codec, which performs no internally bounded decompression), not 
just a
+        /// direct call to a codec's Decompress method.
+        /// </summary>
+        [Test]
+        public void TestReaderRejectsOversizedBlock()
+        {
+            const string schemaStr =
+                
"{\"type\":\"record\",\"name\":\"n\",\"fields\":[{\"name\":\"f1\",\"type\":\"string\"}]}";
+            Schema schema = Schema.Parse(schemaStr);
+            var recordSchema = schema as RecordSchema;
+
+            // A single record whose string field is larger than the limit 
below.
+            string big = new string('a', 2 * 1024 * 1024); // 2 MiB
+
+            MemoryStream outStream = new MemoryStream();
+            using (var writer = DataFileWriter<GenericRecord>.OpenWriter(
+                new GenericWriter<GenericRecord>(schema), outStream, 
Codec.CreateCodec(Codec.Type.Null)))
+            {
+                writer.Append(mkRecord(new object[] { "f1", big }, 
recordSchema));
+            }
+
+            MemoryStream inStream = new MemoryStream(outStream.ToArray());
+
+            var previous = 
Environment.GetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar);
+            
Environment.SetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar, "1048576"); 
// 1 MiB
+            try
+            {
+                Assert.Throws<AvroRuntimeException>(() =>
+                {
+                    using (var reader = 
DataFileReader<GenericRecord>.OpenReader(inStream, schema))
+                    {
+                        foreach (var rec in reader.NextEntries)

Review Comment:
   ## CodeQL / Useless assignment to local variable
   
   This assignment to [rec](1) is useless, since its value is never read.
   
   [Show more 
details](https://github.com/apache/avro/security/code-scanning/3369)



##########
lang/csharp/src/apache/test/File/FileTests.cs:
##########
@@ -425,6 +425,109 @@
             Assert.Throws(typeof(AvroRuntimeException), action);
         }
 
+        /// <summary>
+        /// A block with a very high compression ratio can expand to far more 
memory
+        /// than its compressed size; decompressing such a block must be 
rejected once
+        /// its decompressed size would exceed the configured maximum.
+        /// </summary>
+        [Test]
+        public void TestDeflateDecompressionLimit()
+        {
+            var codec = new DeflateCodec();
+            byte[] big = new byte[4 * 1024 * 1024]; // 4 MiB of zeros, 
compresses tiny
+            byte[] compressed = codec.Compress(big);
+
+            var previous = 
Environment.GetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar);
+            
Environment.SetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar, "1048576"); 
// 1 MiB
+            try
+            {
+                Assert.Throws<AvroRuntimeException>(
+                    () => codec.Decompress(compressed, compressed.Length));
+            }
+            finally
+            {
+                
Environment.SetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar, previous);
+            }
+        }
+
+        [Test]
+        public void TestDeflateWithinDecompressionLimit()
+        {
+            var codec = new DeflateCodec();
+            byte[] payload = System.Text.Encoding.UTF8.GetBytes("hello world");
+            byte[] compressed = codec.Compress(payload);
+
+            var previous = 
Environment.GetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar);
+            
Environment.SetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar, "1048576"); 
// 1 MiB
+            try
+            {
+                byte[] result = codec.Decompress(compressed, 
compressed.Length);
+                Assert.AreEqual(payload, result);
+            }
+            finally
+            {
+                
Environment.SetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar, previous);
+            }
+        }
+
+        [Test]
+        public void TestCopyBoundedValidatesArguments()
+        {
+            using (var stream = new MemoryStream())
+            {
+                Assert.Throws<ArgumentNullException>(() => 
Codec.CopyBounded(null, stream, 10));
+                Assert.Throws<ArgumentNullException>(() => 
Codec.CopyBounded(stream, null, 10));
+                Assert.Throws<ArgumentOutOfRangeException>(() => 
Codec.CopyBounded(stream, stream, -1));
+            }
+        }
+
+        /// <summary>
+        /// The DataFileReader itself must reject a block whose decompressed 
size
+        /// exceeds the configured maximum. This covers the safeguard applied 
to
+        /// every codec that returns a fully materialized buffer (here the Null
+        /// codec, which performs no internally bounded decompression), not 
just a
+        /// direct call to a codec's Decompress method.
+        /// </summary>
+        [Test]
+        public void TestReaderRejectsOversizedBlock()
+        {
+            const string schemaStr =
+                
"{\"type\":\"record\",\"name\":\"n\",\"fields\":[{\"name\":\"f1\",\"type\":\"string\"}]}";
+            Schema schema = Schema.Parse(schemaStr);
+            var recordSchema = schema as RecordSchema;
+
+            // A single record whose string field is larger than the limit 
below.
+            string big = new string('a', 2 * 1024 * 1024); // 2 MiB
+
+            MemoryStream outStream = new MemoryStream();
+            using (var writer = DataFileWriter<GenericRecord>.OpenWriter(
+                new GenericWriter<GenericRecord>(schema), outStream, 
Codec.CreateCodec(Codec.Type.Null)))
+            {
+                writer.Append(mkRecord(new object[] { "f1", big }, 
recordSchema));
+            }
+
+            MemoryStream inStream = new MemoryStream(outStream.ToArray());
+
+            var previous = 
Environment.GetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar);
+            
Environment.SetEnvironmentVariable(Codec.MaxDecompressLengthEnvVar, "1048576"); 
// 1 MiB
+            try
+            {
+                Assert.Throws<AvroRuntimeException>(() =>
+                {
+                    using (var reader = 
DataFileReader<GenericRecord>.OpenReader(inStream, schema))
+                    {
+                        foreach (var rec in reader.NextEntries)
+                        {
+                        }

Review Comment:
   ## CodeQL / Empty branch of conditional, or empty loop body
   
   Empty block without comment.
   
   [Show more 
details](https://github.com/apache/avro/security/code-scanning/3368)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to