Prevent null values being added to CloudEventAttributes via the Add methods

Signed-off-by: Jon Skeet <jonskeet@google.com>
This commit is contained in:
Jon Skeet 2020-08-03 10:43:56 +01:00 committed by Jon Skeet
parent acafac096d
commit 0441d93593
4 changed files with 42 additions and 4 deletions

View File

@ -211,12 +211,21 @@ namespace CloudNative.CloudEvents
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
{
object value = item.Value;
// Note: can't throw ArgumentNullException as the null value is only part of the argument.
if (value is null)
{
throw new InvalidOperationException(Strings.ErrorCannotAddNullAttributeValue);
}
ValidateAndNormalize(item.Key, ref value);
dict.Add(item.Key, value);
}
void IDictionary<string, object>.Add(string key, object value)
{
if (value is null)
{
throw new ArgumentNullException(nameof(value), Strings.ErrorCannotAddNullAttributeValue);
}
ValidateAndNormalize(key, ref value);
dict.Add(key, value);
}
@ -266,7 +275,7 @@ namespace CloudNative.CloudEvents
return dict.TryGetValue(key, out value);
}
internal virtual bool ValidateAndNormalize(string key, ref object value)
private bool ValidateAndNormalize(string key, ref object value)
{
if (key.Equals(TypeAttributeName(this.SpecVersion), StringComparison.InvariantCultureIgnoreCase))
{
@ -297,7 +306,7 @@ namespace CloudNative.CloudEvents
}
else if (key.Equals(TimeAttributeName(this.SpecVersion), StringComparison.InvariantCultureIgnoreCase))
{
if (value is null || value is DateTime)
if (value is DateTime)
{
return true;
}
@ -343,7 +352,7 @@ namespace CloudNative.CloudEvents
}
else if (key.Equals(DataSchemaAttributeName(this.SpecVersion), StringComparison.InvariantCultureIgnoreCase))
{
if (value is null || value is Uri)
if (value is Uri)
{
return true;
}
@ -361,7 +370,7 @@ namespace CloudNative.CloudEvents
}
else if (key.Equals(DataContentTypeAttributeName(this.SpecVersion), StringComparison.InvariantCultureIgnoreCase))
{
if (value is null || value is ContentType)
if (value is ContentType)
{
return true;
}

View File

@ -60,6 +60,15 @@ namespace CloudNative.CloudEvents {
}
}
/// <summary>
/// Looks up a localized string similar to Null values cannot be added as attributes.
/// </summary>
internal static string ErrorCannotAddNullAttributeValue {
get {
return ResourceManager.GetString("ErrorCannotAddNullAttributeValue", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The &apos;contenttype&apos; attribute value must be a content-type expression compliant with RFC2046.
/// </summary>

View File

@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ErrorCannotAddNullAttributeValue" xml:space="preserve">
<value>Null values cannot be added as attributes</value>
</data>
<data name="ErrorContentTypeIsNotRFC2046" xml:space="preserve">
<value>The 'contenttype' attribute value must be a content-type expression compliant with RFC2046</value>
</data>

View File

@ -29,5 +29,22 @@ namespace CloudNative.CloudEvents.UnitTests
string attributeName = CloudEventAttributes.SpecVersionAttributeName();
Assert.Throws<InvalidOperationException>(() => attributes[attributeName] = null);
}
[Fact]
public void Dictionary_Add_NullValue()
{
IDictionary<string, object> attributes = new CloudEventAttributes(CloudEventsSpecVersion.Default, emptyExtensions);
string attributeName = CloudEventAttributes.TypeAttributeName();
Assert.Throws<ArgumentNullException>(() => attributes.Add(attributeName, null));
}
[Fact]
public void Collection_Add_NullValue()
{
ICollection<KeyValuePair<string, object>> attributes = new CloudEventAttributes(CloudEventsSpecVersion.Default, emptyExtensions);
string attributeName = CloudEventAttributes.TypeAttributeName();
var pair = KeyValuePair.Create(attributeName, default(object));
Assert.Throws<InvalidOperationException>(() => attributes.Add(pair));
}
}
}