From 86c0d9f764e0260efc456c555a24cb86397ff75e Mon Sep 17 00:00:00 2001
From: badcel <1218031+badcel@users.noreply.github.com>
Date: Sat, 8 Oct 2022 21:57:25 +0200
Subject: [PATCH] Fix string length detection - Unicode string length detection
only checked one byte instead of both - UTF32 string length detection only
checked one byte instead of all four - Added Unit tests to test for special
chars which would provoke wrong string length detection
---
.github/workflows/ci.yml | 4 ++
src/Directory.Build.props | 8 +++
.../HidApi.Net.Benchmark.csproj | 21 +++----
.../HidApi.Net.Tester.csproj | 8 +--
src/HidApi.Net.Tests/HidApi.Net.Tests.csproj | 17 ++++++
src/HidApi.Net.Tests/StringTests.cs | 56 +++++++++++++++++++
src/HidApi.Net.sln | 7 +++
src/HidApi.Net/HidApi.Net.csproj | 5 +-
src/HidApi.Net/Internal/Unicode.cs | 10 ++--
src/HidApi.Net/Internal/Utf32.cs | 10 ++--
10 files changed, 111 insertions(+), 35 deletions(-)
create mode 100644 src/Directory.Build.props
create mode 100644 src/HidApi.Net.Tests/HidApi.Net.Tests.csproj
create mode 100644 src/HidApi.Net.Tests/StringTests.cs
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c48e94a..e8e7d42 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -49,6 +49,10 @@ jobs:
run: dotnet format --no-restore --verify-no-changes
working-directory: './src'
+ - name: Run unit tests
+ run: dotnet test --no-restore -c ${{ env.configuration }}
+ working-directory: './src'
+
- name: Test Linux 64 bit
if: ${{ matrix.os == 'ubuntu-22.04' }}
run: |
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
new file mode 100644
index 0000000..3ec396f
--- /dev/null
+++ b/src/Directory.Build.props
@@ -0,0 +1,8 @@
+
+
+ net6.0
+ enable
+ enable
+ true
+
+
\ No newline at end of file
diff --git a/src/HidApi.Net.Benchmark/HidApi.Net.Benchmark.csproj b/src/HidApi.Net.Benchmark/HidApi.Net.Benchmark.csproj
index c24b542..7e3312d 100644
--- a/src/HidApi.Net.Benchmark/HidApi.Net.Benchmark.csproj
+++ b/src/HidApi.Net.Benchmark/HidApi.Net.Benchmark.csproj
@@ -1,16 +1,11 @@
+
+ Exe
+ true
+ false
+
-
- Exe
- net6.0
- enable
- enable
- true
- false
-
-
-
-
-
-
+
+
+
diff --git a/src/HidApi.Net.Tester/HidApi.Net.Tester.csproj b/src/HidApi.Net.Tester/HidApi.Net.Tester.csproj
index 56bfea5..1ebb90c 100644
--- a/src/HidApi.Net.Tester/HidApi.Net.Tester.csproj
+++ b/src/HidApi.Net.Tester/HidApi.Net.Tester.csproj
@@ -1,16 +1,12 @@
-
Exe
- net6.0
- enable
- enable
true
false
-
-
+
+
diff --git a/src/HidApi.Net.Tests/HidApi.Net.Tests.csproj b/src/HidApi.Net.Tests/HidApi.Net.Tests.csproj
new file mode 100644
index 0000000..2652a9f
--- /dev/null
+++ b/src/HidApi.Net.Tests/HidApi.Net.Tests.csproj
@@ -0,0 +1,17 @@
+
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/HidApi.Net.Tests/StringTests.cs b/src/HidApi.Net.Tests/StringTests.cs
new file mode 100644
index 0000000..a092ce3
--- /dev/null
+++ b/src/HidApi.Net.Tests/StringTests.cs
@@ -0,0 +1,56 @@
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace HidApi.Tests;
+
+[TestClass]
+public class StringTests
+{
+ [TestMethod]
+ public void TestUnicode()
+ {
+ var data = new byte[6];
+ data[0] = 0;
+ data[1] = 1;
+ data[2] = 0;
+ data[3] = 1;
+ data[4] = 0;
+ data[5] = 0;
+
+ unsafe
+ {
+ fixed (byte* p = data)
+ {
+ var str = Unicode.Read(p);
+ str.Should().Be(new string(new[] { '\u0100', '\u0100' }));
+ }
+ }
+ }
+
+ [TestMethod]
+ public void TestUtf32()
+ {
+ var data = new byte[12];
+ data[0] = 0;
+ data[1] = 1;
+ data[2] = 0;
+ data[3] = 0;
+ data[4] = 0;
+ data[5] = 1;
+ data[6] = 0;
+ data[7] = 0;
+ data[8] = 0;
+ data[9] = 0;
+ data[10] = 0;
+ data[11] = 0;
+
+ unsafe
+ {
+ fixed (byte* p = data)
+ {
+ var str = Utf32.Read(p);
+ str.Should().Be(new string(new[] { '\u0100', '\u0100' }));
+ }
+ }
+ }
+}
diff --git a/src/HidApi.Net.sln b/src/HidApi.Net.sln
index 93aa5f3..6eb0933 100644
--- a/src/HidApi.Net.sln
+++ b/src/HidApi.Net.sln
@@ -9,12 +9,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionIt
..\.editorconfig = ..\.editorconfig
..\.github\workflows\ci.yml = ..\.github\workflows\ci.yml
..\.github\dependabot.yml = ..\.github\dependabot.yml
+ Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HidApi.Net.Benchmark", "HidApi.Net.Benchmark\HidApi.Net.Benchmark.csproj", "{0AFE95CC-90A8-490A-8FE5-2604A1BB13CE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HidApi.Net.Tester", "HidApi.Net.Tester\HidApi.Net.Tester.csproj", "{D7FE837A-D24D-4D56-B538-CCC6968DDF1E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HidApi.Net.Tests", "HidApi.Net.Tests\HidApi.Net.Tests.csproj", "{3F7CF192-630B-4981-963A-6BA97F8C65EA}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -33,5 +36,9 @@ Global
{D7FE837A-D24D-4D56-B538-CCC6968DDF1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7FE837A-D24D-4D56-B538-CCC6968DDF1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7FE837A-D24D-4D56-B538-CCC6968DDF1E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3F7CF192-630B-4981-963A-6BA97F8C65EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3F7CF192-630B-4981-963A-6BA97F8C65EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F7CF192-630B-4981-963A-6BA97F8C65EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3F7CF192-630B-4981-963A-6BA97F8C65EA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/src/HidApi.Net/HidApi.Net.csproj b/src/HidApi.Net/HidApi.Net.csproj
index a03e585..9a2bb38 100644
--- a/src/HidApi.Net/HidApi.Net.csproj
+++ b/src/HidApi.Net/HidApi.Net.csproj
@@ -2,11 +2,7 @@
0.1.1
- net6.0
- enable
- enable
HidApi
- true
true
Marcel Tiede
@@ -32,6 +28,7 @@
+
diff --git a/src/HidApi.Net/Internal/Unicode.cs b/src/HidApi.Net/Internal/Unicode.cs
index f55331b..a2f0ba7 100644
--- a/src/HidApi.Net/Internal/Unicode.cs
+++ b/src/HidApi.Net/Internal/Unicode.cs
@@ -4,11 +4,9 @@ namespace HidApi;
internal static class Unicode
{
- private const int UnicodeSize = 2;
-
public static ReadOnlySpan CreateBuffer(int size)
{
- return new byte[size * UnicodeSize];
+ return new byte[size * sizeof(ushort)];
}
public static unsafe string Read(byte* ptr)
@@ -25,13 +23,13 @@ private static unsafe int Length(byte* ptr)
//check code to throw exception in case of arithmethic overflow
checked
{
- var current = ptr;
+ var current = (ushort*) ptr;
while (*current != 0)
{
- current += UnicodeSize; //Jump to next unicode char
+ current += 1; //Jump to next unicode char
}
- return (int) (current - ptr);
+ return (int) ((byte*) current - ptr);
}
}
}
diff --git a/src/HidApi.Net/Internal/Utf32.cs b/src/HidApi.Net/Internal/Utf32.cs
index feababe..23b4846 100644
--- a/src/HidApi.Net/Internal/Utf32.cs
+++ b/src/HidApi.Net/Internal/Utf32.cs
@@ -4,11 +4,9 @@ namespace HidApi;
internal static class Utf32
{
- private const int Utf32Size = 4;
-
public static ReadOnlySpan CreateBuffer(int size)
{
- return new byte[size * Utf32Size];
+ return new byte[size * sizeof(uint)];
}
public static unsafe string Read(byte* ptr)
@@ -25,13 +23,13 @@ private static unsafe int Length(byte* ptr)
//check code to throw exception in case of arithmethic overflow
checked
{
- var current = ptr;
+ var current = (uint*) ptr;
while (*current != 0)
{
- current += Utf32Size; //Jump to next UTF32 char
+ current += 1; //Jump to next UTF32 char
}
- return (int) (current - ptr);
+ return (int) ((byte*) current - ptr);
}
}
}