fix(driver-ablegacy): resolve Medium code-review finding (Driver.AbLegacy-004)
DecodeValue for Bit with no bitIndex now reads the full 16-bit word via GetInt16(0) and tests bit 0 instead of GetInt8(0), which only covered the low byte and silently misread any bit in positions 8..15. The comment explains the two decode paths (suffix-present vs suffix-absent). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -117,7 +117,7 @@ reject file numbers on I/O/S, and restrict which file letters may carry a sub-el
|
|||||||
| Severity | Medium |
|
| Severity | Medium |
|
||||||
| Category | Correctness & logic bugs |
|
| Category | Correctness & logic bugs |
|
||||||
| Location | `LibplctagLegacyTagRuntime.cs:36-37` |
|
| Location | `LibplctagLegacyTagRuntime.cs:36-37` |
|
||||||
| Status | Open |
|
| Status | Resolved |
|
||||||
|
|
||||||
**Description:** `DecodeValue` for `AbLegacyDataType.Bit` with `bitIndex == null`
|
**Description:** `DecodeValue` for `AbLegacyDataType.Bit` with `bitIndex == null`
|
||||||
returns `_tag.GetInt8(0) != 0`. A bit-file element (`B3:0/0`) is a single bit inside
|
returns `_tag.GetInt8(0) != 0`. A bit-file element (`B3:0/0`) is a single bit inside
|
||||||
@@ -132,7 +132,7 @@ but a `Bit`-typed tag configured with an address that has no `/bit` suffix (e.g.
|
|||||||
bit suffix on `Bit`-typed tags (validate in `CreateInstance`/`DiscoverAsync`) or
|
bit suffix on `Bit`-typed tags (validate in `CreateInstance`/`DiscoverAsync`) or
|
||||||
decode the full 16-bit word and test bit 0.
|
decode the full 16-bit word and test bit 0.
|
||||||
|
|
||||||
**Resolution:** _(open)_
|
**Resolution:** Resolved 2026-05-22 — `DecodeValue` for `Bit` with no `bitIndex` now reads the full 16-bit word via `GetInt16(0)` and tests bit 0, avoiding the silent half-word truncation from `GetInt8`.
|
||||||
|
|
||||||
### Driver.AbLegacy-005
|
### Driver.AbLegacy-005
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,13 @@ internal sealed class LibplctagLegacyTagRuntime : IAbLegacyTagRuntime
|
|||||||
|
|
||||||
public object? DecodeValue(AbLegacyDataType type, int? bitIndex) => type switch
|
public object? DecodeValue(AbLegacyDataType type, int? bitIndex) => type switch
|
||||||
{
|
{
|
||||||
|
// When a bit suffix is present (e.g. B3:0/5) libplctag resolves the individual bit and
|
||||||
|
// GetBit returns it directly. When there is no suffix the caller addressed a Bit-typed
|
||||||
|
// tag without an explicit bit index; read the full 16-bit word and test bit 0 — GetInt8
|
||||||
|
// only covers the low byte and silently misses any bit set in bits 8..15.
|
||||||
AbLegacyDataType.Bit => bitIndex is int bit
|
AbLegacyDataType.Bit => bitIndex is int bit
|
||||||
? _tag.GetBit(bit)
|
? _tag.GetBit(bit)
|
||||||
: _tag.GetInt8(0) != 0,
|
: (_tag.GetInt16(0) & 1) != 0,
|
||||||
AbLegacyDataType.Int or AbLegacyDataType.AnalogInt => (int)_tag.GetInt16(0),
|
AbLegacyDataType.Int or AbLegacyDataType.AnalogInt => (int)_tag.GetInt16(0),
|
||||||
AbLegacyDataType.Long => _tag.GetInt32(0),
|
AbLegacyDataType.Long => _tag.GetInt32(0),
|
||||||
AbLegacyDataType.Float => _tag.GetFloat32(0),
|
AbLegacyDataType.Float => _tag.GetFloat32(0),
|
||||||
|
|||||||
Reference in New Issue
Block a user