Skip to content

Commit

Permalink
Better exceptions for FromBytes
Browse files Browse the repository at this point in the history
  • Loading branch information
NZSmartie committed Nov 29, 2017
1 parent 4436a9f commit 0ac5f88
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 8 deletions.
13 changes: 8 additions & 5 deletions src/CoAPNet/CoapMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ public void FromBytes(byte[] data)
_token = data.Skip(4).Take(data[0] & 0x0F).ToArray();

// Catch all the CoapOptionExceptions and throw them after all the options have been parsed.
var badOptions = new List<int>();
var badOptions = new List<CoapOptionException>();
var optionDelta = 0;
for(var i = offset; i<data.Length; i++)
{
Expand Down Expand Up @@ -345,9 +345,9 @@ public void FromBytes(byte[] data)
if (option != null)
Options.Add(option);
}
catch (CoapOptionException)
catch (CoapOptionException ex)
{
badOptions.Add(optCode + optionDelta);
badOptions.Add(ex);
}

i += dataLen;
Expand All @@ -358,8 +358,11 @@ public void FromBytes(byte[] data)
if (new int[] {1, 6, 7}.Contains(code / 100))
throw new CoapMessageFormatException("Message.Code can not use reserved classes");

if (badOptions.Count > 0)
throw new CoapOptionException($"Unsupported critical option ({string.Join(", ", badOptions)})");
if (badOptions.Count == 1)
throw badOptions.First();

if (badOptions.Count > 1)
throw new AggregateException(badOptions);
}

/// <summary>
Expand Down
6 changes: 6 additions & 0 deletions src/CoAPNet/CoapOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ public byte[] GetBytes()
if (_type == OptionType.Empty)
return new byte[0];

if (_length < _minLength || _length > _maxLength)
throw new CoapOptionException($"Invalid option length ({_length}). Must be between {_minLength} and {_maxLength} bytes");

if (_type == OptionType.Opaque)
return (byte[])_value;

Expand Down Expand Up @@ -320,6 +323,9 @@ public void FromBytes(byte[] data)
return;
}

if(data.Length < _minLength || data.Length > _maxLength)
throw new CoapOptionException($"Invalid option length ({data.Length}). Must be between {_minLength} and {_maxLength} bytes");

if (_type == OptionType.Opaque)
{
ValueOpaque = data;
Expand Down
6 changes: 3 additions & 3 deletions tests/CoAPNet.Tests/CoapOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ public void TestOptionSize1()
[Test]
public void TestOpaqueOption()
{
var option = new CoapOption(0, type: OptionType.Opaque);
var option = new CoapOption(0, type: OptionType.Opaque, maxLength: 256);

option.ValueOpaque = new byte[] {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xF0};
Assert.AreEqual(8, option.Length);
Expand All @@ -410,13 +410,13 @@ public void TestOpaqueOption()
[TestCase(0x12345678u, 4, new byte[] {0x12, 0x34, 0x56, 0x78})]
public void TestValueOption(uint value, int length, byte[] expected)
{
var optionToBytes = new CoapOption(0, type: OptionType.UInt);
var optionToBytes = new CoapOption(0, type: OptionType.UInt, maxLength: 4);

optionToBytes.ValueUInt = value;
Assert.AreEqual(length, optionToBytes.Length);
Assert.AreEqual(expected, optionToBytes.GetBytes());

var optionFromBytes = new CoapOption(0, type: OptionType.UInt);
var optionFromBytes = new CoapOption(0, type: OptionType.UInt, maxLength: 4);

optionFromBytes.FromBytes(expected);
Assert.AreEqual(length, optionFromBytes.Length);
Expand Down

0 comments on commit 0ac5f88

Please sign in to comment.