diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2010-01-12 17:13:00 -0800 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2010-01-12 17:13:00 -0800 |
commit | 3f1a51cfcc88de654fbf01341c8dfec9a7c1036e (patch) | |
tree | 70a94fe2eeafc68141796c81a6b0c132d2f53188 | |
parent | bc8834845b2930491cd05aa07726ed61bc69499f (diff) | |
download | DotNetOpenAuth-3f1a51cfcc88de654fbf01341c8dfec9a7c1036e.zip DotNetOpenAuth-3f1a51cfcc88de654fbf01341c8dfec9a7c1036e.tar.gz DotNetOpenAuth-3f1a51cfcc88de654fbf01341c8dfec9a7c1036e.tar.bz2 |
Code Contract fixes.
12 files changed, 129 insertions, 6 deletions
diff --git a/src/DotNetOpenAuth/Configuration/TypeConfigurationElement.cs b/src/DotNetOpenAuth/Configuration/TypeConfigurationElement.cs index 5ac88da..0335af5 100644 --- a/src/DotNetOpenAuth/Configuration/TypeConfigurationElement.cs +++ b/src/DotNetOpenAuth/Configuration/TypeConfigurationElement.cs @@ -126,6 +126,7 @@ namespace DotNetOpenAuth.Configuration { /// be present. /// </remarks> private static T CreateInstanceFromXaml(Stream xaml) { + Contract.Ensures(Contract.Result<T>() != null); return (T)XamlReader.Load(xaml); } } diff --git a/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs b/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs index b37c93a..dd34d90 100644 --- a/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs +++ b/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs @@ -153,10 +153,13 @@ namespace DotNetOpenAuth.Messaging { /// <returns>The seekable Stream instance that contains a copy of what was returned in the HTTP response.</returns> private static MemoryStream CacheNetworkStreamAndClose(HttpWebResponse response, int maximumBytesToRead) { Contract.Requires<ArgumentNullException>(response != null); + Contract.Ensures(Contract.Result<MemoryStream>() != null); // Now read and cache the network stream Stream networkStream = response.GetResponseStream(); MemoryStream cachedStream = new MemoryStream(response.ContentLength < 0 ? 4 * 1024 : Math.Min((int)response.ContentLength, maximumBytesToRead)); + Contract.Assume(networkStream.CanRead, "HttpWebResponse.GetResponseStream() always returns a readable stream."); // CC missing + Contract.Assume(cachedStream.CanWrite, "This is a MemoryStream -- it's always writable."); // CC missing networkStream.CopyTo(cachedStream); cachedStream.Seek(0, SeekOrigin.Begin); diff --git a/src/DotNetOpenAuth/Messaging/EnumerableCache.cs b/src/DotNetOpenAuth/Messaging/EnumerableCache.cs index 71825bc..29ec533 100644 --- a/src/DotNetOpenAuth/Messaging/EnumerableCache.cs +++ b/src/DotNetOpenAuth/Messaging/EnumerableCache.cs @@ -35,6 +35,8 @@ namespace DotNetOpenAuth.Messaging { /// to avoid double-caching.</para> /// </remarks> public static IEnumerable<T> CacheGeneratedResults<T>(this IEnumerable<T> sequence) { + Contract.Requires<ArgumentNullException>(sequence != null); + // Don't create a cache for types that don't need it. if (sequence is IList<T> || sequence is ICollection<T> || diff --git a/src/DotNetOpenAuth/Messaging/IDirectWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/IDirectWebRequestHandler.cs index af03ba9..3420de9 100644 --- a/src/DotNetOpenAuth/Messaging/IDirectWebRequestHandler.cs +++ b/src/DotNetOpenAuth/Messaging/IDirectWebRequestHandler.cs @@ -187,6 +187,8 @@ namespace DotNetOpenAuth.Messaging { /// </remarks> IncomingWebResponse IDirectWebRequestHandler.GetResponse(HttpWebRequest request) { Contract.Requires<ArgumentNullException>(request != null); + Contract.Ensures(Contract.Result<IncomingWebResponse>() != null); + Contract.Ensures(Contract.Result<IncomingWebResponse>().ResponseStream != null); throw new System.NotImplementedException(); } @@ -209,6 +211,9 @@ namespace DotNetOpenAuth.Messaging { IncomingWebResponse IDirectWebRequestHandler.GetResponse(HttpWebRequest request, DirectWebRequestOptions options) { Contract.Requires<ArgumentNullException>(request != null); Contract.Requires<NotSupportedException>(((IDirectWebRequestHandler)this).CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported); + Contract.Ensures(Contract.Result<IncomingWebResponse>() != null); + Contract.Ensures(Contract.Result<IncomingWebResponse>().ResponseStream != null); + ////ErrorUtilities.VerifySupported(((IDirectWebRequestHandler)this).CanSupport(options), string.Format(MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name)); throw new System.NotImplementedException(); } diff --git a/src/DotNetOpenAuth/Messaging/ITamperProtectionChannelBindingElement.cs b/src/DotNetOpenAuth/Messaging/ITamperProtectionChannelBindingElement.cs index ba25c12..87ea553 100644 --- a/src/DotNetOpenAuth/Messaging/ITamperProtectionChannelBindingElement.cs +++ b/src/DotNetOpenAuth/Messaging/ITamperProtectionChannelBindingElement.cs @@ -6,12 +6,14 @@ namespace DotNetOpenAuth.Messaging { using System; + using System.Diagnostics.Contracts; using DotNetOpenAuth.OAuth.ChannelElements; /// <summary> /// An interface that must be implemented by message transforms/validators in order /// to be included in the channel stack. /// </summary> + [ContractClass(typeof(ITamperProtectionChannelBindingElementContract))] public interface ITamperProtectionChannelBindingElement : IChannelBindingElement { /// <summary> /// Gets or sets the delegate that will initialize the non-serialized properties necessary on a @@ -25,4 +27,102 @@ namespace DotNetOpenAuth.Messaging { /// <returns>The cloned instance.</returns> ITamperProtectionChannelBindingElement Clone(); } + + /// <summary> + /// Contract class for the <see cref="ITamperProtectionChannelBindingElement"/> interface. + /// </summary> + [ContractClassFor(typeof(ITamperProtectionChannelBindingElement))] + internal abstract class ITamperProtectionChannelBindingElementContract : ITamperProtectionChannelBindingElement { + #region ITamperProtectionChannelBindingElement Properties + + /// <summary> + /// Gets or sets the delegate that will initialize the non-serialized properties necessary on a + /// signable message so that its signature can be correctly calculated or verified. + /// </summary> + Action<ITamperResistantOAuthMessage> ITamperProtectionChannelBindingElement.SignatureCallback { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + #endregion + + #region IChannelBindingElement Members + + /// <summary> + /// Gets or sets the channel that this binding element belongs to. + /// </summary> + /// <remarks> + /// This property is set by the channel when it is first constructed. + /// </remarks> + Channel IChannelBindingElement.Channel { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + /// <summary> + /// Gets the protection commonly offered (if any) by this binding element. + /// </summary> + /// <remarks> + /// This value is used to assist in sorting binding elements in the channel stack. + /// </remarks> + MessageProtections IChannelBindingElement.Protection { + get { throw new NotImplementedException(); } + } + + /// <summary> + /// Prepares a message for sending based on the rules of this channel binding element. + /// </summary> + /// <param name="message">The message to prepare for sending.</param> + /// <returns> + /// The protections (if any) that this binding element applied to the message. + /// Null if this binding element did not even apply to this binding element. + /// </returns> + /// <remarks> + /// Implementations that provide message protection must honor the + /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable. + /// </remarks> + MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) { + Contract.Requires<ArgumentNullException>(message != null); + Contract.Requires<InvalidOperationException>(((IChannelBindingElement)this).Channel != null); + throw new NotImplementedException(); + } + + /// <summary> + /// Performs any transformation on an incoming message that may be necessary and/or + /// validates an incoming message based on the rules of this channel binding element. + /// </summary> + /// <param name="message">The incoming message to process.</param> + /// <returns> + /// The protections (if any) that this binding element applied to the message. + /// Null if this binding element did not even apply to this binding element. + /// </returns> + /// <exception cref="ProtocolException"> + /// Thrown when the binding element rules indicate that this message is invalid and should + /// NOT be processed. + /// </exception> + /// <remarks> + /// Implementations that provide message protection must honor the + /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable. + /// </remarks> + MessageProtections? IChannelBindingElement.ProcessIncomingMessage(IProtocolMessage message) { + Contract.Requires<ArgumentNullException>(message != null); + Contract.Requires<InvalidOperationException>(((IChannelBindingElement)this).Channel != null); + throw new NotImplementedException(); + } + + #endregion + + #region ITamperProtectionChannelBindingElement Methods + + /// <summary> + /// Clones this instance. + /// </summary> + /// <returns>The cloned instance.</returns> + ITamperProtectionChannelBindingElement ITamperProtectionChannelBindingElement.Clone() { + Contract.Ensures(Contract.Result<ITamperProtectionChannelBindingElement>() != null); + throw new NotImplementedException(); + } + + #endregion + } } diff --git a/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs b/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs index e26a672..e39a047 100644 --- a/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs +++ b/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs @@ -24,6 +24,7 @@ namespace DotNetOpenAuth.Messaging { : this(new Uri(locationUri), method) { Contract.Requires<ArgumentNullException>(locationUri != null); Contract.Requires<ArgumentOutOfRangeException>(method != HttpDeliveryMethods.None); + Contract.Requires<ArgumentOutOfRangeException>((method & HttpDeliveryMethods.HttpVerbMask) != 0, MessagingStrings.GetOrPostFlagsRequired); } /// <summary> diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs index 32d2fec..08e2411 100644 --- a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs +++ b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs @@ -286,6 +286,9 @@ namespace DotNetOpenAuth.Messaging.Reflection { /// <param name="messagePartEncoder">The message part encoder type.</param> /// <returns>An instance of the desired encoder.</returns> private static IMessagePartEncoder GetEncoder(Type messagePartEncoder) { + Contract.Requires<ArgumentNullException>(messagePartEncoder != null); + Contract.Ensures(Contract.Result<IMessagePartEncoder>() != null); + IMessagePartEncoder encoder; if (!encoders.TryGetValue(messagePartEncoder, out encoder)) { encoder = encoders[messagePartEncoder] = (IMessagePartEncoder)Activator.CreateInstance(messagePartEncoder); diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementChain.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementChain.cs index bdb0219..67c5205 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementChain.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementChain.cs @@ -20,7 +20,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// <summary> /// The various signing binding elements that may be applicable to a message in preferred use order. /// </summary> - private ITamperProtectionChannelBindingElement[] signers; + private readonly ITamperProtectionChannelBindingElement[] signers; /// <summary> /// Initializes a new instance of the <see cref="SigningBindingElementChain"/> class. @@ -93,6 +93,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// </returns> public MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) { foreach (IChannelBindingElement signer in this.signers) { + ErrorUtilities.VerifyInternal(signer.Channel != null, "A binding element's Channel property is unexpectedly null."); MessageProtections? result = signer.ProcessOutgoingMessage(message); if (result.HasValue) { return result; @@ -113,6 +114,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// </returns> public MessageProtections? ProcessIncomingMessage(IProtocolMessage message) { foreach (IChannelBindingElement signer in this.signers) { + ErrorUtilities.VerifyInternal(signer.Channel != null, "A binding element's Channel property is unexpectedly null."); MessageProtections? result = signer.ProcessIncomingMessage(message); if (result.HasValue) { return result; diff --git a/src/DotNetOpenAuth/OAuth/ServiceProviderDescription.cs b/src/DotNetOpenAuth/OAuth/ServiceProviderDescription.cs index 9014762..6205f55 100644 --- a/src/DotNetOpenAuth/OAuth/ServiceProviderDescription.cs +++ b/src/DotNetOpenAuth/OAuth/ServiceProviderDescription.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OAuth { using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; using System.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth.ChannelElements; @@ -94,6 +95,7 @@ namespace DotNetOpenAuth.OAuth { /// </summary> /// <returns>The created signing element.</returns> internal ITamperProtectionChannelBindingElement CreateTamperProtectionElement() { + Contract.Requires(this.TamperProtectionElements != null); return new SigningBindingElementChain(this.TamperProtectionElements.Select(el => (ITamperProtectionChannelBindingElement)el.Clone()).ToArray()); } } diff --git a/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs b/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs index 6b89e92..8e4cb9d 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs @@ -32,14 +32,14 @@ namespace DotNetOpenAuth.OpenId.Messages { #pragma warning restore 0414 /// <summary> - /// Backing store for the <see cref="Incoming"/> property. + /// Backing store for the <see cref="ExtraData"/> property. /// </summary> - private bool incoming; + private readonly Dictionary<string, string> extraData = new Dictionary<string, string>(); /// <summary> - /// Backing store for the <see cref="ExtraData"/> property. + /// Backing store for the <see cref="Incoming"/> property. /// </summary> - private Dictionary<string, string> extraData = new Dictionary<string, string>(); + private bool incoming; /// <summary> /// Initializes a new instance of the <see cref="RequestBase"/> class. diff --git a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs index 9bcb9cf..baba2e5 100644 --- a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs @@ -132,7 +132,9 @@ namespace DotNetOpenAuth.OpenId { public override bool Equals(object obj) { XriIdentifier other = obj as XriIdentifier; if (obj != null && other == null && Identifier.EqualityOnStrings) { // test hook to enable MockIdentifier comparison - other = Identifier.Parse(obj.ToString()) as XriIdentifier; + string objString = obj.ToString(); + ErrorUtilities.VerifyInternal(!string.IsNullOrEmpty(objString), "Identifier.ToString() returned a null or empty string."); + other = Identifier.Parse(objString) as XriIdentifier; } if (other == null) { return false; diff --git a/src/DotNetOpenAuth/Yadis/Yadis.cs b/src/DotNetOpenAuth/Yadis/Yadis.cs index 589a155..f1c8be3 100644 --- a/src/DotNetOpenAuth/Yadis/Yadis.cs +++ b/src/DotNetOpenAuth/Yadis/Yadis.cs @@ -138,6 +138,8 @@ namespace DotNetOpenAuth.Yadis { internal static IncomingWebResponse Request(IDirectWebRequestHandler requestHandler, Uri uri, bool requireSsl, params string[] acceptTypes) { Contract.Requires<ArgumentNullException>(requestHandler != null); Contract.Requires<ArgumentNullException>(uri != null); + Contract.Ensures(Contract.Result<IncomingWebResponse>() != null); + Contract.Ensures(Contract.Result<IncomingWebResponse>().ResponseStream != null); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); request.CachePolicy = IdentifierDiscoveryCachePolicy; |