# Bug Name
**IndexOutOfRangeException when selecting version-dependent DLMS objects with unsupported attributes**
# Bug Description
## Summary
An `IndexOutOfRangeException` is thrown when selecting or reading certain DLMS objects (specifically `GXDLMSPushSetup`) that have version-dependent attribute counts, but whose UI views only implement controls for a subset of those attributes.
## Affected Components
- `GXDLMSPushSetupView.OnValueChanged()`
- `GXDLMSPushSetupView.OnAccessRightsChange()`
- `GXDlmsUi.ObjectChanged()` → `UpdateProperty()`
## Root Cause Analysis
The `GXDLMSPushSetup` object returns different attribute counts based on its version:
- **Version 0**: returns 7 attributes
- **Version 1**: returns 10 attributes
- **Version 2**: returns 13 attributes
However, `GXDLMSPushSetupView` only implements UI controls and handlers for attributes **2, 3, and 4**.
When the framework calls `ObjectChanged()` to initialize a view, it iterates through all attributes (1 to N) and invokes:
- `UpdateProperty()` → `OnValueChanged()`
- `UpdateAccessRights()` → `OnAccessRightsChange()`
For attributes outside the range [2,4], the view's `OnValueChanged()` method throws:
```csharp
else
{
throw new IndexOutOfRangeException("index");
}
```
This is problematic because:
1. Version-dependent attributes (5-13) don't have UI controls in this view
2. They should be ignored rather than causing exceptions
3. The framework has no way to know which indices are supported by a specific view
## Reproduction Steps
### Primary Reproduction (UI Selection)
1. Open GXDLMSDirector application
2. Connect to a device with `GXDLMSPushSetup` object
3. Navigate to the object tree view
4. Click on the `GXDLMSPushSetup` object
5. **Expected Result:** Object details displayed in UI panel
6. **Actual Result:** `IndexOutOfRangeException("index")` is thrown
### Secondary Reproduction (Device Read)
1. Configure GXDLMSDirector to read from a device
2. Device contains `GXDLMSPushSetup` object
3. Trigger read operation for PushSetup attributes
4. **Expected Result:** Attributes are read and displayed
5. **Actual Result:** `ArgumentOutOfRangeException` during deserialization in `MainForm.ReadDevice()`
## Exception Stack Trace
```
System.IndexOutOfRangeException: index
at Gurux.DLMS.UI.GXDLMSPushSetupView.OnValueChanged(GXDLMSViewArguments arg)
at Gurux.DLMS.UI.GXDlmsUi.UpdateProperty(GXDLMSClient client, GXDLMSObject obj, int index, IGXDLMSView view, bool connected, bool user)
at Gurux.DLMS.UI.GXDlmsUi.ObjectChanged(IGXDLMSView view, GXDLMSClient client, GXDLMSObject target, bool connected)
at GXDLMSDirector.MainForm.SelectItem(object obj)
at GXDLMSDirector.MainForm.ObjectTree_AfterSelect(object sender, TreeViewEventArgs e)
```
## Impact Assessment
| Category | Details |
|----------|---------|
| **Severity** | **HIGH** |
| **Crash Type** | Unhandled Exception - Application crashes |
| **Scope** | All `GXDLMSPushSetup` objects; potentially other version-dependent DLMS objects |
| **User Impact** | Users cannot view or manage PushSetup objects; device reads fail completely |
| **Workaround** | None - users must avoid PushSetup objects or use different tools |
## Affected Code Files
| File | Lines | Issue |
|------|-------|-------|
| `GXDLMSPushSetupView.cs` | 106 | Throws exception in `OnValueChanged()` for unsupported indices |
| `GXDLMSPushSetupView.cs` | 173 | Commented-out throw in `OnAccessRightsChange()` (but silently fails) |
| `GXDlmsUi.cs` | 287-293 | Calls `OnValueChanged()` without defensive exception handling |
| `GXDlmsUi.cs` | 323-343 | Calls `OnAccessRightsChange()` without defensive exception handling |
| `GXDLMSPushSetup.cs` | GetAttributeCount() | Returns version-dependent count (7, 10, or 13) |
| `GXDLMSPushSetup.cs` | GetNames() | Returns fixed array of 13 names (always) |
| `GXDLMSPushSetup.cs` | GetMethodNames() | Returns version-dependent array (1 or 2 methods) |
## Related Objects
This issue likely affects other DLMS objects with version-dependent attributes:
- `GXDLMSAssociationLN`
- `GXDLMSAssociationSN`
- `GXDLMSProfileGeneric`
- Other objects with multiple versions
# Technical Details
## Version-Dependent Behavior
**GXDLMSPushSetup.GetAttributeCount():**
```csharp
int IGXDLMSBase.GetAttributeCount()
{
if (Version == 0)
return 7;
if (Version == 1)
return 10;
return 13; // Version 2
}
```
**GXDLMSPushSetupView.OnValueChanged():**
```csharp
public void OnValueChanged(GXDLMSViewArguments arg)
{
if (arg.Index == 2)
{
// Handle attribute 2
}
else if (arg.Index == 3)
{
// Handle attribute 3
}
else if (arg.Index == 4)
{
// Handle attribute 4
}
else
{
throw new IndexOutOfRangeException("index"); // PROBLEM HERE
}
}
```
## Flow Sequence
1. User selects `GXDLMSPushSetup` object in tree
2. `SelectItem(obj)` is called
3. `ObjectChanged(view, client, obj, connected)` is called
4. Loop: `for (int index = 1; index <= GetAttributeCount(); ++index)`
5. `UpdateProperty(client, obj, index, view, ...)` is called for each index
6. For unsupported indices (5-13), `view.OnValueChanged(arg)` throws exception
7. Exception bubbles up to caller
# Severity Justification
- **HIGH** because:
- Application crashes (unhandled exception)
- No user recovery possible
- Affects common DLMS object type
- Blocks normal workflow with affected devices
- Problem occurs during routine UI interaction
# Environment
- **Target Frameworks:** .NET Framework 4.6 - 4.8, .NET Core 3.1, .NET Standard 2.0 - 2.1, .NET 6, 9, 10
- **Component:** Gurux.DLMS.UI
- **Trigger:** User selection of PushSetup object or device read operation
# Proposed Root Cause Classification
**Category:** Defensive Programming / Version Compatibility Issue
**Root Issue:** View implementations do not gracefully handle attribute indices for which they have no UI controls. Instead of silently ignoring unsupported indices, they throw exceptions.
# Notes
- The framework cannot know in advance which attribute indices a view implementation supports
- Views should either:
1. Handle all possible attribute indices (including no-ops for unsupported ones)
2. Or the framework should have a mechanism to query supported indices
- Currently there is no such mechanism, making option 1 the appropriate solution
- This is a systemic issue affecting all view implementations with version-dependent DLMS objects
- The problem manifests particularly with `GXDLMSPushSetup` due to its large range of versions (0-2) and significant attribute count variation
# Additional Context
The `GXDLMSPushSetupView` supports:
- **Attribute 2 (PushObjectList):** ListView with objects
- **Attribute 3 (SendDestinationAndMethod):** ComboBoxes for service/message + TextBox for destination
- **Attribute 4 (CommunicationWindow):** ListView with date/time ranges
Attributes 1, 5-13 have no UI representation and should be silently ignored during view initialization rather than throwing exceptions.