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

brandonwilliams pushed a commit to branch cassandra-3.11
in repository https://gitbox.apache.org/repos/asf/cassandra.git

commit c190ab9fcbc8a993e570e6cdafc2b90219f80109
Merge: 377ceb6 04be736
Author: Brandon Williams <brandonwilli...@apache.org>
AuthorDate: Mon Apr 27 11:15:30 2020 -0500

    Merge branch 'cassandra-3.0' into cassandra-3.11

 CHANGES.txt                                        |  1 +
 .../cassandra/io/compress/CompressionMetadata.java |  6 +-
 .../compress/CompressedRandomAccessReaderTest.java | 86 +++++++++++++++++-----
 3 files changed, 73 insertions(+), 20 deletions(-)

diff --cc CHANGES.txt
index fd7ad6a,99f540c..b3c593b
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,7 -1,5 +1,8 @@@
 -3.0.21
 +3.11.7
 + * Allow sstableloader to use SSL on the native port (CASSANDRA-14904)
 +Merged from 3.0:
+  * Fix chunk index overflow due to large sstable with small chunk length 
(CASSANDRA-15595)
 + * Allow selecting static column only when querying static index 
(CASSANDRA-14242)
   * cqlsh return non-zero status when STDIN CQL fails (CASSANDRA-15623)
   * Don't skip sstables in slice queries based only on local min/max/deletion 
timestamp (CASSANDRA-15690)
   * Memtable memory allocations may deadlock (CASSANDRA-15367)
diff --cc 
test/unit/org/apache/cassandra/io/compress/CompressedRandomAccessReaderTest.java
index 0d2a9fb,34ff94f..c718147
--- 
a/test/unit/org/apache/cassandra/io/compress/CompressedRandomAccessReaderTest.java
+++ 
b/test/unit/org/apache/cassandra/io/compress/CompressedRandomAccessReaderTest.java
@@@ -123,42 -118,77 +125,61 @@@ public class CompressedRandomAccessRead
          }
      }
  
-     private static void testResetAndTruncate(File f, boolean compressed, 
boolean usemmap, int junkSize) throws IOException
+     /**
+      * JIRA: CASSANDRA-15595 verify large position with small chunk length 
won't overflow chunk index
+      */
+     @Test
+     public void testChunkIndexOverflow() throws IOException
      {
-         final String filename = f.getAbsolutePath();
-         MetadataCollector sstableMetadataCollector = new 
MetadataCollector(new ClusteringComparator(BytesType.instance));
-         try(SequentialWriter writer = compressed
-                 ? new CompressedSequentialWriter(f, filename + ".metadata",
-                 null, SequentialWriterOption.DEFAULT,
-                 CompressionParams.snappy(), sstableMetadataCollector)
-                 : new SequentialWriter(f))
+         File file = File.createTempFile("chunk_idx_overflow", "1");
+         String filename = file.getAbsolutePath();
+         int chunkLength = 4096; // 4k
+ 
+         try
          {
-             writer.write("The quick ".getBytes());
-             DataPosition mark = writer.mark();
-             writer.write("blue fox jumps over the lazy dog".getBytes());
+             writeSSTable(file, CompressionParams.snappy(chunkLength), 10);
+             CompressionMetadata metadata = new CompressionMetadata(filename + 
".metadata", file.length(), ChecksumType.CRC32);
  
-             // write enough to be sure to change chunk
-             for (int i = 0; i < junkSize; ++i)
+             long chunks = 2761628520L;
+             long midPosition = (chunks / 2L) * chunkLength;
+             int idx = 8 * (int) (midPosition / chunkLength); // before patch
+             assertTrue("Expect integer overflow", idx < 0);
+ 
+             try
              {
-                 writer.write((byte) 1);
+                 metadata.chunkFor(midPosition);
+                 fail("Expected to throw EOF exception with chunk idx larger 
than total number of chunks in the sstable");
+             }
+             catch (CorruptSSTableException e)
+             {
+                 assertTrue("Expect EOF, but got " + e.getCause(), 
e.getCause() instanceof EOFException);
              }
- 
-             writer.resetAndTruncate(mark);
-             writer.write("brown fox jumps over the lazy dog".getBytes());
-             writer.finish();
          }
-         assert f.exists();
+         finally
+         {
+             if (file.exists())
+                 assertTrue(file.delete());
+             File metadata = new File(filename + ".metadata");
+             if (metadata.exists())
+                 metadata.delete();
+         }
+     }
+ 
+     private static void testResetAndTruncate(File f, boolean compressed, 
boolean usemmap, int junkSize) throws IOException
+     {
+         final String filename = f.getAbsolutePath();
 -        try(ChannelProxy channel = new ChannelProxy(f))
 -        {
 -            writeSSTable(f, compressed ? CompressionParams.snappy() : null, 
junkSize);
 -
 -            CompressionMetadata compressionMetadata = compressed ? new 
CompressionMetadata(filename + ".metadata", f.length(), ChecksumType.CRC32) : 
null;
 -            RandomAccessReader.Builder builder = compressed
 -                                                 ? new 
CompressedRandomAccessReader.Builder(channel, compressionMetadata)
 -                                                 : new 
RandomAccessReader.Builder(channel);
 -
 -            if (usemmap)
 -            {
 -                if (compressed)
 -                    builder.regions(MmappedRegions.map(channel, 
compressionMetadata));
 -                else
 -                    builder.regions(MmappedRegions.map(channel, f.length()));
 -            }
++        writeSSTable(f, compressed ? CompressionParams.snappy() : null, 
junkSize);
  
 -            try(RandomAccessReader reader = builder.build())
 -            {
 -                String expected = "The quick brown fox jumps over the lazy 
dog";
 -                assertEquals(expected.length(), reader.length());
 -                byte[] b = new byte[expected.length()];
 -                reader.readFully(b);
 -                assert new String(b).equals(expected) : "Expecting '" + 
expected + "', got '" + new String(b) + '\'';
 -            }
 -
 -            if (usemmap)
 -                builder.regions.close();
 +        CompressionMetadata compressionMetadata = compressed ? new 
CompressionMetadata(filename + ".metadata", f.length(), ChecksumType.CRC32) : 
null;
 +        try (FileHandle.Builder builder = new 
FileHandle.Builder(filename).mmapped(usemmap).withCompressionMetadata(compressionMetadata);
 +             FileHandle fh = builder.complete();
 +             RandomAccessReader reader = fh.createReader())
 +        {
 +            String expected = "The quick brown fox jumps over the lazy dog";
 +            assertEquals(expected.length(), reader.length());
 +            byte[] b = new byte[expected.length()];
 +            reader.readFully(b);
 +            assert new String(b).equals(expected) : "Expecting '" + expected 
+ "', got '" + new String(b) + '\'';
          }
          finally
          {
@@@ -170,6 -200,31 +191,33 @@@
          }
      }
  
+     private static void writeSSTable(File f, CompressionParams params, int 
junkSize) throws IOException
+     {
+         final String filename = f.getAbsolutePath();
+         MetadataCollector sstableMetadataCollector = new 
MetadataCollector(new ClusteringComparator(BytesType.instance));
+         try(SequentialWriter writer = params != null
 -                                      ? new CompressedSequentialWriter(f, 
filename + ".metadata", params, sstableMetadataCollector)
 -                                      : SequentialWriter.open(f))
++                ? new CompressedSequentialWriter(f, filename + ".metadata",
++                                                 null, 
SequentialWriterOption.DEFAULT,
++                                                 params, 
sstableMetadataCollector)
++                : new SequentialWriter(f))
+         {
+             writer.write("The quick ".getBytes());
+             DataPosition mark = writer.mark();
+             writer.write("blue fox jumps over the lazy dog".getBytes());
+ 
+             // write enough to be sure to change chunk
+             for (int i = 0; i < junkSize; ++i)
+             {
+                 writer.write((byte) 1);
+             }
+ 
+             writer.resetAndTruncate(mark);
+             writer.write("brown fox jumps over the lazy dog".getBytes());
+             writer.finish();
+         }
+         assert f.exists();
+     }
+ 
      /**
       * If the data read out doesn't match the checksum, an exception should 
be thrown
       */


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to