You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by al...@apache.org on 2014/08/11 00:07:50 UTC

[05/17] git commit: Validate arguments of blobAs functions

Validate arguments of blobAs functions

patch by slebresne; reviewed by thobbs for CASSANDRA-7707


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

Branch: refs/heads/cassandra-2.1
Commit: b70eaf380a4560e2d241125c8c71fa23fee4877f
Parents: 9399940
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Fri Aug 8 10:20:22 2014 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Fri Aug 8 17:45:46 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cql3/functions/BytesConversionFcts.java     | 22 +++++++++++++++----
 .../cassandra/cql3/functions/FunctionCall.java  | 23 ++++++++++++++++++--
 3 files changed, 40 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/b70eaf38/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 9ebb8cd..2c2ab71 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -6,6 +6,7 @@
  * Fix UDT field selection with empty fields (CASSANDRA-7670)
  * Bogus deserialization of static cells from sstable (CASSANDRA-7684)
 Merged from 2.0:
+ * Validate arguments of blobAs* functions (CASSANDRA-7707)
  * Fix potential AssertionError with 2ndary indexes (CASSANDRA-6612)
  * Avoid logging CompactionInterrupted at ERROR (CASSANDRA-7694)
  * Minor leak in sstable2jon (CASSANDRA-7709)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/b70eaf38/src/java/org/apache/cassandra/cql3/functions/BytesConversionFcts.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/BytesConversionFcts.java b/src/java/org/apache/cassandra/cql3/functions/BytesConversionFcts.java
index b30b5e7..e3023db 100644
--- a/src/java/org/apache/cassandra/cql3/functions/BytesConversionFcts.java
+++ b/src/java/org/apache/cassandra/cql3/functions/BytesConversionFcts.java
@@ -23,6 +23,9 @@ import java.util.List;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.db.marshal.BytesType;
 import org.apache.cassandra.db.marshal.UTF8Type;
+import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.serializers.MarshalException;
 
 public abstract class BytesConversionFcts
 {
@@ -40,14 +43,25 @@ public abstract class BytesConversionFcts
         };
     }
 
-    public static Function makeFromBlobFunction(AbstractType<?> toType)
+    public static Function makeFromBlobFunction(final AbstractType<?> toType)
     {
-        String name = "blobas" + toType.asCQL3Type();
+        final String name = "blobas" + toType.asCQL3Type();
         return new AbstractFunction(name, toType, BytesType.instance)
         {
-            public ByteBuffer execute(List<ByteBuffer> parameters)
+            public ByteBuffer execute(List<ByteBuffer> parameters) throws InvalidRequestException
             {
-                return parameters.get(0);
+                ByteBuffer val = parameters.get(0);
+                try
+                {
+                    if (val != null)
+                        toType.validate(val);
+                    return val;
+                }
+                catch (MarshalException e)
+                {
+                    throw new InvalidRequestException(String.format("In call to function %s, value 0x%s is not a valid binary representation for type %s",
+                                                                    name, ByteBufferUtil.bytesToHex(val), toType.asCQL3Type()));
+                }
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/b70eaf38/src/java/org/apache/cassandra/cql3/functions/FunctionCall.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/FunctionCall.java b/src/java/org/apache/cassandra/cql3/functions/FunctionCall.java
index a0c7447..4ae7c98 100644
--- a/src/java/org/apache/cassandra/cql3/functions/FunctionCall.java
+++ b/src/java/org/apache/cassandra/cql3/functions/FunctionCall.java
@@ -28,6 +28,8 @@ import org.apache.cassandra.db.marshal.ListType;
 import org.apache.cassandra.db.marshal.MapType;
 import org.apache.cassandra.db.marshal.SetType;
 import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.serializers.MarshalException;
 
 public class FunctionCall extends Term.NonTerminal
 {
@@ -63,8 +65,24 @@ public class FunctionCall extends Term.NonTerminal
                 throw new InvalidRequestException(String.format("Invalid null value for argument to %s", fun));
             buffers.add(val);
         }
+        return executeInternal(fun, buffers);
+    }
 
-        return fun.execute(buffers);
+    private static ByteBuffer executeInternal(Function fun, List<ByteBuffer> params) throws InvalidRequestException
+    {
+        ByteBuffer result = fun.execute(params);
+        try
+        {
+            // Check the method didn't lied on it's declared return type
+            if (result != null)
+                fun.returnType().validate(result);
+            return result;
+        }
+        catch (MarshalException e)
+        {
+            throw new RuntimeException(String.format("Return of function %s (%s) is not a valid value for its declared return type %s", 
+                                                     fun, ByteBufferUtil.bytesToHex(result), fun.returnType().asCQL3Type()));
+        }
     }
 
     public boolean containsBindMarker()
@@ -132,7 +150,8 @@ public class FunctionCall extends Term.NonTerminal
                 assert t instanceof Term.Terminal;
                 buffers.add(((Term.Terminal)t).get(QueryOptions.DEFAULT));
             }
-            return fun.execute(buffers);
+
+            return executeInternal(fun, buffers);
         }
 
         public boolean isAssignableTo(String keyspace, ColumnSpecification receiver)