From 07009801171f3f8d45d8b0911bc540b470ac2acf Mon Sep 17 00:00:00 2001 From: Peter Butzhammer Date: Thu, 25 Apr 2024 13:47:24 +0200 Subject: [PATCH] Fix string to byte array encoding --- .../ValueConverterTests/WriteToBuffer.cs | 25 ++++++++++++++++--- Sharp7.Rx/ValueConverter.cs | 4 ++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Sharp7.Rx.Tests/ValueConverterTests/WriteToBuffer.cs b/Sharp7.Rx.Tests/ValueConverterTests/WriteToBuffer.cs index 0e8e15d..b316ae0 100644 --- a/Sharp7.Rx.Tests/ValueConverterTests/WriteToBuffer.cs +++ b/Sharp7.Rx.Tests/ValueConverterTests/WriteToBuffer.cs @@ -23,12 +23,31 @@ internal class WriteToBuffer : ConverterTestBase public static IEnumerable GetAdditinalWriteTestCases() { + yield return new ConverterTestCase("a", "DB0.Byte80.3", [0x61, 0x00, 0x00]); // short string + yield return new ConverterTestCase("abc", "DB0.Byte80.3", [0x61, 0x62, 0x63]); // matching string + yield return new ConverterTestCase("abcxx", "DB0.Byte80.3", [0x61, 0x62, 0x63]); // long string + + yield return new ConverterTestCase("a", "DB0.string0.3", [0x03, 0x01, 0x61, 0x00, 0x00]); // short string + yield return new ConverterTestCase("abc", "DB0.string0.3", [0x03, 0x03, 0x61, 0x62, 0x63]); // matching string + yield return new ConverterTestCase("abcxx", "DB0.string0.3", [0x03, 0x03, 0x61, 0x62, 0x63]); // long string + + yield return new ConverterTestCase("a", "DB0.wstring0.3", [0x00, 0x03, 0x00, 0x01, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00]); // short string + yield return new ConverterTestCase("abc", "DB0.wstring0.3", [0x00, 0x03, 0x00, 0x03, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63]); // matching string + yield return new ConverterTestCase("abcxx", "DB0.wstring0.3", [0x00, 0x03, 0x00, 0x03, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63]); // long string + + yield return new ConverterTestCase("aaaaBCDE", "DB0.string0.4", [0x04, 0x04, 0x61, 0x61, 0x61, 0x61]); // Length in address exceeds PLC string length yield return new ConverterTestCase("aaaaBCDE", "DB0.WString0.4", [0x00, 0x04, 0x00, 0x04, 0x00, 0x61, 0x00, 0x61, 0x00, 0x61, 0x00, 0x61]); // Length in address exceeds PLC string length yield return new ConverterTestCase("aaaaBCDE", "DB0.DBB0.4", [0x61, 0x61, 0x61, 0x61]); // Length in address exceeds PLC array length - yield return new ConverterTestCase("\ud83d\udc69\ud83c\udffd\u200d\ud83d\ude80", "DB0.WString0.2", [0x00, 0x02, 0x00, 0x02, 0xD8, 0x3D, 0xDC, 0x69]); // Length in address exceeds PLC string length, multi char unicode point - yield return new ConverterTestCase("\ud83d\udc69\ud83c\udffd\u200d\ud83d\ude80", "DB0.String0.2", [0x02, 0x02, 0x3F, 0x3F]); // Length in address exceeds PLC string length, multi char unicode point - yield return new ConverterTestCase("\ud83d\udc69\ud83c\udffd\u200d\ud83d\ude80", "DB0.DBB0.4", [0x3F, 0x3F, 0x3F, 0x3F]); // Length in address exceeds PLC string length, multi char unicode point + + // Length in address exceeds PLC string length, multi char unicode point + yield return new ConverterTestCase("\ud83d\udc69\ud83c\udffd\u200d\ud83d\ude80", "DB0.WString0.2", [0x00, 0x02, 0x00, 0x02, 0xD8, 0x3D, 0xDC, 0x69]); + + // Length in address exceeds PLC string length, multi char unicode point + yield return new ConverterTestCase("\ud83d\udc69\ud83c\udffd\u200d\ud83d\ude80", "DB0.String0.2", [0x02, 0x02, 0x3F, 0x3F]); + + // Length in address exceeds PLC string length, multi char unicode point + yield return new ConverterTestCase("\ud83d\udc69\ud83c\udffd\u200d\ud83d\ude80", "DB0.DBB0.4", [0x3F, 0x3F, 0x3F, 0x3F]); } [TestCase(18, "DB0.DInt12", 3)] diff --git a/Sharp7.Rx/ValueConverter.cs b/Sharp7.Rx/ValueConverter.cs index 97d4666..24f307b 100644 --- a/Sharp7.Rx/ValueConverter.cs +++ b/Sharp7.Rx/ValueConverter.cs @@ -54,7 +54,9 @@ internal static class ValueConverter EncodeWString(data); return; case DbType.Byte: - Encoding.ASCII.GetBytes(stringValue.AsSpan(0, address.Length), data); + + var readOnlySpan = stringValue.AsSpan(0, Math.Min(address.Length, stringValue.Length)); + Encoding.ASCII.GetBytes(readOnlySpan, data); return; default: throw new DataTypeMissmatchException($"Cannot write string to {address.Type}", typeof(string), address);