Skip to content

Commit f30dd0b

Browse files
author
sridharn
committed
Fix for CSHARP-379. Have TryParse invoke Parse
1 parent 83e34aa commit f30dd0b

File tree

2 files changed

+137
-28
lines changed

2 files changed

+137
-28
lines changed

Bson/BsonUtils.cs

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,43 @@ namespace MongoDB.Bson
2929
/// </summary>
3030
public static class BsonUtils
3131
{
32-
// public static methods
32+
3333
/// <summary>
34-
/// Parses a hex string to a byte array.
34+
/// Parses a hex string into its equivalent byte array.
3535
/// </summary>
36-
/// <param name="s">The hex string.</param>
37-
/// <returns>A byte array.</returns>
36+
/// <param name="s">The hex string to parse.</param>
37+
/// <returns>The byte equivalent of the hex string.</returns>
3838
public static byte[] ParseHexString(string s)
3939
{
40+
if (string.IsNullOrEmpty(s))
41+
{
42+
throw new ArgumentNullException("s");
43+
}
44+
4045
byte[] bytes;
41-
if (!TryParseHexString(s, out bytes))
46+
if ((s.Length & 1) != 0)
47+
{
48+
s = "0" + s; // make length of s even
49+
}
50+
bytes = new byte[s.Length / 2];
51+
for (int i = 0; i < bytes.Length; i++)
4252
{
43-
var message = string.Format("'{0}' is not a valid hex string.", s);
44-
throw new FormatException(message);
53+
string hex = s.Substring(2 * i, 2);
54+
try
55+
{
56+
byte b = Convert.ToByte(hex, 16);
57+
bytes[i] = b;
58+
}
59+
catch (FormatException e)
60+
{
61+
throw new FormatException(
62+
string.Format("Invalid hex string. Problem with substring {0} starting at position {1}",
63+
hex,
64+
2 * i),
65+
e);
66+
}
4567
}
68+
4669
return bytes;
4770
}
4871

@@ -154,29 +177,17 @@ public static DateTime ToUniversalTime(DateTime dateTime)
154177
/// <returns>True if the hex string was successfully parsed.</returns>
155178
public static bool TryParseHexString(string s, out byte[] bytes)
156179
{
157-
if (s != null)
180+
try
158181
{
159-
if ((s.Length & 1) != 0) { s = "0" + s; } // make length of s even
160-
bytes = new byte[s.Length / 2];
161-
for (int i = 0; i < bytes.Length; i++)
162-
{
163-
string hex = s.Substring(2 * i, 2);
164-
try
165-
{
166-
byte b = Convert.ToByte(hex, 16);
167-
bytes[i] = b;
168-
}
169-
catch (FormatException)
170-
{
171-
bytes = null;
172-
return false;
173-
}
174-
}
175-
return true;
182+
bytes = ParseHexString(s);
183+
}
184+
catch
185+
{
186+
bytes = null;
187+
return false;
176188
}
177189

178-
bytes = null;
179-
return false;
190+
return true;
180191
}
181192
}
182193
}

BsonUnitTests/BsonUtilsTests.cs

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public void TestMinToMillisConversion()
8383
public void TestToUniversalTimeUTCNow()
8484
{
8585
var expected = DateTime.UtcNow;
86-
var actual = BsonUtils.ToUniversalTime(expected);
86+
var actual = BsonUtils.ToUniversalTime(expected.ToLocalTime());
8787
Assert.AreEqual(expected, actual);
8888
}
8989

@@ -119,5 +119,103 @@ public void TestToHexStringNull()
119119
var actual = BsonUtils.ToHexString(null);
120120
}
121121

122+
[Test]
123+
[ExpectedException(typeof(ArgumentNullException))]
124+
public void TestParseHexStringNull()
125+
{
126+
var actual = BsonUtils.ParseHexString(null);
127+
}
128+
129+
[Test]
130+
[ExpectedException(typeof(ArgumentNullException))]
131+
public void TestParseHexStringEmpty()
132+
{
133+
var actual = BsonUtils.ParseHexString(string.Empty);
134+
}
135+
136+
[Test]
137+
public void TestParseHexString()
138+
{
139+
var expected = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 255 };
140+
var value = "000102030405060708090a0b0c0d0e0f10ff";
141+
var actual = BsonUtils.ParseHexString(value);
142+
Assert.AreEqual(expected, actual);
143+
}
144+
145+
[Test]
146+
public void TestParseHexStringOdd()
147+
{
148+
var expected = new byte[] { 0, 15 };
149+
var value = "00f";
150+
var actual = BsonUtils.ParseHexString(value);
151+
Assert.AreEqual(expected, actual);
152+
}
153+
154+
[Test]
155+
[ExpectedException(typeof(FormatException))]
156+
public void TestParseHexStringInvalid()
157+
{
158+
var actual = BsonUtils.ParseHexString("1G");
159+
}
160+
161+
[Test]
162+
[ExpectedException(typeof(FormatException))]
163+
public void TestParseHexStringInvalid2()
164+
{
165+
var actual = BsonUtils.ParseHexString("00 1");
166+
}
167+
168+
[Test]
169+
public void TestTryParseHexStringNull()
170+
{
171+
byte[] expected;
172+
BsonUtils.TryParseHexString(null, out expected);
173+
Assert.IsNull(expected);
174+
}
175+
176+
[Test]
177+
public void TestTryParseHexStringEmpty()
178+
{
179+
byte[] expected;
180+
var actual = BsonUtils.TryParseHexString(string.Empty, out expected);
181+
Assert.IsNull(expected);
182+
}
183+
184+
[Test]
185+
public void TestTryParseHexString()
186+
{
187+
var expected = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 255 };
188+
var value = "000102030405060708090a0b0c0d0e0f10ff";
189+
byte[] actual;
190+
BsonUtils.TryParseHexString(value, out actual);
191+
Assert.AreEqual(expected, actual);
192+
}
193+
194+
[Test]
195+
public void TestTryParseHexStringOdd()
196+
{
197+
var expected = new byte[] { 0, 15 };
198+
var value = "00f";
199+
byte[] actual;
200+
BsonUtils.TryParseHexString(value, out actual);
201+
Assert.AreEqual(expected, actual);
202+
}
203+
204+
[Test]
205+
public void TestTryParseHexStringInvalid()
206+
{
207+
byte[] expected;
208+
var actual = BsonUtils.TryParseHexString("1G", out expected);
209+
Assert.IsNull(expected);
210+
}
211+
212+
[Test]
213+
public void TestTryParseHexStringInvalid2()
214+
{
215+
byte[] expected;
216+
var actual = BsonUtils.TryParseHexString("00 1", out expected);
217+
Assert.IsNull(expected);
218+
}
219+
122220
}
123221
}

0 commit comments

Comments
 (0)