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

edimitrova pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git


The following commit(s) were added to refs/heads/trunk by this push:
     new eb68380  Throw IOE in AbstractType.writeValue if value has wrong fixed 
length authored by Alexandre Dutra; reviewed by Berenguer Blasi and Andres de 
la Pena for CASSANDRA-16500
eb68380 is described below

commit eb68380866c9d96592580fefbc1b79a497a674bf
Author: Alexandre Dutra <[email protected]>
AuthorDate: Wed Mar 10 11:01:35 2021 +0100

    Throw IOE in AbstractType.writeValue if value has wrong fixed length
    authored by Alexandre Dutra; reviewed by Berenguer Blasi and Andres de la 
Pena for CASSANDRA-16500
---
 .../apache/cassandra/db/marshal/AbstractType.java   | 18 ++++++++++++++----
 test/unit/org/apache/cassandra/db/ScrubTest.java    |  3 ++-
 .../cassandra/db/marshal/TypeValidationTest.java    | 21 ++++++++++++++++++++-
 3 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/src/java/org/apache/cassandra/db/marshal/AbstractType.java 
b/src/java/org/apache/cassandra/db/marshal/AbstractType.java
index 0b47644..19cf849 100644
--- a/src/java/org/apache/cassandra/db/marshal/AbstractType.java
+++ b/src/java/org/apache/cassandra/db/marshal/AbstractType.java
@@ -435,11 +435,21 @@ public abstract class AbstractType<T> implements 
Comparator<ByteBuffer>, Assignm
     // This assumes that no empty values are passed
     public  <V> void writeValue(V value, ValueAccessor<V> accessor, 
DataOutputPlus out) throws IOException
     {
-        assert !accessor.isEmpty(value);
-        if (valueLengthIfFixed() >= 0)
-            accessor.write(value, out);
+        assert !accessor.isEmpty(value) : "bytes should not be empty for type 
" + this;
+        int expectedValueLength = valueLengthIfFixed();
+        if (expectedValueLength >= 0)
+        {
+            int actualValueLength = accessor.size(value);
+            if (actualValueLength == expectedValueLength)
+                accessor.write(value, out);
+            else
+                throw new IOException(String.format("Expected exactly %d 
bytes, but was %d",
+                                                    expectedValueLength, 
actualValueLength));
+        }
         else
+        {
             accessor.writeWithVIntLength(value, out);
+        }
     }
 
     public long writtenLength(ByteBuffer value)
@@ -451,7 +461,7 @@ public abstract class AbstractType<T> implements 
Comparator<ByteBuffer>, Assignm
     {
         assert !accessor.isEmpty(value) : "bytes should not be empty for type 
" + this;
         return valueLengthIfFixed() >= 0
-               ? accessor.size(value)
+               ? accessor.size(value) // if the size is wrong, this will be 
detected in writeValue
                : accessor.sizeWithVIntLength(value);
     }
 
diff --git a/test/unit/org/apache/cassandra/db/ScrubTest.java 
b/test/unit/org/apache/cassandra/db/ScrubTest.java
index 6ecaded..343089e 100644
--- a/test/unit/org/apache/cassandra/db/ScrubTest.java
+++ b/test/unit/org/apache/cassandra/db/ScrubTest.java
@@ -56,6 +56,7 @@ import org.apache.cassandra.db.compaction.OperationType;
 import org.apache.cassandra.db.compaction.Scrubber;
 import org.apache.cassandra.db.lifecycle.LifecycleNewTracker;
 import org.apache.cassandra.db.lifecycle.LifecycleTransaction;
+import org.apache.cassandra.db.marshal.Int32Type;
 import org.apache.cassandra.db.marshal.LongType;
 import org.apache.cassandra.db.marshal.UUIDType;
 import org.apache.cassandra.db.partitions.Partition;
@@ -548,7 +549,7 @@ public class ScrubTest
         QueryProcessor.process("CREATE TABLE 
\"Keyspace1\".test_scrub_validation (a text primary key, b int)", 
ConsistencyLevel.ONE);
         ColumnFamilyStore cfs2 = 
keyspace.getColumnFamilyStore("test_scrub_validation");
 
-        new Mutation(UpdateBuilder.create(cfs2.metadata(), 
"key").newRow().add("b", LongType.instance.decompose(1L)).build()).apply();
+        new Mutation(UpdateBuilder.create(cfs2.metadata(), 
"key").newRow().add("b", Int32Type.instance.decompose(1)).build()).apply();
         cfs2.forceBlockingFlush();
 
         CompactionManager.instance.performScrub(cfs2, false, false, 2);
diff --git a/test/unit/org/apache/cassandra/db/marshal/TypeValidationTest.java 
b/test/unit/org/apache/cassandra/db/marshal/TypeValidationTest.java
index cdcc5a6..7c0c863 100644
--- a/test/unit/org/apache/cassandra/db/marshal/TypeValidationTest.java
+++ b/test/unit/org/apache/cassandra/db/marshal/TypeValidationTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -19,16 +19,19 @@
 package org.apache.cassandra.db.marshal;
 
 import org.apache.cassandra.Util;
+import org.apache.cassandra.io.util.DataOutputPlus;
 import org.apache.cassandra.serializers.MarshalException;
 import org.apache.cassandra.utils.AbstractTypeGenerators;
 import org.apache.cassandra.utils.Pair;
 import org.apache.cassandra.utils.UUIDGen;
 import org.assertj.core.api.Assertions;
+import org.mockito.Mockito;
 import org.quicktheories.core.Gen;
 import org.quicktheories.generators.SourceDSL;
 
 import org.junit.Test;
 
+import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
@@ -37,6 +40,7 @@ import java.util.UUID;
 import static org.apache.cassandra.utils.AbstractTypeGenerators.getTypeSupport;
 import static 
org.apache.cassandra.utils.AbstractTypeGenerators.primitiveTypeGen;
 import static org.apache.cassandra.utils.AbstractTypeGenerators.userTypeGen;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.quicktheories.QuickTheory.qt;
 
 public class TypeValidationTest
@@ -75,6 +79,21 @@ public class TypeValidationTest
     }
 
     @Test
+    public void testWriteValueWrongFixedLength()
+    {
+        DataOutputPlus output = Mockito.mock(DataOutputPlus.class);
+
+        assertThatThrownBy(() -> 
Int32Type.instance.writeValue(Util.getBytes(42L), output))
+        .isInstanceOf(IOException.class).hasMessageContaining("Expected 
exactly 4 bytes, but was 8");
+        assertThatThrownBy(() -> 
LongType.instance.writeValue(Util.getBytes(42), output))
+        .isInstanceOf(IOException.class).hasMessageContaining("Expected 
exactly 8 bytes, but was 4");
+        assertThatThrownBy(() -> 
UUIDType.instance.writeValue(Util.getBytes(42L), output))
+        .isInstanceOf(IOException.class).hasMessageContaining("Expected 
exactly 16 bytes, but was 8");
+
+        Mockito.verifyNoInteractions(output);
+    }
+
+    @Test
     public void testValidUtf8() throws UnsupportedEncodingException
     {
         assert Character.MAX_CODE_POINT == 0x0010ffff;

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to