diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2009-03-08 21:39:04 -0700 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2009-03-09 15:48:44 -0700 |
commit | 291e90854ac69ee6ab97938c978c7d25ee0870e1 (patch) | |
tree | 9202f632c21cdddbbf06781d9489967a7473aa7d /src | |
parent | 800ad97dbf057985984905eff66d707772ab3ff1 (diff) | |
download | DotNetOpenAuth-291e90854ac69ee6ab97938c978c7d25ee0870e1.zip DotNetOpenAuth-291e90854ac69ee6ab97938c978c7d25ee0870e1.tar.gz DotNetOpenAuth-291e90854ac69ee6ab97938c978c7d25ee0870e1.tar.bz2 |
More Code Contract work.
Diffstat (limited to 'src')
-rw-r--r-- | src/DotNetOpenAuth.Test/AssemblyTesting.cs | 1 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/Identifier.cs | 4 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/Realm.cs | 12 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/UriIdentifier.cs | 19 | ||||
-rw-r--r-- | src/DotNetOpenAuth/OpenId/XriIdentifier.cs | 32 | ||||
-rw-r--r-- | src/DotNetOpenAuth/UriUtil.cs | 8 |
6 files changed, 67 insertions, 9 deletions
diff --git a/src/DotNetOpenAuth.Test/AssemblyTesting.cs b/src/DotNetOpenAuth.Test/AssemblyTesting.cs index d3ecb8d..fecd97b 100644 --- a/src/DotNetOpenAuth.Test/AssemblyTesting.cs +++ b/src/DotNetOpenAuth.Test/AssemblyTesting.cs @@ -12,6 +12,7 @@ namespace DotNetOpenAuth.Test { public class AssemblyTesting { [AssemblyInitialize] public static void AssemblyInitialize(TestContext tc) { + // Make contract failures become test failures. Contract.ContractFailed += (sender, e) => { e.Handled = true; Assert.Fail(e.FailureKind.ToString() + ": " + e.DebugMessage); diff --git a/src/DotNetOpenAuth/OpenId/Identifier.cs b/src/DotNetOpenAuth/OpenId/Identifier.cs index cc051d5..0179ee1 100644 --- a/src/DotNetOpenAuth/OpenId/Identifier.cs +++ b/src/DotNetOpenAuth/OpenId/Identifier.cs @@ -9,6 +9,7 @@ namespace DotNetOpenAuth.OpenId { using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.RelyingParty; @@ -16,6 +17,8 @@ namespace DotNetOpenAuth.OpenId { /// An Identifier is either a "http" or "https" URI, or an XRI. /// </summary> [Serializable] + [ContractVerification(true)] + [Pure] public abstract class Identifier { /// <summary> /// Initializes a new instance of the <see cref="Identifier"/> class. @@ -62,6 +65,7 @@ namespace DotNetOpenAuth.OpenId { if (identifier == null) { return null; } + return new UriIdentifier(identifier); } diff --git a/src/DotNetOpenAuth/OpenId/Realm.cs b/src/DotNetOpenAuth/OpenId/Realm.cs index de8a83d..80f3ce4 100644 --- a/src/DotNetOpenAuth/OpenId/Realm.cs +++ b/src/DotNetOpenAuth/OpenId/Realm.cs @@ -9,6 +9,7 @@ namespace DotNetOpenAuth.OpenId { using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; using System.Globalization; using System.Linq; using System.Text.RegularExpressions; @@ -25,6 +26,8 @@ namespace DotNetOpenAuth.OpenId { /// See http://openid.net/specs/openid-authentication-2_0.html#realms /// </remarks> [Serializable] +// [ContractVerification(true)] + [Pure] public class Realm { /// <summary> /// A regex used to detect a wildcard that is being used in the realm. @@ -377,6 +380,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.uri != null); + Contract.Invariant(this.uri.AbsoluteUri != null); + } + + /// <summary> /// Calls <see cref="UriBuilder.ToString"/> if the argument is non-null. /// Otherwise throws <see cref="ArgumentNullException"/>. /// </summary> diff --git a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs index 9bfa7dd..e5de997 100644 --- a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; using System.Linq; using System.Text.RegularExpressions; using System.Web.UI.HtmlControls; @@ -20,6 +21,8 @@ namespace DotNetOpenAuth.OpenId { /// A URI style of OpenID Identifier. /// </summary> [Serializable] + //[ContractVerification(true)] + [Pure] public sealed class UriIdentifier : Identifier { /// <summary> /// The allowed protocol schemes in a URI Identifier. @@ -30,7 +33,9 @@ namespace DotNetOpenAuth.OpenId { /// Initializes a new instance of the <see cref="UriIdentifier"/> class. /// </summary> /// <param name="uri">The value this identifier will represent.</param> - internal UriIdentifier(string uri) : this(uri, false) { } + internal UriIdentifier(string uri) + : this(uri, false) { + } /// <summary> /// Initializes a new instance of the <see cref="UriIdentifier"/> class. @@ -56,7 +61,8 @@ namespace DotNetOpenAuth.OpenId { /// Initializes a new instance of the <see cref="UriIdentifier"/> class. /// </summary> /// <param name="uri">The value this identifier will represent.</param> - internal UriIdentifier(Uri uri) : this(uri, false) { } + internal UriIdentifier(Uri uri) : this(uri, false) { + } /// <summary> /// Initializes a new instance of the <see cref="UriIdentifier"/> class. @@ -304,6 +310,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.Uri != null); + Contract.Invariant(this.Uri.AbsoluteUri != null); + } + + /// <summary> /// Searches HTML for the HEAD META tags that describe OpenID provider services. /// </summary> /// <param name="claimedIdentifier">The final URL that provided this HTML document. diff --git a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs index ab4cdb9..b0610b5 100644 --- a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; + using System.Diagnostics.Contracts; using System.Globalization; using System.Xml; using DotNetOpenAuth.Messaging; @@ -18,6 +19,8 @@ namespace DotNetOpenAuth.OpenId { /// An XRI style of OpenID Identifier. /// </summary> [Serializable] + [ContractVerification(true)] + [Pure] public sealed class XriIdentifier : Identifier { /// <summary> /// An XRI always starts with one of these symbols. @@ -47,6 +50,11 @@ namespace DotNetOpenAuth.OpenId { private readonly string xriResolverProxy; /// <summary> + /// Backing store for the <see cref="CanonicalXri"/> property. + /// </summary> + private readonly string canonicalXri; + + /// <summary> /// Initializes a new instance of the <see cref="XriIdentifier"/> class. /// </summary> /// <param name="xri">The string value of the XRI.</param> @@ -64,10 +72,8 @@ namespace DotNetOpenAuth.OpenId { /// </param> internal XriIdentifier(string xri, bool requireSsl) : base(requireSsl) { - if (!IsValidXri(xri)) { - throw new FormatException( - string.Format(CultureInfo.CurrentCulture, OpenIdStrings.InvalidXri, xri)); - } + ErrorUtilities.VerifyFormat(IsValidXri(xri), OpenIdStrings.InvalidXri, xri); + Contract.Assume(xri != null); // Proven by IsValidXri this.xriResolverProxy = XriResolverProxyTemplate; if (requireSsl) { // Indicate to xri.net that we require SSL to be used for delegated resolution @@ -75,7 +81,7 @@ namespace DotNetOpenAuth.OpenId { this.xriResolverProxy += ";https=true"; } this.OriginalXri = xri; - this.CanonicalXri = CanonicalizeXri(xri); + this.canonicalXri = CanonicalizeXri(xri); } /// <summary> @@ -86,7 +92,9 @@ namespace DotNetOpenAuth.OpenId { /// <summary> /// Gets the canonical form of the XRI string. /// </summary> - internal string CanonicalXri { get; private set; } + internal string CanonicalXri { + get { return this.canonicalXri; } + } /// <summary> /// Gets the URL from which this XRI's XRDS document may be downloaded. @@ -134,6 +142,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> /// Tests whether a given string represents a valid XRI format. /// </summary> /// <param name="xri">The value to test for XRI validity.</param> @@ -213,8 +230,11 @@ namespace DotNetOpenAuth.OpenId { /// <returns>The canonicalized form of the XRI.</returns> /// <remarks>The canonical form, per the OpenID spec, is no scheme and no whitespace on either end.</remarks> private static string CanonicalizeXri(string xri) { + Contract.Requires(xri != null); + Contract.Ensures(Contract.Result<string>() != null); xri = xri.Trim(); if (xri.StartsWith(XriScheme, StringComparison.OrdinalIgnoreCase)) { + Contract.Assume(XriScheme.Length <= xri.Length); // should be implied by StartsWith xri = xri.Substring(XriScheme.Length); } return xri; diff --git a/src/DotNetOpenAuth/UriUtil.cs b/src/DotNetOpenAuth/UriUtil.cs index 97b9d10..f8f480c 100644 --- a/src/DotNetOpenAuth/UriUtil.cs +++ b/src/DotNetOpenAuth/UriUtil.cs @@ -13,10 +13,12 @@ namespace DotNetOpenAuth { using System.Web; using System.Web.UI; using DotNetOpenAuth.Messaging; + using System.Diagnostics.Contracts; /// <summary> /// Utility methods for working with URIs. /// </summary> + [ContractVerification(true)] internal static class UriUtil { /// <summary> /// Tests a URI for the presence of an OAuth payload. @@ -58,6 +60,8 @@ namespace DotNetOpenAuth { /// <param name="builder">The UriBuilder to render as a string.</param> /// <returns>The string version of the Uri.</returns> internal static string ToStringWithImpliedPorts(this UriBuilder builder) { + Contract.Requires(builder != null); + Contract.Ensures(Contract.Result<string>() != null); ErrorUtilities.VerifyArgumentNotNull(builder, "builder"); // We only check for implied ports on HTTP and HTTPS schemes since those @@ -70,7 +74,9 @@ namespace DotNetOpenAuth { // Be really careful to only remove the first :80 or :443 so we are guaranteed // we're removing only the port (and not something in the query string that // looks like a port. - return Regex.Replace(url, @"^(https?://[^:]+):\d+", m => m.Groups[1].Value, RegexOptions.IgnoreCase); + string result = Regex.Replace(url, @"^(https?://[^:]+):\d+", m => m.Groups[1].Value, RegexOptions.IgnoreCase); + Contract.Assume(result != null); // Regex.Replace never returns null + return result; } else { // The port must be explicitly given anyway. return builder.ToString(); |