Skip to content

Commit

Permalink
Merge pull request #79 from progaudi/add-fixstr-length-evaluation
Browse files Browse the repository at this point in the history
Add fixstr length evaluation to converter
  • Loading branch information
aensidhe authored Sep 21, 2018
2 parents 8a1bdf5 + d5f5b37 commit 7cfad8f
Show file tree
Hide file tree
Showing 6 changed files with 296 additions and 11 deletions.
15 changes: 8 additions & 7 deletions .azure/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ steps:
versioningScheme: byEnvVar
versionEnvVar: NugetPackageVersion
arguments: -c Release /property:PackageOutputPath=$(Build.ArtifactStagingDirectory)
- task: NuGetCommand@2
displayName: push nuget packages
inputs:
command: push
packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg'
nuGetFeedType: external
publishFeedCredentials: api.nuget.org
- ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
- task: NuGetCommand@2
displayName: push nuget packages
inputs:
command: push
packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg'
nuGetFeedType: external
publishFeedCredentials: api.nuget.org
- task: PublishBuildArtifacts@1
inputs:
pathtoPublish: '$(Build.ArtifactStagingDirectory)'
Expand Down
71 changes: 69 additions & 2 deletions src/msgpack.light/Converters/BinaryConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ namespace ProGaudi.MsgPack.Light.Converters
{
internal class BinaryConverter : IMsgPackConverter<byte[]>
{
private readonly bool _compatibilityMode;

private MsgPackContext _context;

public BinaryConverter(bool compatibilityMode)
{
_compatibilityMode = compatibilityMode;
}

public void Initialize(MsgPackContext context)
{
_context = context;
Expand All @@ -19,7 +26,15 @@ public void Write(byte[] value, IMsgPackWriter writer)
return;
}

WriteBinaryHeaderAndLength((uint)value.Length, writer);
var valueLength = (uint) value.Length;
if (_compatibilityMode)
{
WriteStringHeaderAndLength(valueLength, writer);
}
else
{
WriteBinaryHeaderAndLength(valueLength, writer);
}

writer.Write(value);
}
Expand Down Expand Up @@ -47,8 +62,40 @@ public byte[] Read(IMsgPackReader reader)
length = NumberConverter.ReadUInt32(reader);
break;

case DataTypes.Str8:
if (_compatibilityMode)
length = NumberConverter.ReadUInt8(reader);
else
throw ExceptionUtils.CantReadStringAsBinary();
break;

case DataTypes.Str16:
if (_compatibilityMode)
length = NumberConverter.ReadUInt16(reader);
else
throw ExceptionUtils.CantReadStringAsBinary();
break;

case DataTypes.Str32:
if (_compatibilityMode)
length = NumberConverter.ReadUInt32(reader);
else
throw ExceptionUtils.CantReadStringAsBinary();
break;

default:
throw ExceptionUtils.BadTypeException(type, DataTypes.Bin8, DataTypes.Bin16, DataTypes.Bin32, DataTypes.Null);
if ((type & DataTypes.FixStr) == DataTypes.FixStr)
{
if (_compatibilityMode)
length = (uint)(type & ~DataTypes.FixStr);
else
throw ExceptionUtils.CantReadStringAsBinary();
}
else
{
throw ExceptionUtils.BadTypeException(type, DataTypes.Bin8, DataTypes.Bin16, DataTypes.Bin32, DataTypes.Null);
}
break;
}

var segment = reader.ReadBytes(length);
Expand All @@ -75,5 +122,25 @@ private void WriteBinaryHeaderAndLength(uint length, IMsgPackWriter writer)
NumberConverter.WriteUIntValue(length, writer);
}
}

private void WriteStringHeaderAndLength(uint length, IMsgPackWriter writer)
{
if (length <= 31)
{
writer.Write((byte)(((byte)DataTypes.FixStr + length) % 256));
return;
}

if (length <= ushort.MaxValue)
{
writer.Write(DataTypes.Str16);
NumberConverter.WriteUShortValue((ushort)length, writer);
}
else
{
writer.Write(DataTypes.Str32);
NumberConverter.WriteUIntValue((uint)length, writer);
}
}
}
}
5 changes: 5 additions & 0 deletions src/msgpack.light/ExceptionUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ public static Exception BadTypeException(DataTypes actual, params DataTypes[] ex
return new SerializationException($"Got {actual:G} (0x{actual:X}), while expecting one of these: {String.Join(", ", expectedCodes)}");
}

public static Exception CantReadStringAsBinary()
{
return new SerializationException($"Reading a string as a byte array is disabled. Set MsgPackContext.BinaryCompatibilityMode property to true to enable it");
}

public static Exception NotEnoughBytes(uint actual, uint expected)
{
return new SerializationException($"Expected {expected} bytes, got {actual} bytes.");
Expand Down
4 changes: 2 additions & 2 deletions src/msgpack.light/MsgPackContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class MsgPackContext

private readonly Dictionary<Type, Func<object>> _objectActivators = new Dictionary<Type, Func<object>>();

public MsgPackContext(bool strictParseOfFloat = false, bool convertEnumsAsStrings = true)
public MsgPackContext(bool strictParseOfFloat = false, bool convertEnumsAsStrings = true, bool binaryCompatibilityMode = false)
{
_convertEnumsAsStrings = convertEnumsAsStrings;
var numberConverter = new NumberConverter(strictParseOfFloat);
Expand All @@ -32,7 +32,7 @@ public MsgPackContext(bool strictParseOfFloat = false, bool convertEnumsAsString
{typeof(MsgPackToken), new MsgPackTokenConverter()},
{typeof (bool), new BoolConverter()},
{typeof (string), new StringConverter()},
{typeof (byte[]), new BinaryConverter()},
{typeof (byte[]), new BinaryConverter(binaryCompatibilityMode)},
{typeof (float), numberConverter},
{typeof (double), numberConverter},
{typeof (byte), numberConverter},
Expand Down
130 changes: 130 additions & 0 deletions tests/msgpack.light.tests/Reader/Binary.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Runtime.Serialization;

using Shouldly;

using Xunit;
Expand Down Expand Up @@ -88,5 +90,133 @@ public void Test(byte[] value, byte[] data)
var token = Helpers.CheckTokenDeserialization(data);
((byte[])token).ShouldBe(value);
}

[Theory]
[InlineData(new byte[] {160})]
[InlineData(new byte[] {161, 1})]
[InlineData(new byte[]
{
218, 1, 44,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0
})]
public void FailToReadOldBinary(byte[] data)
{
var e = Should.Throw<SerializationException>(() => MsgPackSerializer.Deserialize<byte[]>(data));
e.Message.ShouldBe("Reading a string as a byte array is disabled. Set MsgPackContext.BinaryCompatibilityMode property to true to enable it");
}

[Theory]
[InlineData(new byte[0], new byte[] {160})]
[InlineData(new byte[] {1}, new byte[] {161, 1})]
[InlineData(new byte[]
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0
},
new byte[]
{
218, 1, 44,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0
})]
public void ReadOldBinary(byte[] value, byte[] data)
{
var context = new MsgPackContext(binaryCompatibilityMode: true);
var result = Should.NotThrow(() => MsgPackSerializer.Deserialize<byte[]>(data, context));
result.ShouldBe(value);
}
}
}
82 changes: 82 additions & 0 deletions tests/msgpack.light.tests/Writer/Binary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,87 @@ public void Test(byte[] value, byte[] data)

((MsgPackToken)value).RawBytes.ShouldBe(data);
}

[Theory]
[InlineData(new byte[0], new byte[] {160})]
[InlineData(new byte[] {1}, new byte[] {161, 1})]
[InlineData(new byte[]
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0
},
new byte[]
{
218, 1, 44,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,

1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0
})]
public void WriteOldBinary(byte[] value, byte[] data)
{
var context = new MsgPackContext(binaryCompatibilityMode: true);
var result = Should.NotThrow(() => MsgPackSerializer.Serialize(value, context));
result.ShouldBe(data);
}
}
}

0 comments on commit 7cfad8f

Please sign in to comment.