public static void ValidateObjectKey(string?bucketName, KeyValidationMode mode) { if (TryValidateObjectKey(bucketName, mode, out ValidationStatus status)) { return; } throw status switch { ValidationStatus.WrongLength => new ArgumentException("Object keys must be less than 1024 characters in length", nameof(bucketName)), ValidationStatus.WrongFormat => new ArgumentException("Invalid character in object key. Only a-z, A-Z, 0-9 and !, -, _, ., *, ', ( and ) are allowed", nameof(bucketName)), ValidationStatus.NullInput => new ArgumentNullException(nameof(bucketName)), _ => new ArgumentException("Failed to validate key id") }; }
public static void ValidateObjectKey(string bucketName, KeyValidationMode mode) { Validator.RequireNotNull(bucketName, nameof(bucketName)); if (TryValidateObjectKey(bucketName, mode, out ValidationStatus status)) { return; } switch (status) { case ValidationStatus.WrongLength: throw new ArgumentException("Object keys must be less than 1024 characters in length", nameof(bucketName)); case ValidationStatus.WrongFormat: throw new ArgumentException("Invalid character in object key. Only a-z, A-Z, 0-9 and !, -, _, ., *, ', ( and ) are allowed", nameof(bucketName)); default: throw new ArgumentException("Failed to validate key id"); } }
public static bool TryValidateObjectKey(string objectKey, KeyValidationMode mode, out ValidationStatus status) { if (string.IsNullOrEmpty(objectKey)) { status = ValidationStatus.NullInput; return(false); } if (objectKey.Length > 1024) { status = ValidationStatus.WrongLength; return(false); } if (mode == KeyValidationMode.Unrestricted) { status = ValidationStatus.Ok; return(true); } foreach (char c in objectKey) { if (CharHelper.InRange(c, 'a', 'z')) { continue; } if (CharHelper.InRange(c, 'A', 'Z')) { continue; } if (CharHelper.InRange(c, '0', '9')) { continue; } //See https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html if (CharHelper.OneOf(c, '/', '!', '-', '_', '.', '*', '\'', '(', ')')) { continue; } //0xD800 to 0xDFFF are reserved code points in UTF-16. Since they will always be URL encoded to %EF%BF%BD (the � char) in UTF-8 if (CharHelper.InRange(c, '\uD800', '\uDFFF')) { status = ValidationStatus.WrongFormat; return(false); } if (mode == KeyValidationMode.SafeMode) { status = ValidationStatus.WrongFormat; return(false); } if (CharHelper.OneOf(c, '&', '$', '@', '=', ';', ':', '+', ' ', ',', '?')) { continue; } if (CharHelper.InRange(c, (char)0, (char)31) || c == (char)127) { continue; } if (mode == KeyValidationMode.AsciiMode) { status = ValidationStatus.WrongFormat; return(false); } if (CharHelper.OneOf(c, '\\', '{', '}', '^', '%', '`', '[', ']', '"', '<', '>', '~', '#', '|')) { continue; } if (CharHelper.InRange(c, (char)128, (char)255)) { continue; } if (mode == KeyValidationMode.ExtendedAsciiMode) { status = ValidationStatus.WrongFormat; return(false); } } status = ValidationStatus.Ok; return(true); }
public void ObjectKeyFailTest(string input, KeyValidationMode mode) { Assert.False(InputValidator.TryValidateObjectKey(input, mode, out _)); }
public void ObjectKeySuccessTest(string input, KeyValidationMode mode) { Assert.True(InputValidator.TryValidateObjectKey(input, mode, out _)); }