Repository: cassandra
Updated Branches:
  refs/heads/trunk 00a34c791 -> 288ffca73


Fix IOOBE when inserting bad tuple w/ string literal

Patch by Benjamin Lerer; reviewed by Tyler Hobbs for CASSANDRA-9559


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

Branch: refs/heads/trunk
Commit: c233270643d0a887dc84ae90573176eb52f8ca93
Parents: 1119983
Author: blerer <benjamin.le...@datastax.com>
Authored: Fri Jun 26 12:25:05 2015 -0500
Committer: Tyler Hobbs <tylerlho...@gmail.com>
Committed: Fri Jun 26 12:25:05 2015 -0500

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 ++
 .../apache/cassandra/db/marshal/TupleType.java  |  9 +++++--
 .../cql3/validation/entities/TupleTypeTest.java | 27 +++++++++++++++++++-
 3 files changed, 35 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/c2332706/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 7f4ca28..874c8ee 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,6 @@
 2.1.8
+ * Fix IndexOutOfBoundsException when inserting tuple with too many
+   elements using the string literal notation (CASSANDRA-9559)
  * Allow JMX over SSL directly from nodetool (CASSANDRA-9090)
  * Fix incorrect result for IN queries where column not found (CASSANDRA-9540)
  * Enable describe on indices (CASSANDRA-7814)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c2332706/src/java/org/apache/cassandra/db/marshal/TupleType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/TupleType.java 
b/src/java/org/apache/cassandra/db/marshal/TupleType.java
index ddaf53f..e07319b 100644
--- a/src/java/org/apache/cassandra/db/marshal/TupleType.java
+++ b/src/java/org/apache/cassandra/db/marshal/TupleType.java
@@ -18,18 +18,18 @@
 package org.apache.cassandra.db.marshal;
 
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
 import com.google.common.base.Objects;
 
+import org.apache.cassandra.exceptions.InvalidRequestException;
+
 import org.apache.cassandra.cql3.CQL3Type;
 import org.apache.cassandra.exceptions.ConfigurationException;
 import org.apache.cassandra.exceptions.SyntaxException;
 import org.apache.cassandra.serializers.*;
 import org.apache.cassandra.utils.ByteBufferUtil;
-import org.apache.cassandra.utils.Pair;
 
 /**
  * This is essentially like a CompositeType, but it's not primarily meant for 
comparison, just
@@ -212,6 +212,11 @@ public class TupleType extends AbstractType<ByteBuffer>
     {
         // Split the input on non-escaped ':' characters
         List<String> fieldStrings = AbstractCompositeType.split(source);
+
+        if (fieldStrings.size() > size())
+            throw new MarshalException(String.format("Invalid tuple literal: 
too many elements. Type %s expects %d but got %d",
+                                                     asCQL3Type(), size(), 
fieldStrings.size()));
+
         ByteBuffer[] fields = new ByteBuffer[fieldStrings.size()];
         for (int i = 0; i < fieldStrings.size(); i++)
         {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c2332706/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java 
b/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
index 2d145de..177def7 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
@@ -92,12 +92,37 @@ public class TupleTypeTest extends CQLTester
     }
 
     @Test
+    public void testTupleFromString() throws Throwable
+    {
+        createTable("CREATE TABLE %s (k int, c int, t frozen<tuple<int, 
text>>, PRIMARY KEY (k, c))");
+
+        execute("INSERT INTO %s (k, c, t) VALUES (0, 0, '0:0')");
+        execute("INSERT INTO %s (k, c, t) VALUES (0, 1, '0:1')");
+        execute("INSERT INTO %s (k, c, t) VALUES (0, 2, '1')");
+        execute("INSERT INTO %s (k, c, t) VALUES (0, 3, '1:1\\:1')");
+        execute("INSERT INTO %s (k, c, t) VALUES (0, 4, '@:1')");
+
+        assertAllRows(
+            row(0, 0, tuple(0, "0")),
+            row(0, 1, tuple(0, "1")),
+            row(0, 2, tuple(1)),
+            row(0, 3, tuple(1, "1:1")),
+            row(0, 4, tuple(null, "1"))
+        );
+
+        assertInvalidMessage("Invalid tuple literal: too many elements. Type 
tuple<int, text> expects 2 but got 3",
+                             "INSERT INTO %s(k, t) VALUES (1,'1:2:3')");
+    }
+
+    @Test
     public void testInvalidQueries() throws Throwable
     {
         createTable("CREATE TABLE %s (k int PRIMARY KEY, t frozen<tuple<int, 
text, double>>)");
 
         assertInvalidSyntax("INSERT INTO %s (k, t) VALUES (0, ())");
-        assertInvalid("INSERT INTO %s (k, t) VALUES (0, (2, 'foo', 3.1, 
'bar'))");
+
+        assertInvalidMessage("Invalid tuple literal for t: too many elements. 
Type tuple<int, text, double> expects 3 but got 4",
+                             "INSERT INTO %s (k, t) VALUES (0, (2, 'foo', 3.1, 
'bar'))");
     }
 
     /**

Reply via email to