fix(commons): resolve Commons-013,014 — integral JSON index handling, distinguish Malformed vs Legacy OPC UA config
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
| Last reviewed | 2026-05-17 |
|
||||
| Reviewer | claude-agent |
|
||||
| Commit reviewed | `39d737e` |
|
||||
| Open findings | 2 |
|
||||
| Open findings | 0 |
|
||||
|
||||
## Summary
|
||||
|
||||
@@ -587,7 +587,7 @@ each pinned under `de-DE`).
|
||||
|--|--|
|
||||
| Severity | Low |
|
||||
| Category | Correctness & logic bugs |
|
||||
| Status | Open |
|
||||
| Status | Resolved |
|
||||
| Location | `src/ScadaLink.Commons/Types/DynamicJsonElement.cs:40-54` |
|
||||
|
||||
**Description**
|
||||
@@ -611,7 +611,18 @@ single integer before the bounds check. Add a regression test indexing with a `l
|
||||
|
||||
**Resolution**
|
||||
|
||||
_Unresolved._
|
||||
Resolved 2026-05-17 — confirmed the `int`-only guard, and during fixing found the
|
||||
underlying cause was wider than the finding text: `Wrap`'s `TryGetInt64 ? long : double`
|
||||
ternary unified both branches to `double`, so integral JSON numbers were never actually
|
||||
boxed as `long` — `obj.count` always surfaced as `double`. Fixed at the root: `Wrap`
|
||||
delegates to a new `WrapNumber` helper that boxes integral numbers as `long` and
|
||||
non-integral as `double` with separate typed returns; `TryGetIndex` now accepts any
|
||||
integral index via `TryGetIntegralIndex` (`int`/`long`/`short`/`byte`/`sbyte`/`ushort`/
|
||||
`uint`/`ulong`, plus whole-valued `double`/`decimal`) normalized to `long` before the
|
||||
bounds check. Internal-only change — no public-API or message-contract change. Regression
|
||||
tests added in `DynamicJsonElementTests` (`IndexAccess_WithLongIndex_Works`,
|
||||
`IndexAccess_WithIndexDerivedFromWrappedJsonNumber_Works`,
|
||||
`IndexAccess_WithWideningIntegralIndex_Works`, `IndexAccess_WithLongIndexOutOfRange_Throws`).
|
||||
|
||||
### Commons-014 — `OpcUaEndpointConfigSerializer.Deserialize` can mislabel a corrupt typed row as `Legacy`
|
||||
|
||||
@@ -619,7 +630,7 @@ _Unresolved._
|
||||
|--|--|
|
||||
| Severity | Low |
|
||||
| Category | Error handling & resilience |
|
||||
| Status | Open |
|
||||
| Status | Resolved |
|
||||
| Location | `src/ScadaLink.Commons/Serialization/OpcUaEndpointConfigSerializer.cs:107-131` |
|
||||
|
||||
**Description**
|
||||
@@ -651,4 +662,15 @@ field.
|
||||
|
||||
**Resolution**
|
||||
|
||||
_Unresolved._
|
||||
Resolved 2026-05-17 — confirmed the swallow-and-fall-through against the source. Split
|
||||
`Deserialize` into a shape-detection phase and a materialization phase: it first parses
|
||||
the document to decide whether the row is the current typed shape (root object carrying
|
||||
`endpointUrl`); only a non-typed-shape row falls through to `LoadLegacy`. A row that *is*
|
||||
the typed shape but fails `JsonSerializer.Deserialize` (invalid enum, wrong-typed field)
|
||||
is now classified `Malformed` instead of being mislabelled `Legacy` with the offending
|
||||
field silently dropped. The `OpcUaConfigParseResult` shape and `(Config, IsLegacy)`
|
||||
deconstruction are unchanged, so existing callers are unaffected. XML docs updated to
|
||||
describe the corrupt-typed-row branch. Regression tests added in
|
||||
`OpcUaEndpointConfigSerializerTests` (`Deserialize_TypedShapeWithInvalidEnum_ReportsMalformedNotLegacy`,
|
||||
`Deserialize_TypedShapeWithWrongTypeField_ReportsMalformedNotLegacy`,
|
||||
`Deserialize_ValidTypedRow_StillReportsTyped`).
|
||||
|
||||
Reference in New Issue
Block a user