Skip to content

Commit e9433f7

Browse files
committed
added +
1 parent 6ad8569 commit e9433f7

2 files changed

Lines changed: 7 additions & 1 deletion

File tree

src/java/org/apache/cassandra/db/ColumnFamilyStore.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2066,10 +2066,12 @@ private void validateSnapshotName(String snapshotName)
20662066
// Allowed characters are a conservative subset of the AWS S3 "Safe characters" set
20672067
// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-guidelines):
20682068
// 0-9 a-z A-Z - _ .
2069+
// plus '+', which is not an S3 "Safe character" but can legitimately appear in system
2070+
// snapshot names via version build metadata (e.g. an upgrade snapshot "<millis>-upgrade-5.0.4+build-...").
20692071
// The remaining S3-safe characters (! * ' ( )) are intentionally excluded as they are
20702072
// shell-significant and error-prone in paths, and the path separator '/' is excluded too,
20712073
// which is what blocks traversal attempts such as "../../mysnapshot"
2072-
if (!Pattern.compile("[a-zA-Z0-9_.-]+").matcher(snapshotName).matches())
2074+
if (!Pattern.compile("[a-zA-Z0-9_.+-]+").matcher(snapshotName).matches())
20732075
{
20742076
throw new IllegalArgumentException("Snapshot name contains illegal characters: " + snapshotName);
20752077
}

test/unit/org/apache/cassandra/db/SnapshotTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ public void testSnapshotNameValidation()
7878
// Dots embedded in a name are not traversal: with '/' excluded, "a..tag" is just a literal directory.
7979
assertThatCode(() -> cfs.snapshot("a..tag")).doesNotThrowAnyException();
8080

81+
// "+" is part of the allowed set because it can appear in a Cassandra version
82+
// (build metadata, e.g. "7.0.0+abc123"), which ends up in system snapshot names.
83+
assertThatCode(() -> cfs.snapshot("this_is_snapshot-7.0.0+abc123")).doesNotThrowAnyException();
84+
8185
String tooLong = repeat('a', SchemaConstants.FILENAME_LENGTH + 1);
8286
assertThatThrownBy(() -> cfs.snapshot(tooLong))
8387
.isInstanceOf(IllegalArgumentException.class)

0 commit comments

Comments
 (0)