-
Notifications
You must be signed in to change notification settings - Fork 22
Open
Description
Use of these methods can allow for complete bypass of analyzers. For example, it's possible to make an object that to any outside observer is [Immutable] but has interior mutability with no auditing necessary.
Repro:
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using static D2L.CodeStyle.Annotations.Objects;
namespace ImmutableBypass {
[Immutable]
public interface IImmutableInterface {
ImmutableArray<string> Values { get; }
void Oops();
}
[Immutable]
public sealed class DefinitelyAnImmutableType<[Immutable] T> : IImmutableInterface
where T : ICollection<string>, new()
{
public T SuperImmutableProperty { get; } = new T();
public ImmutableArray<string> Values => SuperImmutableProperty.ToImmutableArray();
public void Oops() {
SuperImmutableProperty.Add( Guid.NewGuid().ToString() );
}
}
public static class Program {
public static void Main( string[] args ) {
IImmutableInterface immutableObj = CreateImmutableObject();
Console.WriteLine( immutableObj.Values.Length ); // => 0
immutableObj.Oops();
Console.WriteLine( immutableObj.Values.Length ); // => 1
}
private static IImmutableInterface CreateImmutableObject() {
Type immutableType = typeof( DefinitelyAnImmutableType<> ).MakeGenericType( typeof( List<string> ) );
return (IImmutableInterface)Activator.CreateInstance( immutableType );
}
}
}(note: checking that constraints are immutable could also help, but also potentially possible to bypass by just doing an is/as cast at runtime)
Metadata
Metadata
Assignees
Labels
No labels