diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt/Sparkplug/SparkplugCodec.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt/Sparkplug/SparkplugCodec.cs index 5234cbbe..b428ee19 100644 --- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt/Sparkplug/SparkplugCodec.cs +++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt/Sparkplug/SparkplugCodec.cs @@ -74,36 +74,38 @@ public static class SparkplugCodec return false; } - Payload proto; try { - proto = Payload.Parser.ParseFrom(wire); + var proto = Payload.Parser.ParseFrom(wire); + + var metrics = proto.Metrics.Count == 0 + ? [] + : new SparkplugMetric[proto.Metrics.Count]; + + for (var i = 0; i < proto.Metrics.Count; i++) + { + metrics[i] = ProjectMetric(proto.Metrics[i]); + } + + payload = new SparkplugPayload( + IsValid: true, + Seq: proto.HasSeq ? proto.Seq : null, + TimestampMs: proto.HasTimestamp ? proto.Timestamp : null, + Metrics: metrics); + + return true; } catch (Exception) { - // Deliberately broad. InvalidProtocolBufferException covers malformed, truncated and - // over-nested input, but this is the dispatcher-thread boundary: the contract is a - // verdict for EVERY input, and narrowing the catch would trade that guarantee for a - // taxonomy nobody downstream can act on. + // Deliberately broad, and deliberately spanning the projection as well as the parse. + // InvalidProtocolBufferException covers malformed, truncated and over-nested input, but + // this is the dispatcher-thread boundary and the projection walks an attacker-shaped + // object graph: the contract is a verdict for EVERY input, so a guard that stopped at + // the parse would be a contract with a hole in it. Narrowing the catch would trade the + // guarantee for a taxonomy nobody downstream can act on. + payload = SparkplugPayload.Invalid; return false; } - - var metrics = proto.Metrics.Count == 0 - ? [] - : new SparkplugMetric[proto.Metrics.Count]; - - for (var i = 0; i < proto.Metrics.Count; i++) - { - metrics[i] = ProjectMetric(proto.Metrics[i]); - } - - payload = new SparkplugPayload( - IsValid: true, - Seq: proto.HasSeq ? proto.Seq : null, - TimestampMs: proto.HasTimestamp ? proto.Timestamp : null, - Metrics: metrics); - - return true; } ///