review(Driver.S7.Contracts): first review; gate stringLength check to String type

First review at 7286d320. -002 (Low): stringLength range check now only fires for
S7DataType.String (was rejecting valid non-String equipment-tag blobs). -001 ArrayCount=1
doc fix. -003 (driver-specs.md CpuType omissions) deferred. Consuming Driver.S7.Tests green.
This commit is contained in:
Joseph Doherty
2026-06-19 12:22:53 -04:00
parent 9244e506c9
commit 5d01271f03
3 changed files with 89 additions and 4 deletions
@@ -105,7 +105,8 @@ public sealed class S7ProbeOptions
/// coils that drive edge-triggered routines in the PLC program.
/// </param>
/// <param name="ArrayCount">
/// Element count when the tag is a 1-D array; <c>null</c> (or <c>&lt;= 1</c>) for a scalar.
/// Element count when the tag is a 1-D array; <c>null</c> for a scalar. Any value <c>&gt;= 1</c>
/// (including 1) surfaces as a 1-D OPC UA array node.
/// For an equipment tag this is threaded from the <c>TagConfig</c> JSON's <c>arrayLength</c>
/// (honoured only when <c>isArray</c> is true) by <see cref="S7EquipmentTagParser"/>. When
/// set, the driver issues a single contiguous block read of
@@ -33,9 +33,10 @@ public static class S7EquipmentTagParser
if (string.IsNullOrWhiteSpace(address)) return false;
var dataType = ReadEnum(root, "dataType", S7DataType.Int16);
var stringLength = ReadInt(root, "stringLength");
// Range-guard rather than truncate: an S7 string can't exceed 254 chars, and a
// negative length is meaningless — reject so a malformed blob can't slip through.
if (stringLength < 0 || stringLength > MaxStringLength) return false;
// Range-guard applies only to String tags: an S7 string can't exceed 254 chars, and a
// negative length is meaningless. For non-String types stringLength is irrelevant and any
// authored value (including an out-of-range remnant from copy-paste) must not block parsing.
if (dataType == S7DataType.String && (stringLength < 0 || stringLength > MaxStringLength)) return false;
// Array intent: the canonical sink-side parse (DeploymentArtifact.ExtractTagArray)
// honours arrayLength ONLY when isArray is true AND the prop is a JSON number — mirror
// that here so the driver's transient def agrees byte-for-byte with the materialised