summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs3
-rw-r--r--src/DotNetOpenAuth/Configuration/AssociationTypeElement.cs2
-rw-r--r--src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs5
-rw-r--r--src/DotNetOpenAuth/Configuration/HostNameElement.cs2
-rw-r--r--src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs3
-rw-r--r--src/DotNetOpenAuth/Configuration/MessagingElement.cs2
-rw-r--r--src/DotNetOpenAuth/Configuration/OpenIdElement.cs2
-rw-r--r--src/DotNetOpenAuth/Configuration/OpenIdProviderElement.cs2
-rw-r--r--src/DotNetOpenAuth/Configuration/OpenIdRelyingPartyElement.cs2
-rw-r--r--src/DotNetOpenAuth/Configuration/ProviderSecuritySettingsElement.cs13
-rw-r--r--src/DotNetOpenAuth/Messaging/ErrorUtilities.cs8
-rw-r--r--src/DotNetOpenAuth/Messaging/IMessage.cs47
-rw-r--r--src/DotNetOpenAuth/Messaging/MessageSerializer.cs11
-rw-r--r--src/DotNetOpenAuth/Messaging/Reflection/MessageDescription.cs4
-rw-r--r--src/DotNetOpenAuth/OpenId/Identifier.cs2
-rw-r--r--src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs6
-rw-r--r--src/DotNetOpenAuth/OpenId/Realm.cs1
-rw-r--r--src/DotNetOpenAuth/OpenId/UriIdentifier.cs2
-rw-r--r--src/DotNetOpenAuth/OpenId/XriIdentifier.cs25
-rw-r--r--src/DotNetOpenAuth/UriUtil.cs6
-rw-r--r--src/DotNetOpenAuth/Util.cs16
21 files changed, 138 insertions, 26 deletions
diff --git a/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs b/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs
index c75ceb6..b65f92d 100644
--- a/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs
+++ b/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs
@@ -7,10 +7,12 @@
namespace DotNetOpenAuth.Configuration {
using System.Collections.Generic;
using System.Configuration;
+ using System.Diagnostics.Contracts;
/// <summary>
/// Describes a collection of association type sub-elements in a .config file.
/// </summary>
+ [ContractVerification(true)]
internal class AssociationTypeCollection : ConfigurationElementCollection, IEnumerable<AssociationTypeElement> {
/// <summary>
/// Initializes a new instance of the <see cref="AssociationTypeCollection"/> class.
@@ -52,6 +54,7 @@ namespace DotNetOpenAuth.Configuration {
/// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>.
/// </returns>
protected override object GetElementKey(ConfigurationElement element) {
+ Contract.Assert(element != null); // this should be Contract.Requires in base class.
return ((AssociationTypeElement)element).AssociationType;
}
}
diff --git a/src/DotNetOpenAuth/Configuration/AssociationTypeElement.cs b/src/DotNetOpenAuth/Configuration/AssociationTypeElement.cs
index dce8d74..0eaea0e 100644
--- a/src/DotNetOpenAuth/Configuration/AssociationTypeElement.cs
+++ b/src/DotNetOpenAuth/Configuration/AssociationTypeElement.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.Configuration {
using System;
using System.Collections.Generic;
using System.Configuration;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
@@ -15,6 +16,7 @@ namespace DotNetOpenAuth.Configuration {
/// Describes an association type and its maximum lifetime as an element
/// in a .config file.
/// </summary>
+ [ContractVerification(true)]
internal class AssociationTypeElement : ConfigurationElement {
/// <summary>
/// The name of the attribute that stores the association type.
diff --git a/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs b/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs
index a419334..b38c882 100644
--- a/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs
+++ b/src/DotNetOpenAuth/Configuration/DotNetOpenAuthSection.cs
@@ -6,11 +6,13 @@
namespace DotNetOpenAuth.Configuration {
using System.Configuration;
+ using System.Diagnostics.Contracts;
/// <summary>
/// Represents the section in the host's .config file that configures
/// this library's settings.
/// </summary>
+ [ContractVerification(true)]
public class DotNetOpenAuthSection : ConfigurationSection {
/// <summary>
/// The name of the section under which this library's settings must be found.
@@ -31,7 +33,8 @@ namespace DotNetOpenAuth.Configuration {
/// Initializes a new instance of the <see cref="DotNetOpenAuthSection"/> class.
/// </summary>
internal DotNetOpenAuthSection() {
- SectionInformation.AllowLocation = false;
+ Contract.Assert(this.SectionInformation != null);
+ this.SectionInformation.AllowLocation = false;
}
/// <summary>
diff --git a/src/DotNetOpenAuth/Configuration/HostNameElement.cs b/src/DotNetOpenAuth/Configuration/HostNameElement.cs
index 304fe92..f252d6f 100644
--- a/src/DotNetOpenAuth/Configuration/HostNameElement.cs
+++ b/src/DotNetOpenAuth/Configuration/HostNameElement.cs
@@ -6,10 +6,12 @@
namespace DotNetOpenAuth.Configuration {
using System.Configuration;
+ using System.Diagnostics.Contracts;
/// <summary>
/// Represents the name of a single host or a regex pattern for host names.
/// </summary>
+ [ContractVerification(true)]
internal class HostNameElement : ConfigurationElement {
/// <summary>
/// Gets the name of the @name attribute.
diff --git a/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs b/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs
index 0fa2fb1..1c3062f 100644
--- a/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs
+++ b/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs
@@ -7,11 +7,13 @@
namespace DotNetOpenAuth.Configuration {
using System.Collections.Generic;
using System.Configuration;
+ using System.Diagnostics.Contracts;
using System.Text.RegularExpressions;
/// <summary>
/// Represents a collection of child elements that describe host names either as literal host names or regex patterns.
/// </summary>
+ [ContractVerification(true)]
internal class HostNameOrRegexCollection : ConfigurationElementCollection {
/// <summary>
/// Initializes a new instance of the <see cref="HostNameOrRegexCollection"/> class.
@@ -59,6 +61,7 @@ namespace DotNetOpenAuth.Configuration {
/// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>.
/// </returns>
protected override object GetElementKey(ConfigurationElement element) {
+ Contract.Assert(element != null); // this should be Contract.Requires in base class.
return ((HostNameElement)element).Name;
}
}
diff --git a/src/DotNetOpenAuth/Configuration/MessagingElement.cs b/src/DotNetOpenAuth/Configuration/MessagingElement.cs
index 6c4fb24..86ff615 100644
--- a/src/DotNetOpenAuth/Configuration/MessagingElement.cs
+++ b/src/DotNetOpenAuth/Configuration/MessagingElement.cs
@@ -7,12 +7,14 @@
namespace DotNetOpenAuth.Configuration {
using System;
using System.Configuration;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Bindings;
/// <summary>
/// Represents the &lt;messaging&gt; element in the host's .config file.
/// </summary>
+ [ContractVerification(true)]
public class MessagingElement : ConfigurationElement {
/// <summary>
/// The name of the &lt;untrustedWebRequest&gt; sub-element.
diff --git a/src/DotNetOpenAuth/Configuration/OpenIdElement.cs b/src/DotNetOpenAuth/Configuration/OpenIdElement.cs
index ec466ca..d5986c6 100644
--- a/src/DotNetOpenAuth/Configuration/OpenIdElement.cs
+++ b/src/DotNetOpenAuth/Configuration/OpenIdElement.cs
@@ -7,10 +7,12 @@
namespace DotNetOpenAuth.Configuration {
using System;
using System.Configuration;
+ using System.Diagnostics.Contracts;
/// <summary>
/// Represents the &lt;openid&gt; element in the host's .config file.
/// </summary>
+ [ContractVerification(true)]
internal class OpenIdElement : ConfigurationElement {
/// <summary>
/// Gets the name of the &lt;relyingParty&gt; sub-element.
diff --git a/src/DotNetOpenAuth/Configuration/OpenIdProviderElement.cs b/src/DotNetOpenAuth/Configuration/OpenIdProviderElement.cs
index 5b51907..a68c0c4 100644
--- a/src/DotNetOpenAuth/Configuration/OpenIdProviderElement.cs
+++ b/src/DotNetOpenAuth/Configuration/OpenIdProviderElement.cs
@@ -6,11 +6,13 @@
namespace DotNetOpenAuth.Configuration {
using System.Configuration;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.OpenId.Provider;
/// <summary>
/// The section in the .config file that allows customization of OpenID Provider behaviors.
/// </summary>
+ [ContractVerification(true)]
internal class OpenIdProviderElement : ConfigurationElement {
/// <summary>
/// The name of the security sub-element.
diff --git a/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartyElement.cs b/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartyElement.cs
index cb20c19..fd16125 100644
--- a/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartyElement.cs
+++ b/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartyElement.cs
@@ -6,11 +6,13 @@
namespace DotNetOpenAuth.Configuration {
using System.Configuration;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.OpenId.RelyingParty;
/// <summary>
/// The section in the .config file that allows customization of OpenID Relying Party behaviors.
/// </summary>
+ [ContractVerification(true)]
internal class OpenIdRelyingPartyElement : ConfigurationElement {
/// <summary>
/// The name of the custom store sub-element.
diff --git a/src/DotNetOpenAuth/Configuration/ProviderSecuritySettingsElement.cs b/src/DotNetOpenAuth/Configuration/ProviderSecuritySettingsElement.cs
index 11b4859..3cd17f3 100644
--- a/src/DotNetOpenAuth/Configuration/ProviderSecuritySettingsElement.cs
+++ b/src/DotNetOpenAuth/Configuration/ProviderSecuritySettingsElement.cs
@@ -6,12 +6,14 @@
namespace DotNetOpenAuth.Configuration {
using System.Configuration;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Provider;
/// <summary>
/// Represents the .config file element that allows for setting the security policies of the Provider.
/// </summary>
+ [ContractVerification(true)]
internal class ProviderSecuritySettingsElement : ConfigurationElement {
/// <summary>
/// Gets the name of the @protectDownlevelReplayAttacks attribute.
@@ -73,8 +75,14 @@ namespace DotNetOpenAuth.Configuration {
[ConfigurationProperty(AssociationsConfigName, IsDefaultCollection = false)]
[ConfigurationCollection(typeof(AssociationTypeCollection))]
public AssociationTypeCollection AssociationLifetimes {
- get { return (AssociationTypeCollection)this[AssociationsConfigName] ?? new AssociationTypeCollection(); }
- set { this[AssociationsConfigName] = value; }
+ get {
+ Contract.Ensures(Contract.Result<AssociationTypeCollection>() != null);
+ return (AssociationTypeCollection)this[AssociationsConfigName] ?? new AssociationTypeCollection();
+ }
+
+ set {
+ this[AssociationsConfigName] = value;
+ }
}
/// <summary>
@@ -87,6 +95,7 @@ namespace DotNetOpenAuth.Configuration {
settings.MaximumHashBitLength = this.MaximumHashBitLength;
settings.ProtectDownlevelReplayAttacks = this.ProtectDownlevelReplayAttacks;
foreach (AssociationTypeElement element in this.AssociationLifetimes) {
+ Contract.Assert(element != null);
settings.AssociationLifetimes.Add(element.AssociationType, element.MaximumLifetime);
}
return settings;
diff --git a/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs b/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs
index c07a70e..8c001c4 100644
--- a/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs
@@ -214,6 +214,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="args">The string formatting arguments, if any.</param>
/// <exception cref="ArgumentException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
internal static void VerifyArgument(bool condition, string message, params object[] args) {
+ Contract.Requires(condition);
Contract.Requires(args != null);
Contract.Assume(message != null);
if (!condition) {
@@ -228,6 +229,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="parameterName">Name of the parameter.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
internal static void VerifyArgumentInRange(bool condition, string parameterName) {
+ Contract.Requires(condition);
if (!condition) {
throw new ArgumentOutOfRangeException(parameterName);
}
@@ -242,6 +244,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="args">The string formatting arguments.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
internal static void VerifyArgumentInRange(bool condition, string parameterName, string message, params object[] args) {
+ Contract.Requires(condition);
Contract.Requires(args != null);
Contract.Assume(message != null);
if (!condition) {
@@ -258,6 +261,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="args">The string formatting arguments, if any.</param>
/// <exception cref="ArgumentException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
internal static void VerifyArgumentNamed(bool condition, string parameterName, string message, params object[] args) {
+ Contract.Requires(condition);
Contract.Requires(args != null);
Contract.Assume(message != null);
if (!condition) {
@@ -272,7 +276,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="paramName">Name of the parameter, which will be used in the <see cref="ArgumentException"/>, if thrown.</param>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
internal static void VerifyArgumentNotNull(object value, string paramName) {
- Contract.EndContractBlock();
+ Contract.Requires(value != null);
if (value == null) {
throw new ArgumentNullException(paramName);
}
@@ -288,7 +292,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> has zero length.</exception>
internal static void VerifyNonZeroLength(string value, string paramName) {
- Contract.EndContractBlock();
+ Contract.Requires(!string.IsNullOrEmpty(value) || (value != null && value.Length > 0));
VerifyArgumentNotNull(value, paramName);
if (value.Length == 0) {
throw new ArgumentException(MessagingStrings.UnexpectedEmptyString, paramName);
diff --git a/src/DotNetOpenAuth/Messaging/IMessage.cs b/src/DotNetOpenAuth/Messaging/IMessage.cs
index acc1224..7eba540 100644
--- a/src/DotNetOpenAuth/Messaging/IMessage.cs
+++ b/src/DotNetOpenAuth/Messaging/IMessage.cs
@@ -7,16 +7,21 @@
namespace DotNetOpenAuth.Messaging {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Text;
/// <summary>
/// The interface that classes must implement to be serialized/deserialized
/// as protocol or extension messages.
/// </summary>
+ [ContractClass(typeof(IMessageContract))]
public interface IMessage {
/// <summary>
/// Gets the version of the protocol or extension this message is prepared to implement.
/// </summary>
+ /// <remarks>
+ /// Implementations of this interface should ensure that this property never returns null.
+ /// </remarks>
Version Version { get; }
/// <summary>
@@ -41,4 +46,46 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ProtocolException">Thrown if the message is invalid.</exception>
void EnsureValidMessage();
}
+
+ [ContractClassFor(typeof(IMessage))]
+ internal sealed class IMessageContract : IMessage {
+ /// <summary>
+ /// Gets the version of the protocol or extension this message is prepared to implement.
+ /// </summary>
+ Version IMessage.Version {
+ get {
+ Contract.Ensures(Contract.Result<Version>() != null);
+ return default(Version); // dummy return
+ }
+ }
+
+ /// <summary>
+ /// Gets the extra, non-standard Protocol parameters included in the message.
+ /// </summary>
+ /// <value></value>
+ /// <remarks>
+ /// Implementations of this interface should ensure that this property never returns null.
+ /// </remarks>
+ IDictionary<string, string> IMessage.ExtraData {
+ get {
+ Contract.Ensures(Contract.Result<IDictionary<string, string>>() != null);
+ return default(IDictionary<string, string>);
+ }
+ }
+
+ /// <summary>
+ /// Checks the message state for conformity to the protocol specification
+ /// and throws an exception if the message is invalid.
+ /// </summary>
+ /// <remarks>
+ /// <para>Some messages have required fields, or combinations of fields that must relate to each other
+ /// in specialized ways. After deserializing a message, this method checks the state of the
+ /// message to see if it conforms to the protocol.</para>
+ /// <para>Note that this property should <i>not</i> check signatures or perform any state checks
+ /// outside this scope of this particular message.</para>
+ /// </remarks>
+ /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception>
+ void IMessage.EnsureValidMessage() {
+ }
+ }
}
diff --git a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs
index 55f82df..873c7bf 100644
--- a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs
+++ b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs
@@ -33,6 +33,7 @@ namespace DotNetOpenAuth.Messaging {
/// that will be serialized and deserialized using this class.</param>
private MessageSerializer(Type messageType) {
Contract.Requires(messageType != null);
+ Contract.Requires(typeof(IMessage).IsAssignableFrom(messageType));
ErrorUtilities.VerifyArgumentNamed(
typeof(IMessage).IsAssignableFrom(messageType),
@@ -50,9 +51,9 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="messageType">The type of message that will be serialized/deserialized.</param>
/// <returns>A message serializer for the given message type.</returns>
internal static MessageSerializer Get(Type messageType) {
- if (messageType == null) {
- throw new ArgumentNullException("messageType");
- }
+ Contract.Requires(messageType != null);
+ Contract.Requires(typeof(IMessage).IsAssignableFrom(messageType));
+ ErrorUtilities.VerifyArgumentNotNull(messageType, "messageType");
return new MessageSerializer(messageType);
}
@@ -64,6 +65,7 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>The dictionary of values to send for the message.</returns>
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Parallel design with Deserialize method.")]
internal IDictionary<string, string> Serialize(IMessage message) {
+ Contract.Requires(message != null);
ErrorUtilities.VerifyArgumentNotNull(message, "message");
var messageDescription = MessageDescription.Get(this.messageType, message.Version);
@@ -77,6 +79,7 @@ namespace DotNetOpenAuth.Messaging {
foreach (var pair in messageDictionary) {
MessagePart partDescription;
if (messageDescription.Mapping.TryGetValue(pair.Key, out partDescription)) {
+ Contract.Assert(partDescription != null);
if (partDescription.IsRequired || partDescription.IsNondefaultValueSet(message)) {
result.Add(pair.Key, pair.Value);
}
@@ -96,6 +99,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="message">The message to deserialize into.</param>
/// <exception cref="ProtocolException">Thrown when protocol rules are broken by the incoming message.</exception>
internal void Deserialize(IDictionary<string, string> fields, IMessage message) {
+ Contract.Requires(fields != null);
+ Contract.Requires(message != null);
ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
ErrorUtilities.VerifyArgumentNotNull(message, "message");
diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessageDescription.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessageDescription.cs
index dcd5b9c..a47126a 100644
--- a/src/DotNetOpenAuth/Messaging/Reflection/MessageDescription.cs
+++ b/src/DotNetOpenAuth/Messaging/Reflection/MessageDescription.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.Messaging.Reflection {
using System;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
using System.Reflection;
@@ -68,6 +69,9 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// <param name="messageVersion">The protocol version of the message.</param>
/// <returns>A <see cref="MessageDescription"/> instance.</returns>
internal static MessageDescription Get(Type messageType, Version messageVersion) {
+ Contract.Requires(messageType != null);
+ Contract.Requires(messageVersion != null);
+ Contract.Ensures(Contract.Result<MessageDescription>() != null);
ErrorUtilities.VerifyArgumentNotNull(messageType, "messageType");
ErrorUtilities.VerifyArgumentNotNull(messageVersion, "messageVersion");
diff --git a/src/DotNetOpenAuth/OpenId/Identifier.cs b/src/DotNetOpenAuth/OpenId/Identifier.cs
index 0179ee1..d1f09ce 100644
--- a/src/DotNetOpenAuth/OpenId/Identifier.cs
+++ b/src/DotNetOpenAuth/OpenId/Identifier.cs
@@ -90,6 +90,7 @@ namespace DotNetOpenAuth.OpenId {
/// <returns>An <see cref="Identifier"/> instance for the given value.</returns>
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Some of these identifiers are not properly formatted to be Uris at this stage.")]
public static Identifier Parse(string identifier) {
+ Contract.Requires(!string.IsNullOrEmpty(identifier));
ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier");
if (XriIdentifier.IsValidXri(identifier)) {
return new XriIdentifier(identifier);
@@ -125,6 +126,7 @@ namespace DotNetOpenAuth.OpenId {
/// </returns>
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Some of these identifiers are not properly formatted to be Uris at this stage.")]
public static bool IsValid(string identifier) {
+ Contract.Requires(!string.IsNullOrEmpty(identifier));
return XriIdentifier.IsValidXri(identifier) || UriIdentifier.IsValidUri(identifier);
}
diff --git a/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs b/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs
index 531356f..2c8e865 100644
--- a/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs
+++ b/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.OpenId {
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.RelyingParty;
@@ -13,11 +14,13 @@ namespace DotNetOpenAuth.OpenId {
/// <summary>
/// Wraps an existing Identifier and prevents it from performing discovery.
/// </summary>
+ [ContractVerification(true)]
+ [Pure]
internal class NoDiscoveryIdentifier : Identifier {
/// <summary>
/// The wrapped identifier.
/// </summary>
- private Identifier wrappedIdentifier;
+ private readonly Identifier wrappedIdentifier;
/// <summary>
/// Initializes a new instance of the <see cref="NoDiscoveryIdentifier"/> class.
@@ -26,6 +29,7 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="claimSsl">Whether this Identifier should claim to be SSL-secure, although no discovery will never generate service endpoints anyway.</param>
internal NoDiscoveryIdentifier(Identifier wrappedIdentifier, bool claimSsl)
: base(claimSsl) {
+ Contract.Requires(wrappedIdentifier != null);
ErrorUtilities.VerifyArgumentNotNull(wrappedIdentifier, "wrappedIdentifier");
this.wrappedIdentifier = wrappedIdentifier;
diff --git a/src/DotNetOpenAuth/OpenId/Realm.cs b/src/DotNetOpenAuth/OpenId/Realm.cs
index 90680aa..83a2189 100644
--- a/src/DotNetOpenAuth/OpenId/Realm.cs
+++ b/src/DotNetOpenAuth/OpenId/Realm.cs
@@ -26,7 +26,6 @@ namespace DotNetOpenAuth.OpenId {
/// See http://openid.net/specs/openid-authentication-2_0.html#realms
/// </remarks>
[Serializable]
-// [ContractVerification(true)]
[Pure]
public sealed class Realm {
/// <summary>
diff --git a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs
index e5de997..6f5ff7c 100644
--- a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs
+++ b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs
@@ -21,7 +21,6 @@ namespace DotNetOpenAuth.OpenId {
/// A URI style of OpenID Identifier.
/// </summary>
[Serializable]
- //[ContractVerification(true)]
[Pure]
public sealed class UriIdentifier : Identifier {
/// <summary>
@@ -417,6 +416,7 @@ namespace DotNetOpenAuth.OpenId {
/// require network access are also done, such as lower-casing the hostname in the URI.
/// </remarks>
private static bool TryCanonicalize(string uri, out Uri canonicalUri, bool forceHttpsDefaultScheme, out bool schemePrepended) {
+ Contract.Requires(!string.IsNullOrEmpty(uri));
ErrorUtilities.VerifyNonZeroLength(uri, "uri");
uri = uri.Trim();
diff --git a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs
index b0610b5..20fa1d5 100644
--- a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs
+++ b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs
@@ -72,6 +72,7 @@ namespace DotNetOpenAuth.OpenId {
/// </param>
internal XriIdentifier(string xri, bool requireSsl)
: base(requireSsl) {
+ Contract.Requires(!string.IsNullOrEmpty(xri));
ErrorUtilities.VerifyFormat(IsValidXri(xri), OpenIdStrings.InvalidXri, xri);
Contract.Assume(xri != null); // Proven by IsValidXri
this.xriResolverProxy = XriResolverProxyTemplate;
@@ -93,7 +94,10 @@ namespace DotNetOpenAuth.OpenId {
/// Gets the canonical form of the XRI string.
/// </summary>
internal string CanonicalXri {
- get { return this.canonicalXri; }
+ get {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return this.canonicalXri;
+ }
}
/// <summary>
@@ -142,15 +146,6 @@ namespace DotNetOpenAuth.OpenId {
}
/// <summary>
- /// Verifies conditions that should be true for any valid state of this object.
- /// </summary>
- [ContractInvariantMethod]
- protected void ObjectInvariant() {
- Contract.Invariant(this.xriResolverProxy != null);
- Contract.Invariant(this.canonicalXri != null);
- }
-
- /// <summary>
/// Tests whether a given string represents a valid XRI format.
/// </summary>
/// <param name="xri">The value to test for XRI validity.</param>
@@ -158,6 +153,7 @@ namespace DotNetOpenAuth.OpenId {
/// <c>true</c> if the given string constitutes a valid XRI; otherwise, <c>false</c>.
/// </returns>
internal static bool IsValidXri(string xri) {
+ Contract.Requires(!string.IsNullOrEmpty(xri));
ErrorUtilities.VerifyNonZeroLength(xri, "xri");
xri = xri.Trim();
@@ -224,6 +220,15 @@ namespace DotNetOpenAuth.OpenId {
}
/// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [ContractInvariantMethod]
+ protected void ObjectInvariant() {
+ Contract.Invariant(this.xriResolverProxy != null);
+ Contract.Invariant(this.canonicalXri != null);
+ }
+
+ /// <summary>
/// Takes any valid form of XRI string and returns the canonical form of the same XRI.
/// </summary>
/// <param name="xri">The xri to canonicalize.</param>
diff --git a/src/DotNetOpenAuth/UriUtil.cs b/src/DotNetOpenAuth/UriUtil.cs
index f8f480c..4790ec6 100644
--- a/src/DotNetOpenAuth/UriUtil.cs
+++ b/src/DotNetOpenAuth/UriUtil.cs
@@ -8,12 +8,12 @@ namespace DotNetOpenAuth {
using System;
using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using DotNetOpenAuth.Messaging;
- using System.Diagnostics.Contracts;
/// <summary>
/// Utility methods for working with URIs.
@@ -29,12 +29,14 @@ namespace DotNetOpenAuth {
/// True if the URI contains an OAuth message.
/// </returns>
internal static bool QueryStringContainPrefixedParameters(this Uri uri, string prefix) {
+ Contract.Requires(!string.IsNullOrEmpty(prefix));
ErrorUtilities.VerifyNonZeroLength(prefix, "prefix");
if (uri == null) {
return false;
}
NameValueCollection nvc = HttpUtility.ParseQueryString(uri.Query);
+ Contract.Assert(nvc != null); // BCL
return nvc.Keys.OfType<string>().Any(key => key.StartsWith(prefix, StringComparison.Ordinal));
}
@@ -97,6 +99,8 @@ namespace DotNetOpenAuth {
}
if (page != null && !designMode) {
+ Contract.Assert(page.Request != null);
+
// Validate new value by trying to construct a Realm object based on it.
new Uri(page.Request.Url, page.ResolveUrl(value)); // throws an exception on failure.
} else {
diff --git a/src/DotNetOpenAuth/Util.cs b/src/DotNetOpenAuth/Util.cs
index cb5581f..1a67966 100644
--- a/src/DotNetOpenAuth/Util.cs
+++ b/src/DotNetOpenAuth/Util.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Net;
using System.Reflection;
@@ -14,6 +15,7 @@ namespace DotNetOpenAuth {
/// <summary>
/// A grab-bag utility class.
/// </summary>
+ [ContractVerification(true)]
internal static class Util {
/// <summary>
/// The base namespace for this library from which all other namespaces derive.
@@ -72,6 +74,7 @@ namespace DotNetOpenAuth {
return new DelayedToString<IEnumerable<KeyValuePair<K, V>>>(
pairs,
p => {
+ Contract.Requires(pairs != null);
var dictionary = pairs as IDictionary<K, V>;
StringBuilder sb = new StringBuilder(dictionary != null ? dictionary.Count * 40 : 200);
foreach (var pair in pairs) {
@@ -103,6 +106,9 @@ namespace DotNetOpenAuth {
return new DelayedToString<IEnumerable<T>>(
list,
l => {
+ Contract.Requires(l != null);
+ string newLine = Environment.NewLine;
+ Contract.Assume(newLine != null && newLine.Length > 0);
StringBuilder sb = new StringBuilder();
if (multiLineElements) {
sb.AppendLine("[{");
@@ -111,7 +117,7 @@ namespace DotNetOpenAuth {
string objString = obj != null ? obj.ToString() : "<NULL>";
// Indent every line printed
- objString = objString.Replace(Environment.NewLine, Environment.NewLine + "\t");
+ objString = objString.Replace(newLine, Environment.NewLine + "\t");
sb.Append("\t");
sb.Append(objString);
@@ -150,12 +156,12 @@ namespace DotNetOpenAuth {
/// <summary>
/// The object that will be serialized if called upon.
/// </summary>
- private T obj;
+ private readonly T obj;
/// <summary>
/// The method used to serialize <see cref="obj"/> to string form.
/// </summary>
- private Func<T, string> toString;
+ private readonly Func<T, string> toString;
/// <summary>
/// Initializes a new instance of the DelayedToString class.
@@ -163,6 +169,8 @@ namespace DotNetOpenAuth {
/// <param name="obj">The object that may be serialized to string form.</param>
/// <param name="toString">The method that will serialize the object if called upon.</param>
public DelayedToString(T obj, Func<T, string> toString) {
+ Contract.Requires(toString != null);
+
this.obj = obj;
this.toString = toString;
}
@@ -174,7 +182,7 @@ namespace DotNetOpenAuth {
/// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
/// </returns>
public override string ToString() {
- return this.toString(this.obj);
+ return this.toString(this.obj) ?? string.Empty;
}
}
}