fix(serialization): Remove legacy BinaryFormatter support
SonarQube Analysis / sonarqube (pull_request) Successful in 4m42s

The `[Serializable]` attribute and corresponding `[OnDeserialized]` methods have been removed from various breakdown classes. This eliminates reliance on `BinaryFormatter`, which is a deprecated and insecure serialization mechanism in modern .NET.

This change also resolves SonarQube rule S5766 warnings by removing the context in which they apply, leading to cleaner and more secure code.
This commit is contained in:
Thom Lamb
2026-05-20 17:44:21 -05:00
parent 3de3b8bf68
commit 2d9148547f
20 changed files with 0 additions and 201 deletions
@@ -5,7 +5,6 @@ namespace Strata.SqlTools.SqlBreakdown.Classes;
/// <summary>
/// Represents a query parameter with a name and value.
/// </summary>
[Serializable]
public sealed class QueryParam : IQueryParam
{
/// <summary>
@@ -10,7 +10,6 @@ namespace Strata.SqlTools.SqlBreakdown.Classes;
/// This class is primarily used for batch SQL parsing where raw statements need to be stored
/// without detailed clause breakdown. Actual clause parsing can be performed separately.
/// </remarks>
[Serializable]
public class RawSqlBreakdown : ISqlBreakdown
{
/// <summary>
@@ -7,7 +7,6 @@ namespace Strata.SqlTools.SqlBreakdown.Classes;
/// <summary>
/// Base class for SQL query breakdowns that provides common setup/finish clause handling and cloning.
/// </summary>
[Serializable]
public abstract class SqlBreakdownBase : ISqlBreakdown
{
/// <summary>
@@ -48,18 +47,6 @@ public abstract class SqlBreakdownBase : ISqlBreakdown
/// </summary>
public bool IsUsingFinishClause => FinishClauses.Count > 0;
/// <summary>
/// Re-establishes the invariants normally guaranteed by the constructors after the object
/// is reconstructed by deserialization. Deserialization bypasses constructors, so the
/// collection state must be re-validated to avoid a partially-initialized object
/// (SonarQube rule S5766).
/// </summary>
protected void RevalidateBreakdownState()
{
SetupClauses ??= new List<string>();
FinishClauses ??= new ArrayList();
}
/// <summary>
/// Gets the SQL breakdown as a string. Must be implemented by derived classes.
/// </summary>
@@ -1,4 +1,3 @@
using System.Runtime.Serialization;
using System.Text;
using Strata.SqlTools.SqlBreakdown.Interfaces;
using Strata.SqlTools.SqlBreakdown.Interfaces.QueryEngine;
@@ -13,7 +12,6 @@ namespace Strata.SqlTools.SqlBreakdown.Classes;
/// allowing efficient management and retrieval of multiple SQL breakdowns as a unified collection.
/// Implements ICollection&lt;ISqlBreakdown&gt; to provide standard collection semantics and LINQ support.
/// </remarks>
[Serializable]
public class SqlBreakdownCollection : ICollection<ISqlBreakdown>
{
private readonly List<ISqlBreakdown> _breakdowns;
@@ -36,20 +34,6 @@ public class SqlBreakdownCollection : ICollection<ISqlBreakdown>
_breakdowns = new List<ISqlBreakdown>(breakdowns ?? Enumerable.Empty<ISqlBreakdown>());
}
/// <summary>
/// Validates that the backing list survived deserialization, since deserialization bypasses
/// the constructors that normally initialize it (SonarQube rule S5766).
/// </summary>
/// <param name="context">The streaming context for the deserialization operation.</param>
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
if (_breakdowns is null)
{
throw new SerializationException("Deserialized SqlBreakdownCollection is missing its backing list.");
}
}
/// <summary>
/// Gets the collection of SQL breakdowns.
/// </summary>
@@ -1,4 +1,3 @@
using System.Runtime.Serialization;
using System.Text;
using Strata.SqlTools.SqlBreakdown.Interfaces.Core;
@@ -8,7 +7,6 @@ namespace Strata.SqlTools.SqlBreakdown.Classes;
/// Represents a SQL filter with an expression and parameters.
/// Implements SQL appendable and SQL interfaces for query building.
/// </summary>
[Serializable]
public class SqlFilter : ISqlAppendable
{
private readonly StringBuilder _sqlExpression;
@@ -59,21 +57,6 @@ public class SqlFilter : ISqlAppendable
}
}
/// <summary>
/// Validates that the expression and parameter state survived deserialization, since
/// deserialization bypasses the constructors that normally initialize them and enforce the
/// even parameter-name/value pairing (SonarQube rule S5766).
/// </summary>
/// <param name="context">The streaming context for the deserialization operation.</param>
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
if (_sqlExpression is null || _parameterValues is null)
{
throw new SerializationException("Deserialized SqlFilter is missing its expression or parameter state.");
}
}
/// <summary>
/// Gets or sets the SQL expression.
/// </summary>