mirror of https://github.com/apache/cassandra
Bytecode inspection for Java-UDFs
patch by Robert Stupp; reviewed by T Jake Luciani for CASSANDRA-9890
This commit is contained in:
parent
a22ce89e86
commit
1774eb9a86
|
|
@ -1,5 +1,5 @@
|
|||
3.0
|
||||
* Implement proper sandboxing for UDFs (CASSANDRA-9402)
|
||||
* Implement proper sandboxing for UDFs (CASSANDRA-9402, 9890)
|
||||
* Simplify (and unify) cleanup of compaction leftovers (CASSANDRA-7066)
|
||||
* Allow extra schema definitions in cassandra-stress yaml (CASSANDRA-9850)
|
||||
* Metrics should use up to date nomenclature (CASSANDRA-9448)
|
||||
|
|
|
|||
|
|
@ -79,3 +79,7 @@ Protocol buffers for varint encoding
|
|||
https://developers.google.com/protocol-buffers/
|
||||
Copyright 2008 Google Inc. All rights reserved.
|
||||
BSD 3-clause
|
||||
|
||||
ASM
|
||||
(http://asm.ow2.org/)
|
||||
Copyright (c) 2000-2011 INRIA, France Telecom
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,29 @@
|
|||
Copyright (c) 2000-2011 INRIA, France Telecom
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holders nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -38,9 +38,11 @@ import java.security.cert.Certificate;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
|
@ -90,6 +92,8 @@ final class JavaBasedUDFunction extends UDFunction
|
|||
|
||||
private static final EcjTargetClassLoader targetClassLoader = new EcjTargetClassLoader();
|
||||
|
||||
private static final UDFByteCodeVerifier udfByteCodeVerifier = new UDFByteCodeVerifier();
|
||||
|
||||
private static final ProtectionDomain protectionDomain;
|
||||
|
||||
private static final IErrorHandlingPolicy errorHandlingPolicy = DefaultErrorHandlingPolicies.proceedWithAllProblems();
|
||||
|
|
@ -105,6 +109,24 @@ final class JavaBasedUDFunction extends UDFunction
|
|||
|
||||
static
|
||||
{
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/Class", "forName");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/Class", "getClassLoader");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/Class", "getResource");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/Class", "getResourceAsStream");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "clearAssertionStatus");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "getResource");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "getResourceAsStream");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "getResources");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "getSystemClassLoader");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "getSystemResource");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "getSystemResourceAsStream");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "getSystemResources");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "loadClass");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "setClassAssertionStatus");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "setDefaultAssertionStatus");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/lang/ClassLoader", "setPackageAssertionStatus");
|
||||
udfByteCodeVerifier.addDisallowedMethodCall("java/nio/ByteBuffer", "allocateDirect");
|
||||
|
||||
Map<String, String> settings = new HashMap<>();
|
||||
settings.put(CompilerOptions.OPTION_LineNumberAttribute,
|
||||
CompilerOptions.GENERATE);
|
||||
|
|
@ -172,6 +194,8 @@ final class JavaBasedUDFunction extends UDFunction
|
|||
String pkgName = BASE_PACKAGE + '.' + generateClassName(name, 'p');
|
||||
String clsName = generateClassName(name, 'C');
|
||||
|
||||
String executeInternalName = generateClassName(name, 'x');
|
||||
|
||||
StringBuilder javaSourceBuilder = new StringBuilder();
|
||||
int lineOffset = 1;
|
||||
for (int i = 0; i < javaSourceTemplate.length; i++)
|
||||
|
|
@ -202,6 +226,9 @@ final class JavaBasedUDFunction extends UDFunction
|
|||
case "return_type":
|
||||
s = javaSourceName(javaReturnType);
|
||||
break;
|
||||
case "execute_internal_name":
|
||||
s = executeInternalName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -262,6 +289,23 @@ final class JavaBasedUDFunction extends UDFunction
|
|||
throw new InvalidRequestException("Java source compilation failed:\n" + problems);
|
||||
}
|
||||
|
||||
// Verify the UDF bytecode against use of probably dangerous code
|
||||
Set<String> errors = udfByteCodeVerifier.verify(targetClassLoader.classData(targetClassName));
|
||||
String validDeclare = "not allowed method declared: " + executeInternalName + '(';
|
||||
String validCall = "call to " + targetClassName.replace('.', '/') + '.' + executeInternalName + "()";
|
||||
for (Iterator<String> i = errors.iterator(); i.hasNext();)
|
||||
{
|
||||
String error = i.next();
|
||||
// we generate a random name of the private, internal execute method, which is detected by the byte-code verifier
|
||||
if (error.startsWith(validDeclare) || error.equals(validCall))
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
if (!errors.isEmpty())
|
||||
throw new InvalidRequestException("Java UDF validation failed: " + errors);
|
||||
|
||||
// Load the class and create a new instance of it
|
||||
Thread thread = Thread.currentThread();
|
||||
ClassLoader orig = thread.getContextClassLoader();
|
||||
try
|
||||
|
|
@ -269,7 +313,7 @@ final class JavaBasedUDFunction extends UDFunction
|
|||
thread.setContextClassLoader(UDFunction.udfClassLoader);
|
||||
// Execute UDF intiialization from UDF class loader
|
||||
|
||||
Class cls = targetClassLoader.loadClass(targetClassName);
|
||||
Class cls = Class.forName(targetClassName, false, targetClassLoader);
|
||||
|
||||
if (cls.getDeclaredMethods().length != 2 || cls.getDeclaredConstructors().length != 1)
|
||||
throw new InvalidRequestException("Check your source to not define additional Java methods or constructors");
|
||||
|
|
@ -382,7 +426,7 @@ final class JavaBasedUDFunction extends UDFunction
|
|||
|
||||
private static String composeMethod(Class<?> type)
|
||||
{
|
||||
return (type.isPrimitive()) ? ("compose_" + type.getName()) : "compose";
|
||||
return (type.isPrimitive()) ? ("super.compose_" + type.getName()) : "super.compose";
|
||||
}
|
||||
|
||||
// Java source UDFs are a very simple compilation task, which allows us to let one class implement
|
||||
|
|
@ -578,6 +622,11 @@ final class JavaBasedUDFunction extends UDFunction
|
|||
classes.put(className, classData);
|
||||
}
|
||||
|
||||
byte[] classData(String className)
|
||||
{
|
||||
return classes.get(className);
|
||||
}
|
||||
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
// remove the class binary - it's only used once - so it's wasting heap
|
||||
|
|
|
|||
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.functions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.Handle;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
/**
|
||||
* Verifies Java UDF byte code.
|
||||
* Checks for disallowed method calls (e.g. {@code Object.finalize()}),
|
||||
* additional code in the constructor,
|
||||
* use of {@code synchronized} blocks,
|
||||
* too many methods.
|
||||
*/
|
||||
public final class UDFByteCodeVerifier
|
||||
{
|
||||
|
||||
public static final String JAVA_UDF_NAME = JavaUDF.class.getName().replace('.', '/');
|
||||
public static final String OBJECT_NAME = Object.class.getName().replace('.', '/');
|
||||
public static final String CTOR_SIG = "(Lcom/datastax/driver/core/DataType;[Lcom/datastax/driver/core/DataType;)V";
|
||||
|
||||
private final Multimap<String, String> disallowedMethodCalls = HashMultimap.create();
|
||||
private final List<String> disallowedPackages = new ArrayList<>();
|
||||
|
||||
public UDFByteCodeVerifier()
|
||||
{
|
||||
addDisallowedMethodCall(OBJECT_NAME, "clone");
|
||||
addDisallowedMethodCall(OBJECT_NAME, "finalize");
|
||||
addDisallowedMethodCall(OBJECT_NAME, "notify");
|
||||
addDisallowedMethodCall(OBJECT_NAME, "notifyAll");
|
||||
addDisallowedMethodCall(OBJECT_NAME, "wait");
|
||||
}
|
||||
|
||||
public UDFByteCodeVerifier addDisallowedMethodCall(String clazz, String method)
|
||||
{
|
||||
disallowedMethodCalls.put(clazz, method);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UDFByteCodeVerifier addDisallowedPackage(String pkg)
|
||||
{
|
||||
disallowedPackages.add(pkg);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Set<String> verify(byte[] bytes)
|
||||
{
|
||||
Set<String> errors = new TreeSet<>(); // it's a TreeSet for unit tests
|
||||
ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM5)
|
||||
{
|
||||
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
|
||||
{
|
||||
errors.add("field declared: " + name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
|
||||
{
|
||||
if ("<init>".equals(name) && CTOR_SIG.equals(desc))
|
||||
{
|
||||
if (Opcodes.ACC_PUBLIC != access)
|
||||
errors.add("constructor not public");
|
||||
// allowed constructor - JavaUDF(DataType returnDataType, DataType[] argDataTypes)
|
||||
return new ConstructorVisitor(errors);
|
||||
}
|
||||
if ("executeImpl".equals(name) && "(ILjava/util/List;)Ljava/nio/ByteBuffer;".equals(desc))
|
||||
{
|
||||
if (Opcodes.ACC_PROTECTED != access)
|
||||
errors.add("executeImpl not protected");
|
||||
// the executeImpl method - ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
return new ExecuteImplVisitor(errors);
|
||||
}
|
||||
if ("<clinit>".equals(name))
|
||||
{
|
||||
errors.add("static initializer declared");
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.add("not allowed method declared: " + name + desc);
|
||||
return new ExecuteImplVisitor(errors);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
if (!JAVA_UDF_NAME.equals(superName))
|
||||
{
|
||||
errors.add("class does not extend " + JavaUDF.class.getName());
|
||||
}
|
||||
if (access != (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_SUPER))
|
||||
{
|
||||
errors.add("class not public final");
|
||||
}
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
public void visitInnerClass(String name, String outerName, String innerName, int access)
|
||||
{
|
||||
errors.add("class declared as inner class");
|
||||
super.visitInnerClass(name, outerName, innerName, access);
|
||||
}
|
||||
};
|
||||
|
||||
ClassReader classReader = new ClassReader(bytes);
|
||||
classReader.accept(classVisitor, ClassReader.SKIP_DEBUG);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
private class ExecuteImplVisitor extends MethodVisitor
|
||||
{
|
||||
private final Set<String> errors;
|
||||
|
||||
ExecuteImplVisitor(Set<String> errors)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf)
|
||||
{
|
||||
Collection<String> disallowed = disallowedMethodCalls.get(owner);
|
||||
if (disallowed != null && disallowed.contains(name))
|
||||
{
|
||||
errors.add("call to " + name + "()");
|
||||
}
|
||||
if (!JAVA_UDF_NAME.equals(owner))
|
||||
{
|
||||
for (String pkg : disallowedPackages)
|
||||
{
|
||||
if (owner.startsWith(pkg))
|
||||
errors.add("call to " + owner + '.' + name + "()");
|
||||
}
|
||||
}
|
||||
super.visitMethodInsn(opcode, owner, name, desc, itf);
|
||||
}
|
||||
|
||||
public void visitInsn(int opcode)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case Opcodes.MONITORENTER:
|
||||
case Opcodes.MONITOREXIT:
|
||||
errors.add("use of synchronized");
|
||||
break;
|
||||
}
|
||||
super.visitInsn(opcode);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConstructorVisitor extends MethodVisitor
|
||||
{
|
||||
private final Set<String> errors;
|
||||
|
||||
ConstructorVisitor(Set<String> errors)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs)
|
||||
{
|
||||
errors.add("Use of invalid method instruction in constructor");
|
||||
super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
|
||||
}
|
||||
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf)
|
||||
{
|
||||
if (!(Opcodes.INVOKESPECIAL == opcode && JAVA_UDF_NAME.equals(owner) && "<init>".equals(name) && CTOR_SIG.equals(desc)))
|
||||
{
|
||||
errors.add("initializer declared");
|
||||
}
|
||||
super.visitMethodInsn(opcode, owner, name, desc, itf);
|
||||
}
|
||||
|
||||
public void visitInsn(int opcode)
|
||||
{
|
||||
if (Opcodes.RETURN != opcode)
|
||||
{
|
||||
errors.add("initializer declared");
|
||||
}
|
||||
super.visitInsn(opcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -113,6 +113,7 @@ public abstract class UDFunction extends AbstractFunction implements ScalarFunct
|
|||
"com/datastax/driver/core/Statement.class",
|
||||
"com/datastax/driver/core/TimestampGenerator.class", // indirectly covers ServerSideTimestampGenerator + ThreadLocalMonotonicTimestampGenerator
|
||||
"java/lang/Compiler.class",
|
||||
"java/lang/InheritableThreadLocal.class",
|
||||
"java/lang/Package.class",
|
||||
"java/lang/Process.class",
|
||||
"java/lang/ProcessBuilder.class",
|
||||
|
|
|
|||
|
|
@ -14,15 +14,15 @@ public final class #class_name# extends JavaUDF
|
|||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
public ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
#return_type# result = executeInternal(
|
||||
#return_type# result = #execute_internal_name#(
|
||||
#arguments#
|
||||
);
|
||||
return decompose(protocolVersion, result);
|
||||
return super.decompose(protocolVersion, result);
|
||||
}
|
||||
|
||||
private #return_type# executeInternal(#argument_list#)
|
||||
private #return_type# #execute_internal_name#(#argument_list#)
|
||||
{
|
||||
#body#
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.cassandra.cql3.CQLTester;
|
||||
import org.apache.cassandra.cql3.functions.UDFByteCodeVerifier;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.CallClone;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.CallComDatastax;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.CallFinalize;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.CallOrgApache;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithField;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithInitializer;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithInitializer2;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithInitializer3;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithStaticInitializer;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.GoodClass;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronized;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronizedWithNotify;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronizedWithNotifyAll;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronizedWithWait;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronizedWithWaitL;
|
||||
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronizedWithWaitLI;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Test the Java UDF byte code verifier.
|
||||
*/
|
||||
public class UFVerifierTest extends CQLTester
|
||||
{
|
||||
@Test
|
||||
public void testByteCodeVerifier()
|
||||
{
|
||||
new UDFByteCodeVerifier().verify(readClass(GoodClass.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassWithField()
|
||||
{
|
||||
assertEquals(new HashSet<>(Collections.singletonList("field declared: field")),
|
||||
new UDFByteCodeVerifier().verify(readClass(ClassWithField.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassWithInitializer()
|
||||
{
|
||||
assertEquals(new HashSet<>(Arrays.asList("field declared: field",
|
||||
"initializer declared")),
|
||||
new UDFByteCodeVerifier().verify(readClass(ClassWithInitializer.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassWithInitializer2()
|
||||
{
|
||||
assertEquals(new HashSet<>(Arrays.asList("field declared: field",
|
||||
"initializer declared")),
|
||||
new UDFByteCodeVerifier().verify(readClass(ClassWithInitializer2.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassWithInitializer3()
|
||||
{
|
||||
assertEquals(new HashSet<>(Collections.singletonList("initializer declared")),
|
||||
new UDFByteCodeVerifier().verify(readClass(ClassWithInitializer3.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassWithStaticInitializer()
|
||||
{
|
||||
assertEquals(new HashSet<>(Collections.singletonList("static initializer declared")),
|
||||
new UDFByteCodeVerifier().verify(readClass(ClassWithStaticInitializer.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseOfSynchronized()
|
||||
{
|
||||
assertEquals(new HashSet<>(Collections.singletonList("use of synchronized")),
|
||||
new UDFByteCodeVerifier().verify(readClass(UseOfSynchronized.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseOfSynchronizedWithNotify()
|
||||
{
|
||||
assertEquals(new HashSet<>(Arrays.asList("use of synchronized", "call to notify()")),
|
||||
new UDFByteCodeVerifier().verify(readClass(UseOfSynchronizedWithNotify.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseOfSynchronizedWithNotifyAll()
|
||||
{
|
||||
assertEquals(new HashSet<>(Arrays.asList("use of synchronized", "call to notifyAll()")),
|
||||
new UDFByteCodeVerifier().verify(readClass(UseOfSynchronizedWithNotifyAll.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseOfSynchronizedWithWait()
|
||||
{
|
||||
assertEquals(new HashSet<>(Arrays.asList("use of synchronized", "call to wait()")),
|
||||
new UDFByteCodeVerifier().verify(readClass(UseOfSynchronizedWithWait.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseOfSynchronizedWithWaitL()
|
||||
{
|
||||
assertEquals(new HashSet<>(Arrays.asList("use of synchronized", "call to wait()")),
|
||||
new UDFByteCodeVerifier().verify(readClass(UseOfSynchronizedWithWaitL.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseOfSynchronizedWithWaitI()
|
||||
{
|
||||
assertEquals(new HashSet<>(Arrays.asList("use of synchronized", "call to wait()")),
|
||||
new UDFByteCodeVerifier().verify(readClass(UseOfSynchronizedWithWaitLI.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallClone()
|
||||
{
|
||||
assertEquals(new HashSet<>(Collections.singletonList("call to clone()")),
|
||||
new UDFByteCodeVerifier().verify(readClass(CallClone.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallFinalize()
|
||||
{
|
||||
assertEquals(new HashSet<>(Collections.singletonList("call to finalize()")),
|
||||
new UDFByteCodeVerifier().verify(readClass(CallFinalize.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallComDatastax()
|
||||
{
|
||||
assertEquals(new HashSet<>(Collections.singletonList("call to com/datastax/driver/core/DataType.cint()")),
|
||||
new UDFByteCodeVerifier().addDisallowedPackage("com/").verify(readClass(CallComDatastax.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallOrgApache()
|
||||
{
|
||||
assertEquals(new HashSet<>(Collections.singletonList("call to org/apache/cassandra/config/DatabaseDescriptor.getClusterName()")),
|
||||
new UDFByteCodeVerifier().addDisallowedPackage("org/").verify(readClass(CallOrgApache.class)));
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
private static byte[] readClass(Class<?> clazz)
|
||||
{
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
URL res = clazz.getClassLoader().getResource(clazz.getName().replace('.', '/') + ".class");
|
||||
assert res != null;
|
||||
try (InputStream input = res.openConnection().getInputStream())
|
||||
{
|
||||
int i;
|
||||
while ((i = input.read()) != -1)
|
||||
out.write(i);
|
||||
return out.toByteArray();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidByteCodeUDFs() throws Throwable
|
||||
{
|
||||
assertInvalidByteCode("try\n" +
|
||||
"{\n" +
|
||||
" clone();\n" +
|
||||
"}\n" +
|
||||
"catch (CloneNotSupportedException e)\n" +
|
||||
"{\n" +
|
||||
" throw new RuntimeException(e);\n" +
|
||||
"}\n" +
|
||||
"return 0d;", "Java UDF validation failed: [call to clone()]");
|
||||
assertInvalidByteCode("try\n" +
|
||||
"{\n" +
|
||||
" finalize();\n" +
|
||||
"}\n" +
|
||||
"catch (Throwable e)\n" +
|
||||
"{\n" +
|
||||
" throw new RuntimeException(e);\n" +
|
||||
"}\n" +
|
||||
"return 0d;", "Java UDF validation failed: [call to finalize()]");
|
||||
assertInvalidByteCode('\n' +
|
||||
"return 0d;\n" +
|
||||
" }\n" +
|
||||
'\n' +
|
||||
" Object field;\n" +
|
||||
'\n' +
|
||||
" {", "Java UDF validation failed: [field declared: field]");
|
||||
assertInvalidByteCode('\n' +
|
||||
"return 0d;\n" +
|
||||
" }\n" +
|
||||
'\n' +
|
||||
" final Object field;\n" +
|
||||
'\n' +
|
||||
" {\n" +
|
||||
"field = new Object();", "Java UDF validation failed: [field declared: field, initializer declared]");
|
||||
assertInvalidByteCode('\n' +
|
||||
"return 0d;\n" +
|
||||
" }\n" +
|
||||
'\n' +
|
||||
" Object field = new Object();\n" +
|
||||
'\n' +
|
||||
" {\n" +
|
||||
"Math.sin(1d);", "Java UDF validation failed: [field declared: field, initializer declared]");
|
||||
assertInvalidByteCode('\n' +
|
||||
"return 0d;\n" +
|
||||
" }\n" +
|
||||
'\n' +
|
||||
" {\n" +
|
||||
"Math.sin(1d);", "Java UDF validation failed: [initializer declared]");
|
||||
assertInvalidByteCode('\n' +
|
||||
"return 0d;\n" +
|
||||
" }\n" +
|
||||
'\n' +
|
||||
" static\n" +
|
||||
" {\n" +
|
||||
"Math.sin(1d);", "Java UDF validation failed: [static initializer declared]");
|
||||
assertInvalidByteCode("synchronized (this)\n" +
|
||||
"{\n" +
|
||||
" Math.sin(1d);\n" +
|
||||
"}\n" +
|
||||
"return 0d;", "Java UDF validation failed: [use of synchronized]");
|
||||
assertInvalidByteCode("synchronized (this)\n" +
|
||||
"{\n" +
|
||||
" notify();\n" +
|
||||
"}\n" +
|
||||
"return 0d;", "Java UDF validation failed: [call to notify(), use of synchronized]");
|
||||
assertInvalidByteCode("synchronized (this)\n" +
|
||||
"{\n" +
|
||||
" notifyAll();\n" +
|
||||
"}\n" +
|
||||
"return 0d;", "Java UDF validation failed: [call to notifyAll(), use of synchronized]");
|
||||
assertInvalidByteCode("synchronized (this)\n" +
|
||||
"{\n" +
|
||||
" try\n" +
|
||||
" {\n" +
|
||||
" wait();\n" +
|
||||
" }\n" +
|
||||
" catch (InterruptedException e)\n" +
|
||||
" {\n" +
|
||||
" throw new RuntimeException(e);\n" +
|
||||
" }\n" +
|
||||
"}\n" +
|
||||
"return 0d;", "Java UDF validation failed: [call to wait(), use of synchronized]");
|
||||
assertInvalidByteCode("synchronized (this)\n" +
|
||||
"{\n" +
|
||||
" try\n" +
|
||||
" {\n" +
|
||||
" wait(1000L);\n" +
|
||||
" }\n" +
|
||||
" catch (InterruptedException e)\n" +
|
||||
" {\n" +
|
||||
" throw new RuntimeException(e);\n" +
|
||||
" }\n" +
|
||||
"}\n" +
|
||||
"return 0d;", "Java UDF validation failed: [call to wait(), use of synchronized]");
|
||||
assertInvalidByteCode("synchronized (this)\n" +
|
||||
"{\n" +
|
||||
" try\n" +
|
||||
" {\n" +
|
||||
" wait(1000L, 100);\n" +
|
||||
" }\n" +
|
||||
" catch (InterruptedException e)\n" +
|
||||
" {\n" +
|
||||
" throw new RuntimeException(e);\n" +
|
||||
" }\n" +
|
||||
"}\n" +
|
||||
"return 0d;", "Java UDF validation failed: [call to wait(), use of synchronized]");
|
||||
}
|
||||
|
||||
private void assertInvalidByteCode(String body, String error) throws Throwable
|
||||
{
|
||||
assertInvalidMessage(error,
|
||||
"CREATE FUNCTION " + KEYSPACE + ".mustBeInvalid ( input double ) " +
|
||||
"CALLED ON NULL INPUT " +
|
||||
"RETURNS double " +
|
||||
"LANGUAGE java AS $$" + body + "$$");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class CallClone extends JavaUDF
|
||||
{
|
||||
public CallClone(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
try
|
||||
{
|
||||
clone();
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class CallComDatastax extends JavaUDF
|
||||
{
|
||||
public CallComDatastax(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
DataType.cint();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class CallFinalize extends JavaUDF
|
||||
{
|
||||
public CallFinalize(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
try
|
||||
{
|
||||
finalize();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class CallOrgApache extends JavaUDF
|
||||
{
|
||||
public CallOrgApache(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
DatabaseDescriptor.getClusterName();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class ClassWithField extends JavaUDF
|
||||
{
|
||||
public ClassWithField(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Object field;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class ClassWithInitializer extends JavaUDF
|
||||
{
|
||||
public ClassWithInitializer(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Object field;
|
||||
|
||||
{
|
||||
field = new Object();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class ClassWithInitializer2 extends JavaUDF
|
||||
{
|
||||
public ClassWithInitializer2(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Object field = new Object();
|
||||
|
||||
{
|
||||
Math.sin(1d);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class ClassWithInitializer3 extends JavaUDF
|
||||
{
|
||||
public ClassWithInitializer3(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
{
|
||||
Math.sin(1d);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class ClassWithStaticInitializer extends JavaUDF
|
||||
{
|
||||
public ClassWithStaticInitializer(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
Math.sin(1d);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class GoodClass extends JavaUDF
|
||||
{
|
||||
public GoodClass(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class UseOfSynchronized extends JavaUDF
|
||||
{
|
||||
public UseOfSynchronized(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
Math.sin(1d);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class UseOfSynchronizedWithNotify extends JavaUDF
|
||||
{
|
||||
public UseOfSynchronizedWithNotify(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
notify();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class UseOfSynchronizedWithNotifyAll extends JavaUDF
|
||||
{
|
||||
public UseOfSynchronizedWithNotifyAll(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
notifyAll();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class UseOfSynchronizedWithWait extends JavaUDF
|
||||
{
|
||||
public UseOfSynchronizedWithWait(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
try
|
||||
{
|
||||
wait();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class UseOfSynchronizedWithWaitL extends JavaUDF
|
||||
{
|
||||
public UseOfSynchronizedWithWaitL(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
try
|
||||
{
|
||||
wait(1000L);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cassandra.cql3.validation.entities.udfverify;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import com.datastax.driver.core.DataType;
|
||||
import org.apache.cassandra.cql3.functions.JavaUDF;
|
||||
|
||||
/**
|
||||
* Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
|
||||
*/
|
||||
public final class UseOfSynchronizedWithWaitLI extends JavaUDF
|
||||
{
|
||||
public UseOfSynchronizedWithWaitLI(DataType returnDataType, DataType[] argDataTypes)
|
||||
{
|
||||
super(returnDataType, argDataTypes);
|
||||
}
|
||||
|
||||
protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
try
|
||||
{
|
||||
wait(1000L, 100);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue