fix(siteruntime): reject SetStaticAttribute with malformed list value (no silent poison persist)
This commit is contained in:
@@ -344,7 +344,33 @@ public class InstanceActor : ReceiveActor
|
||||
if (_resolvedAttributeByName.TryGetValue(command.AttributeName, out var resolved)
|
||||
&& IsListAttribute(resolved))
|
||||
{
|
||||
_attributes[command.AttributeName] = DecodeAttributeValue(resolved, command.Value);
|
||||
// MV-7: the script path pre-encodes valid canonical JSON via ScopeAccessors,
|
||||
// but the Inbound API / direct-command path can submit an arbitrary
|
||||
// command.Value. A non-empty value that fails to decode (malformed JSON,
|
||||
// bad element, missing element type) is poison: storing it would null the
|
||||
// in-memory value yet publish "Good" quality and durably persist the bad
|
||||
// JSON (which then loads as Bad next restart). Reject such writes outright.
|
||||
// Note: DecodeAttributeValue returns null for BOTH a null/empty input
|
||||
// (valid — clearing) AND a malformed non-empty input (invalid). Only the
|
||||
// latter is rejected, hence the explicit IsNullOrWhiteSpace guard. An empty
|
||||
// list "[]" decodes to a non-null empty List, so it passes through.
|
||||
var decoded = DecodeAttributeValue(resolved, command.Value);
|
||||
if (!string.IsNullOrWhiteSpace(command.Value) && decoded == null)
|
||||
{
|
||||
_logger.LogWarning(
|
||||
"SetAttribute rejected — value for List attribute '{Attribute}' on instance '{Instance}' is not a valid list",
|
||||
command.AttributeName, _instanceUniqueName);
|
||||
Sender.Tell(new SetStaticAttributeResponse(
|
||||
command.CorrelationId,
|
||||
_instanceUniqueName,
|
||||
command.AttributeName,
|
||||
false,
|
||||
$"Invalid list value for attribute '{command.AttributeName}'",
|
||||
DateTimeOffset.UtcNow));
|
||||
return;
|
||||
}
|
||||
|
||||
_attributes[command.AttributeName] = decoded;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user