From 4c366e571aa6962755bd9d9470df2ec3fd8e2565 Mon Sep 17 00:00:00 2001
From: Yannick Lecaillez <ylecaillez@forgerock.com>
Date: Wed, 09 Dec 2015 13:42:55 +0000
Subject: [PATCH] OPENDJ-2526: NegativeArraySizeException in OnDiskMergeImporter during OpenAM embedded DJ upgrade (DJ 2.6 -> 3.0)

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java     |   12 ++++++------
 opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/OnDiskMergeImporterTest.java |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
index 76ff156..ad6f42b 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
@@ -2656,7 +2656,7 @@
   }
 
   /** Buffer used by {@link InMemorySortedChunk} to store and sort data. */
-  private interface Buffer extends Closeable
+  interface Buffer extends Closeable
   {
     void writeInt(int position, int value);
 
@@ -2764,7 +2764,7 @@
     }
 
     /** Off-heap buffer using Unsafe memory access. */
-    private final class OffHeapBuffer implements Buffer
+    static final class OffHeapBuffer implements Buffer
     {
       private final long address;
       private final int size;
@@ -2774,7 +2774,7 @@
         @Override
         public int read() throws IOException
         {
-          return unsafe.getByte(address + position++);
+          return unsafe.getByte(address + position++) & 0xFF;
         }
       };
       private final OutputStream asOutputStream = new OutputStream()
@@ -2878,7 +2878,7 @@
       }
 
       @Override
-      public void close() throws IOException
+      public void close()
       {
         if (!closed)
         {
@@ -2888,8 +2888,8 @@
       }
     }
 
-    /** Off-heap buffer using Unsafe memory access. */
-    private final class HeapBuffer implements Buffer
+    /** Heap buffer using ByteBuffer. */
+    static final class HeapBuffer implements Buffer
     {
       private final ByteBuffer buffer;
       private final OutputStream asOutputStream = new OutputStream()
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/OnDiskMergeImporterTest.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/OnDiskMergeImporterTest.java
index 27e1235..dfb3c0f 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/OnDiskMergeImporterTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/OnDiskMergeImporterTest.java
@@ -28,6 +28,7 @@
 import static org.opends.server.backends.pluggable.EntryIDSet.*;
 
 import java.io.File;
+import java.io.IOException;
 import java.nio.channels.FileChannel;
 import java.nio.file.StandardOpenOption;
 import java.util.ArrayList;
@@ -48,7 +49,10 @@
 import org.mockito.Mockito;
 import org.opends.server.DirectoryServerTestCase;
 import org.opends.server.TestCaseUtils;
+import org.opends.server.backends.pluggable.OnDiskMergeImporter.Buffer;
 import org.opends.server.backends.pluggable.OnDiskMergeImporter.BufferPool;
+import org.opends.server.backends.pluggable.OnDiskMergeImporter.BufferPool.HeapBuffer;
+import org.opends.server.backends.pluggable.OnDiskMergeImporter.BufferPool.OffHeapBuffer;
 import org.opends.server.backends.pluggable.OnDiskMergeImporter.Chunk;
 import org.opends.server.backends.pluggable.OnDiskMergeImporter.Collector;
 import org.opends.server.backends.pluggable.OnDiskMergeImporter.EntryIDSetsCollector;
@@ -71,6 +75,34 @@
 public class OnDiskMergeImporterTest extends DirectoryServerTestCase
 {
   @Test
+  public void testBuffer() throws IOException
+  {
+    try(Buffer buffer = new HeapBuffer(1024))
+    {
+      testBufferImplementation(buffer);
+    }
+    try (Buffer buffer = new OffHeapBuffer(1024))
+    {
+      testBufferImplementation(buffer);
+    }
+  }
+
+  private static void testBufferImplementation(Buffer buffer)
+  {
+    final ByteString binary = ByteString.valueOfBytes(new byte[] { 1, 2, 3, 4 });
+
+    buffer.writeByteSequence(0, binary);
+    buffer.writeInt(4, 1234);
+    buffer.writeCompactUnsignedLong(8, 42);
+    buffer.writeCompactUnsignedLong(9, 0xFFFF);
+
+    assertThat(buffer.readByteString(0, 4)).isEqualTo(binary);
+    assertThat(buffer.readInt(4)).isEqualTo(1234);
+    assertThat(buffer.readCompactUnsignedLong(8)).isEqualTo(42);
+    assertThat(buffer.readCompactUnsignedLong(9)).isEqualTo(0xFFFF);
+  }
+
+  @Test
   @SuppressWarnings(value = "resource")
   public void testCollectCursor()
   {

--
Gitblit v1.10.0