diff --git a/Bson/IO/BsonBinaryReader.cs b/Bson/IO/BsonBinaryReader.cs index 37b3c8d6ff..3d89c7534e 100644 --- a/Bson/IO/BsonBinaryReader.cs +++ b/Bson/IO/BsonBinaryReader.cs @@ -184,7 +184,13 @@ namespace MongoDB.Bson.IO { if (disposed) { ThrowObjectDisposedException(); } VerifyBsonType("ReadDateTime", BsonType.DateTime); state = GetNextState(); - return buffer.ReadInt64(); + var value = buffer.ReadInt64(); + if (value == BsonConstants.DateTimeMaxValueMillisecondsSinceEpoch + 1) { + if (settings.FixOldDateTimeMaxValueOnInput) { + value = BsonConstants.DateTimeMaxValueMillisecondsSinceEpoch; + } + } + return value; } /// diff --git a/Bson/IO/BsonBinaryReaderSettings.cs b/Bson/IO/BsonBinaryReaderSettings.cs index 1361d241c5..4e00adc01b 100644 --- a/Bson/IO/BsonBinaryReaderSettings.cs +++ b/Bson/IO/BsonBinaryReaderSettings.cs @@ -31,6 +31,7 @@ namespace MongoDB.Bson.IO { #region private fields private bool closeInput = false; private bool fixOldBinarySubTypeOnInput = true; + private bool fixOldDateTimeMaxValueOnInput = true; private int maxDocumentSize = BsonDefaults.MaxDocumentSize; #endregion @@ -46,17 +47,20 @@ namespace MongoDB.Bson.IO { /// /// Whether to close the input stream when the reader is closed. /// Whether to fix occurrences of the old binary subtype on input. + /// Whether to fix occurrences of the old representation of DateTime.MaxValue on input. /// The representation for Guids. /// The max document size. public BsonBinaryReaderSettings( bool closeInput, bool fixOldBinarySubTypeOnInput, + bool fixOldDateTimeMaxValueOnInput, GuidRepresentation guidRepresentation, int maxDocumentSize ) : base(guidRepresentation) { this.closeInput = closeInput; this.fixOldBinarySubTypeOnInput = fixOldBinarySubTypeOnInput; + this.fixOldDateTimeMaxValueOnInput = fixOldDateTimeMaxValueOnInput; this.maxDocumentSize = maxDocumentSize; } #endregion @@ -99,6 +103,17 @@ namespace MongoDB.Bson.IO { } } + /// + /// Gets or sets whether to fix occurrences of the old representation of DateTime.MaxValue on input. + /// + public bool FixOldDateTimeMaxValueOnInput { + get { return fixOldDateTimeMaxValueOnInput; } + set { + if (isFrozen) { throw new InvalidOperationException("BsonBinaryReaderSettings is frozen."); } + fixOldDateTimeMaxValueOnInput = value; + } + } + /// /// Gets or sets the max document size. /// @@ -130,6 +145,7 @@ namespace MongoDB.Bson.IO { return new BsonBinaryReaderSettings( closeInput, fixOldBinarySubTypeOnInput, + fixOldDateTimeMaxValueOnInput, guidRepresentation, maxDocumentSize ); diff --git a/DriverOnlineTests/DriverOnlineTests.csproj b/DriverOnlineTests/DriverOnlineTests.csproj index bf53c353b2..b4431f6f09 100644 --- a/DriverOnlineTests/DriverOnlineTests.csproj +++ b/DriverOnlineTests/DriverOnlineTests.csproj @@ -104,6 +104,7 @@ + diff --git a/DriverOnlineTests/Jira/CSharp258Tests.cs b/DriverOnlineTests/Jira/CSharp258Tests.cs new file mode 100644 index 0000000000..a2339356e0 --- /dev/null +++ b/DriverOnlineTests/Jira/CSharp258Tests.cs @@ -0,0 +1,98 @@ +/* Copyright 2010-2011 10gen Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using NUnit.Framework; + +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Driver; +using MongoDB.Driver.Builders; + +namespace MongoDB.DriverOnlineTests.Jira.CSharp258 { + [TestFixture] + public class CSharp258Tests { + public class C { + public ObjectId Id { get; set; } + public DateTime DateTime { get; set; } + } + + private MongoServer server; + private MongoDatabase database; + private MongoCollection collection; + + [TestFixtureSetUp] + public void TestFixtureSetup() { + server = MongoServer.Create("mongodb://localhost/?safe=true"); + database = server["onlinetests"]; + collection = database.GetCollection("testcollection"); + } + + [Test] + public void TestDateTimePropertyWithNewMaxDateTimeRepresentation() { + collection.RemoveAll(); + collection.Insert(new BsonDocument { + { "_id", ObjectId.GenerateNewId() }, + { "DateTime", new BsonDateTime(253402300799999) } + }); + + var c = collection.FindOne(); + Assert.AreEqual(DateTime.MaxValue, c.DateTime); + } + + [Test] + public void TestDateTimePropertyWithOldMaxDateTimeRepresentation() { + collection.RemoveAll(); + collection.Insert(new BsonDocument { + { "_id", ObjectId.GenerateNewId() }, + { "DateTime", new BsonDateTime(253402300800000) } + }); + + var c = collection.FindOne(); + Assert.AreEqual(DateTime.MaxValue, c.DateTime); + } + + [Test] + public void TestDocumentWithNewMaxDateTimeRepresentation() { + collection.RemoveAll(); + collection.Insert(new BsonDocument { + { "_id", ObjectId.GenerateNewId() }, + { "DateTime", new BsonDateTime(253402300799999) } + }); + + var document = collection.FindOneAs(); + Assert.AreEqual(DateTime.MaxValue, document["DateTime"].AsDateTime); + Assert.AreEqual(253402300799999, document["DateTime"].AsBsonDateTime.MillisecondsSinceEpoch); + } + + [Test] + public void TestDocumentWithOldMaxDateTimeRepresentation() { + collection.RemoveAll(); + collection.Insert(new BsonDocument { + { "_id", ObjectId.GenerateNewId() }, + { "DateTime", new BsonDateTime(253402300800000) } + }); + + var document = collection.FindOneAs(); + Assert.AreEqual(DateTime.MaxValue, document["DateTime"].AsDateTime); + Assert.AreEqual(253402300799999, document["DateTime"].AsBsonDateTime.MillisecondsSinceEpoch); + } + } +}