summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-03-08 21:39:04 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2009-03-09 15:48:44 -0700
commit291e90854ac69ee6ab97938c978c7d25ee0870e1 (patch)
tree9202f632c21cdddbbf06781d9489967a7473aa7d /src
parent800ad97dbf057985984905eff66d707772ab3ff1 (diff)
downloadDotNetOpenAuth-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.cs1
-rw-r--r--src/DotNetOpenAuth/OpenId/Identifier.cs4
-rw-r--r--src/DotNetOpenAuth/OpenId/Realm.cs12
-rw-r--r--src/DotNetOpenAuth/OpenId/UriIdentifier.cs19
-rw-r--r--src/DotNetOpenAuth/OpenId/XriIdentifier.cs32
-rw-r--r--src/DotNetOpenAuth/UriUtil.cs8
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();