mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-24 11:01:55 +08:00
fix/encoder-stack-depth-json-flake
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9b034f8291 |
Enable nullable reference types centrally; migrate all unset and annotations-only projects (#4700)
# Description Nullable reference types are now enabled once, in `common.props`, and every project in the repository builds warning-clean with them. **Configuration** - `<Nullable>enable</Nullable>` lives in `common.props`. All per-project `<Nullable>` settings are removed: 178 project files (enable, annotations, and the `disable` in the three Aot test projects). - 419 per-file `#nullable enable`/`restore` directives and the 4 `#nullable disable` directives are removed. - Kept on purpose: - The 5 `<auto-generated>` schema files (`UANodeSet.cs`, `UA Type Dictionary.cs`, `OPCBinarySchema.cs`, `SecuredApplication.cs`, `PInvokeHelper.cs`) keep `#nullable enable`. The compiler ignores the project setting in generated code, so the directive is required there. - `tests/Opc.Ua.Interop.LegacyPeer` keeps `disable`. It builds against the 1.5.378 packages and does not import the repository props. - `docs/DeveloperGuide.md` and `.github/copilot-instructions.md` now describe the central setting. **Migration** (the 43 unset and 13 annotations-only projects, roughly 10k diagnostics) - **Production code: annotated at the declarations.** Covers `tools/Opc.Ua.SourceGeneration.Core`, `src/Opc.Ua.Lds.Server` and the LDS sample. - Members, parameters and returns are nullable where null actually flows. - Null-check helpers carry `[NotNullWhen]` (`IsNull`, `IsValidXmlName`, `IsMethodTypeDesign`). - `CoreUtils.Format`, `Utils.Format`, `ITemplateWriter.WriteLine` take `params object?[]`. `Template.AddReplacement` takes `string?` (rendering already skips null replacements). - `IRegisteredServerStore.RegisterAsync` returns `Task<RegistrationEntry?>`: it returns null when a registration is removed. - Dereferences backed by an invariant (for example, the validated model) use `!`, so runtime behaviour is unchanged. - **Behavioural changes in production code** (small, deliberate): - `NodeSetToModelDesign` throws `InvalidOperationException` when the file is not a NodeSet. Before, it threw a NullReferenceException on the next line. - `ModelDesignValidator` starts its lookup tables empty instead of null. A redundant `if (m_nodes == null) return;` guard is gone. - **Test code: minimal annotations.** - `?` on values that can be null, `!` where the test asserts non-null. - `= null!` for fixture members assigned in SetUp. - `TryGetStructure<T>(out T? x)` where the inferred `T?` broke the `IEncodeable` constraint. - A few redundant `== null` checks on structs (`NodeId`, `ArrayOf<T>`) folded into the adjacent `IsNull`/`Count` checks. **Notes for reviewers** - The diff is large (~1,500 files) but almost entirely mechanical: `?`, `!` and directive removal. The non-annotation changes are listed above. - Known follow-up, not done here: `IModelDesign.Namespaces/TargetNamespace/NamespaceUris` stay non-nullable even though the validator returns null before it loads a dictionary. Making them nullable would ripple through every generator call site. ## Related Issues - Fixes #4439 ## Checklist - [ ] I have signed the [CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf) and read the [CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md) doc. - [ ] I have added tests that prove my fix is effective or that my feature works and increased code coverage. - [x] I have added all necessary documentation. - [x] I have verified that my changes do not introduce (new) build or analyzer warnings. - [ ] I ran **all** tests locally using the **UA.slnx** solution against at least .net **framework** and .net **10**, and all passed. - [ ] I fixed **all** failing and flaky tests in the CI pipelines and **all** CodeQL warnings. - [ ] I have addressed **all** PR feedback received. The "no new warnings" box covers net10.0 and net48: full non-incremental builds of `UA.slnx`, `tools/SourceGeneration.slnx`, `tools/MigrationAnalyzer.slnx` and the Aot test projects finished with 0 warnings and 0 errors under the repository's warnings-as-errors settings. net9.0 and net8.0 also had no nullable diagnostics, but they were not rebuilt after the final fixes. Tests have not been run locally yet. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
ea93c86da2 |
Fix the Opc.Ua.Client defects reported by the client stack audit (#4471)
# Description
Fixes the 78 `Opc.Ua.Client` findings of a read-only bug audit of
`Opc.Ua.Client` / `Opc.Ua.Types` / `Opc.Ua.SourceGeneration` taken at
|
||
|
|
ede0b68154 |
Fix reverse-connect certificate leak and stale-connection retry (#4386)
Two related robustness fixes on the reverse-connect / UA-SC handshake path, both surfaced by the Sessions suite. ## 1. Certificate handle leak in the asymmetric header parse `UaSCBinaryChannel.ReadAsymmetricMessageHeader` parses the sender certificate chain (`Utils.ParseCertificateChainBlob`, allocating fresh `Certificate` handles) and then runs several validations that can throw — invalid/missing sender thumbprint, no matching receiver certificate, receiver thumbprint mismatch, missing receiver thumbprint. The chain is returned through an `out` parameter, so a throw never reaches the caller's `using (senderCertificateChain)` in `ReadAsymmetricMessageAsync`, and the freshly parsed chain is abandoned. For a self-signed leaf that is exactly the intermittent `created == disposed + 1` seen on the Release leak gate under coverage instrumentation. This is the third sibling of the two concurrent-reconnect ownership leaks closed in #4356. **Fix:** wrap the post-allocation region in a `try/catch` that disposes the chain before rethrowing (validation logic unchanged). **Test:** `ReadAsymmetricMessageHeaderDisposesSenderChainWhenReceiverThumbprintMismatches` crafts a header with a valid sender certificate and a mismatched receiver thumbprint; without the fix it reproduces `created=3, disposed=2` and trips the assembly leak gate, with the fix it passes. ## 2. Stale reverse-connection retry A reverse connection the `ReverseConnectManager` delivers can already have been closed by the server before the secure-channel handshake runs: a server rotates and times out the outbound connections it offers, so the one matched here — especially after an `updateBeforeConnect` discovery round consumed an earlier one — may be stale. That surfaced as an intermittent `BadConnectionClosed` ("Remote side closed the connection") failing the whole connect (e.g. `ReverseConnect2Async(true,true,…)`). **Fix:** wrap reverse-connect session creation in `DefaultSessionFactory` in a bounded retry (3 attempts) that requests a freshly delivered connection when an attempt fails with a connection-drop status (`BadConnectionClosed` / `BadNotConnected` / `BadSecureChannelClosed`). Non-transient failures and cancellation still surface immediately; the bound prevents an unbounded loop against a genuinely unreachable server. ## 3. Test-host crash: NULL channel map in the inactivity timer `TcpTransportListener.DetectInactiveChannels` (a fire-and-forget inactivity-timer callback) iterated `m_channels` without holding `m_lock`, while `CloseAsync` disposes the timer and nulls `m_channels` under the lock. Disposing an `ITimer` does not join an already-dispatched callback, so a late callback dereferenced the now-null map and threw an unhandled `NullReferenceException` on a thread-pool thread, crashing the process. This intermittently aborted the `test-macOS-latest-Client` host. **Fix:** snapshot `m_channels` and return early when null (mirroring the existing guarded read on the accept path). Deterministic regression test invokes the callback on a listener whose channel map is null (its state before `OpenAsync` / after `CloseAsync`) and asserts it does not throw. ## Verification - `Opc.Ua.Core.Tests` Stack.Transport/Client/Server: 2178 passed, leak gate green. - Coverage-instrumented `Opc.Ua.Sessions.Tests` (the CI leg): 775 passed, 0 failed, leak gate green. - Reverse-connect suite (`ReverseConnect*`): 52 passed with the retry. - `Opc.Ua.Core` and `Opc.Ua.Client` build warning-free (net10.0, net48, netstandard2.1, net472). Note: the reverse-connect failure is a rare timing flake (0 reproductions in 88 local attempts), so fix #2 addresses the root cause identified from the ADO log and is validated by construction plus regression rather than by a captured local repro. ## Related - Follows #4356 (concurrent channel reconnect certificate leaks). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Marc <marcschier@hotmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
7cec2d614d | Move repository files to the consolidated layout |