This is an automated email from the ASF dual-hosted git repository.

paulirwin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git


The following commit(s) were added to refs/heads/master by this push:
     new d597a5f38 Fix overflow in ByteBlockPool, #1003 (#1055)
d597a5f38 is described below

commit d597a5f38a6a2d78e075545190368735596ddcab
Author: Paul Irwin <[email protected]>
AuthorDate: Tue Dec 3 17:57:07 2024 -0700

    Fix overflow in ByteBlockPool, #1003 (#1055)
---
 src/Lucene.Net.Tests/Util/TestByteBlockPool.cs | 53 +++++++++++++++++++++++++-
 src/Lucene.Net/Util/ByteBlockPool.cs           |  6 ++-
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/src/Lucene.Net.Tests/Util/TestByteBlockPool.cs 
b/src/Lucene.Net.Tests/Util/TestByteBlockPool.cs
index 522f894c8..4e70dd09a 100644
--- a/src/Lucene.Net.Tests/Util/TestByteBlockPool.cs
+++ b/src/Lucene.Net.Tests/Util/TestByteBlockPool.cs
@@ -1,5 +1,7 @@
-using NUnit.Framework;
+using Lucene.Net.Attributes;
+using NUnit.Framework;
 using RandomizedTesting.Generators;
+using System;
 using System.Collections.Generic;
 using JCG = J2N.Collections.Generic;
 using Assert = Lucene.Net.TestFramework.Assert;
@@ -68,5 +70,54 @@ namespace Lucene.Net.Util
                 }
             }
         }
+
+        [Test]
+        [LuceneNetSpecific] // LUCENENET issue #1003
+        public void TestTooManyAllocs()
+        {
+            // Use a mock allocator that doesn't waste memory
+            ByteBlockPool pool = new ByteBlockPool(new MockAllocator(0));
+            pool.NextBuffer();
+
+            bool throwsException = false;
+            int maxIterations = int.MaxValue / ByteBlockPool.BYTE_BLOCK_SIZE + 
1;
+
+            for (int i = 0; i < maxIterations; i++)
+            {
+                try
+                {
+                    pool.NextBuffer();
+                }
+                catch (OverflowException)
+                {
+                    // The offset overflows on the last attempt to call 
NextBuffer()
+                    throwsException = true;
+                    break;
+                }
+            }
+
+            Assert.IsTrue(throwsException);
+            Assert.IsTrue(pool.ByteOffset + ByteBlockPool.BYTE_BLOCK_SIZE < 
pool.ByteOffset);
+        }
+
+        private class MockAllocator : ByteBlockPool.Allocator
+        {
+            private readonly byte[] buffer;
+
+            public MockAllocator(int blockSize) : base(blockSize)
+            {
+                buffer = Array.Empty<byte>();
+            }
+
+            public override void RecycleByteBlocks(byte[][] blocks, int start, 
int end)
+            {
+                // No-op
+            }
+
+            public override byte[] GetByteBlock()
+            {
+                return buffer;
+            }
+        }
     }
 }
diff --git a/src/Lucene.Net/Util/ByteBlockPool.cs 
b/src/Lucene.Net/Util/ByteBlockPool.cs
index 898eaf077..a2df7defb 100644
--- a/src/Lucene.Net/Util/ByteBlockPool.cs
+++ b/src/Lucene.Net/Util/ByteBlockPool.cs
@@ -262,7 +262,11 @@ namespace Lucene.Net.Util
             bufferUpto++;
 
             ByteUpto = 0;
-            ByteOffset += BYTE_BLOCK_SIZE;
+
+            checked // LUCENENET specific - added checked to prevent overflow, 
issue #1003
+            {
+                ByteOffset += BYTE_BLOCK_SIZE;
+            }
         }
 
         /// <summary>

Reply via email to