diff --git a/S7.Net/Protocol/Serialization.cs b/S7.Net/Protocol/Serialization.cs index 8e3c4da..40cb629 100644 --- a/S7.Net/Protocol/Serialization.cs +++ b/S7.Net/Protocol/Serialization.cs @@ -16,7 +16,7 @@ namespace S7.Net.Protocol if (dataItem.Value is string s) return dataItem.VarType == VarType.StringEx ? StringEx.ToByteArray(s, dataItem.Count) - : Types.String.ToByteArray(s); + : Types.String.ToByteArray(s, dataItem.Count); return SerializeValue(dataItem.Value); } @@ -56,7 +56,10 @@ namespace S7.Net.Protocol case "Single[]": return Types.Single.ToByteArray((float[])value); case "String": - return Types.String.ToByteArray(value as string); + // Hack: This is backwards compatible with the old code, but functionally it's broken + // if the consumer does not pay attention to string length. + var stringVal = (string) value; + return Types.String.ToByteArray(stringVal, stringVal.Length); default: throw new InvalidVariableTypeException(); } diff --git a/S7.Net/Types/String.cs b/S7.Net/Types/String.cs index d1ca263..aaf3428 100644 --- a/S7.Net/Types/String.cs +++ b/S7.Net/Types/String.cs @@ -6,11 +6,21 @@ public class String { /// - /// Converts a string to S7 bytes + /// Converts a string to of bytes, padded with 0-bytes if required. /// - public static byte[] ToByteArray(string value) + /// The string to write to the PLC. + /// The amount of bytes reserved for the in the PLC. + public static byte[] ToByteArray(string value, int reservedLength) { - return System.Text.Encoding.ASCII.GetBytes(value); + var length = value?.Length; + if (length > reservedLength) length = reservedLength; + var bytes = new byte[reservedLength]; + + if (length == null || length == 0) return bytes; + + System.Text.Encoding.ASCII.GetBytes(value, 0, length.Value, bytes, 0); + + return bytes; } ///