cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ble...@apache.org
Subject [1/2] cassandra git commit: Fix duration type validation
Date Fri, 27 Jan 2017 09:18:38 GMT
Repository: cassandra
Updated Branches:
  refs/heads/trunk 26eab4546 -> 113b92bcb


Fix duration type validation

patch by Benjamin Lerer; reviewed by Tyler Hobbs for CASSANDRA-13143


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/91564aba
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/91564aba
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/91564aba

Branch: refs/heads/trunk
Commit: 91564abaddce59b06c024e8959c46ec1e4d19eda
Parents: b234ca3
Author: Benjamin Lerer <b.lerer@gmail.com>
Authored: Fri Jan 27 10:12:26 2017 +0100
Committer: Benjamin Lerer <b.lerer@gmail.com>
Committed: Fri Jan 27 10:12:26 2017 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../serializers/DurationSerializer.java         | 16 ++++++++++++
 .../cql3/validation/operations/CreateTest.java  | 26 +++++++++++++++++++-
 3 files changed, 42 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/91564aba/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 55762e2..aec644f 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.10
+ * Fix duration type validation (CASSANDRA-13143)
  * Fix flaky GcCompactionTest (CASSANDRA-12664)
  * Fix TestHintedHandoff.hintedhandoff_decom_test (CASSANDRA-13058)
  * Fixed query monitoring for range queries (CASSANDRA-13050)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/91564aba/src/java/org/apache/cassandra/serializers/DurationSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/serializers/DurationSerializer.java b/src/java/org/apache/cassandra/serializers/DurationSerializer.java
index d139b9e..03d08ae 100644
--- a/src/java/org/apache/cassandra/serializers/DurationSerializer.java
+++ b/src/java/org/apache/cassandra/serializers/DurationSerializer.java
@@ -80,6 +80,22 @@ public final class DurationSerializer implements TypeSerializer<Duration>
     {
         if (bytes.remaining() < 3)
             throw new MarshalException(String.format("Expected at least 3 bytes for a duration
(%d)", bytes.remaining()));
+
+        try (DataInputBuffer in = new DataInputBuffer(bytes, true))
+        {
+            int months = (int) in.readVInt();
+            int days = (int) in.readVInt();
+            long nanoseconds = in.readVInt();
+
+            if (!((months >= 0 && days >= 0 && nanoseconds >= 0)
|| (months <= 0 && days <=0 && nanoseconds <=0)))
+                throw new MarshalException(String.format("The duration months, days and nanoseconds
must be all of the same sign (%d, %d, %d)",
+                                                         months, days, nanoseconds));
+        }
+        catch (IOException e)
+        {
+            // this should never happen with a DataInputBuffer
+            throw new AssertionError("Unexpected error", e);
+        }
     }
 
     public String toString(Duration duration)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/91564aba/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java
index 6912f85..e60bf36 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java
@@ -17,6 +17,8 @@
  */
 package org.apache.cassandra.cql3.validation.operations;
 
+import java.io.IOException;
+import java.nio.ByteBuffer;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.UUID;
@@ -32,6 +34,7 @@ import org.apache.cassandra.db.Mutation;
 import org.apache.cassandra.db.partitions.Partition;
 import org.apache.cassandra.exceptions.ConfigurationException;
 import org.apache.cassandra.exceptions.SyntaxException;
+import org.apache.cassandra.io.util.DataOutputBuffer;
 import org.apache.cassandra.schema.SchemaKeyspace;
 import org.apache.cassandra.triggers.ITrigger;
 import org.apache.cassandra.utils.ByteBufferUtil;
@@ -121,6 +124,8 @@ public class CreateTest extends CQLTester
         execute("INSERT INTO %s (a, b, c) VALUES (1, 18, P1Y3MT2H10M)");
         execute("INSERT INTO %s (a, b, c) VALUES (1, 19, P0000-00-00T30:20:00)");
         execute("INSERT INTO %s (a, b, c) VALUES (1, 20, P0001-03-00T02:10:00)");
+        execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 1, 21, duration(12, 10, 0));
+        execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 1, 22, duration(-12, -10, 0));
 
         assertRows(execute("SELECT * FROM %s"),
                    row(1, 1, Duration.newInstance(14, 0, 0)),
@@ -142,7 +147,9 @@ public class CreateTest extends CQLTester
                    row(1, 17, Duration.newInstance(0, 14, 0)),
                    row(1, 18, Duration.newInstance(15, 0, 130 * NANOS_PER_MINUTE)),
                    row(1, 19, Duration.newInstance(0, 0, 30 * NANOS_PER_HOUR + 20 * NANOS_PER_MINUTE)),
-                   row(1, 20, Duration.newInstance(15, 0, 130 * NANOS_PER_MINUTE)));
+                   row(1, 20, Duration.newInstance(15, 0, 130 * NANOS_PER_MINUTE)),
+                   row(1, 21, Duration.newInstance(12, 10, 0)),
+                   row(1, 22, Duration.newInstance(-12, -10, 0)));
 
         assertInvalidMessage("Slice restriction are not supported on duration columns",
                              "SELECT * FROM %s WHERE c > 1y ALLOW FILTERING");
@@ -157,6 +164,12 @@ public class CreateTest extends CQLTester
         assertInvalidMessage("Invalid duration. The total number of days must be less or
equal to 2147483647",
                              "INSERT INTO %s (a, b, c) VALUES (1, 2, " + Long.MAX_VALUE +
"d)");
 
+        assertInvalidMessage("The duration months, days and nanoseconds must be all of the
same sign (2, -2, 0)",
+                             "INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 2, 1, duration(2,
-2, 0));
+
+        assertInvalidMessage("The duration months, days and nanoseconds must be all of the
same sign (-2, 0, 2000000)",
+                             "INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 2, 1, duration(-2,
0, 2000000));
+
         // Test with duration column name
         createTable("CREATE TABLE %s (a text PRIMARY KEY, duration duration);");
 
@@ -216,6 +229,17 @@ public class CreateTest extends CQLTester
                 "CREATE TABLE %s(pk int, m frozen<map<text, list<tuple<int, duration>>>>,
v int, PRIMARY KEY (pk, m))");
     }
 
+    private ByteBuffer duration(int months, int days, long nanoseconds) throws IOException
+    {
+        try(DataOutputBuffer output = new DataOutputBuffer())
+        {
+            output.writeVInt(months);
+            output.writeVInt(days);
+            output.writeVInt(nanoseconds);
+            return output.buffer();
+        }
+    }
+
     /**
      * Creation and basic operations on a static table,
      * migrated from cql_tests.py:TestCQL.static_cf_test()


Mime
View raw message