You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2014/08/09 13:42:27 UTC

[02/12] 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/4f475d12
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/4f475d12
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/4f475d12

Branch: refs/heads/cassandra-2.1.0
Commit: 4f475d12e99f6760f139cf7fcb031a31152c2ff7
Parents: 6fdcd3b
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 10:20:22 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/4f475d12/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index df40933..b03e250 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.0.10
+ * 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/4f475d12/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/4f475d12/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 3abf65e..66e498f 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());
             }
-            return fun.execute(buffers);
+
+            return executeInternal(fun, buffers);
         }
 
         public boolean isAssignableTo(ColumnSpecification receiver)