diff --git a/CHANGES.txt b/CHANGES.txt index f3ef292155..7863d56e3f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 1.1.6 + * preflight check ttl for maximum of 20 years (CASSANDRA-4771) * Fix HH to compact with correct gcBefore, which avoids wiping out undelivered hints (CASSANDRA-4772) * LCS will merge up to 32 L0 sstables as intended (CASSANDRA-4778) diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java index e47f7f2e5a..23d96e06f1 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java @@ -25,7 +25,7 @@ import java.util.concurrent.TimeoutException; import org.apache.cassandra.auth.Permission; import org.apache.cassandra.cql3.*; import org.apache.cassandra.db.IMutation; -import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.ExpiringColumn; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.StorageProxy; import org.apache.cassandra.thrift.ConsistencyLevel; @@ -70,6 +70,9 @@ public abstract class ModificationStatement extends CFStatement implements CQLSt if (timeToLive < 0) throw new InvalidRequestException("A TTL must be greater or equal to 0"); + if (timeToLive > ExpiringColumn.MAX_TTL) + throw new InvalidRequestException(String.format("ttl is too large. requested (%d) maximum (%d)", timeToLive, ExpiringColumn.MAX_TTL)); + ThriftValidation.validateConsistencyLevel(keyspace(), getConsistencyLevel(), RequestType.WRITE); } diff --git a/src/java/org/apache/cassandra/db/ExpiringColumn.java b/src/java/org/apache/cassandra/db/ExpiringColumn.java index 2eb981dbe0..fe1b57c236 100644 --- a/src/java/org/apache/cassandra/db/ExpiringColumn.java +++ b/src/java/org/apache/cassandra/db/ExpiringColumn.java @@ -43,6 +43,8 @@ import org.apache.cassandra.utils.HeapAllocator; */ public class ExpiringColumn extends Column { + public static final int MAX_TTL = 20 * 365 * 24 * 60 * 60; // 20 years in seconds + private final int localExpirationTime; private final int timeToLive; diff --git a/src/java/org/apache/cassandra/thrift/ThriftValidation.java b/src/java/org/apache/cassandra/thrift/ThriftValidation.java index fe5306009f..c673a9c9e6 100644 --- a/src/java/org/apache/cassandra/thrift/ThriftValidation.java +++ b/src/java/org/apache/cassandra/thrift/ThriftValidation.java @@ -29,15 +29,12 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.config.*; import org.apache.cassandra.db.*; import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.db.marshal.AsciiType; import org.apache.cassandra.db.marshal.MarshalException; -import org.apache.cassandra.db.marshal.TypeParser; import org.apache.cassandra.dht.IPartitioner; import org.apache.cassandra.dht.RandomPartitioner; import org.apache.cassandra.dht.Token; import org.apache.cassandra.locator.*; import org.apache.cassandra.service.StorageService; -import org.apache.cassandra.io.compress.CompressionParameters; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; @@ -337,12 +334,19 @@ public class ThriftValidation private static void validateTtl(Column column) throws InvalidRequestException { - if (column.isSetTtl() && column.ttl <= 0) + if (column.isSetTtl()) { - throw new InvalidRequestException("ttl must be positive"); + if (column.ttl <= 0) + throw new InvalidRequestException("ttl must be positive"); + + if (column.ttl > ExpiringColumn.MAX_TTL) + throw new InvalidRequestException(String.format("ttl is too large. requested (%d) maximum (%d)", column.ttl, ExpiringColumn.MAX_TTL)); + } + else + { + // if it's not set, then it should be zero -- here we are just checking to make sure Thrift doesn't change that contract with us. + assert column.ttl == 0; } - // if it's not set, then it should be zero -- here we are just checking to make sure Thrift doesn't change that contract with us. - assert column.isSetTtl() || column.ttl == 0; } public static void validateMutation(CFMetaData metadata, Mutation mut) @@ -441,7 +445,7 @@ public class ThriftValidation (isSubColumn ? metadata.subcolumnComparator : metadata.comparator).getString(column.name))); } - // Indexed column values cannot be larger than 64K. See CASSANDRA-3057/4240 for more details + // Indexed column values cannot be larger than 64K. See CASSANDRA-3057/4240 for more details if (!Table.open(metadata.ksName).getColumnFamilyStore(metadata.cfName).indexManager.validate(column)) throw new InvalidRequestException(String.format("Can't index column value of size %d for index %s in CF %s of KS %s", column.value.remaining(),