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
@@ -1,5 +1,4 @@
using System.Collections;
using System.Runtime.Serialization;
using System.Text;
using SqlServerDeleteBreakdown = Strata.SqlTools.Breakdowns.SqlServer.DeleteBreakdown;
using StatementParser = Strata.SqlTools.Statements.Snowflake.StatementParser;
@@ -9,7 +8,6 @@ namespace Strata.SqlTools.Breakdowns.Snowflake;
/// <summary>
/// Represents a DELETE SQL statement breakdown with FROM and WHERE clauses for Snowflake.
/// </summary>
[Serializable]
public class DeleteBreakdown : SqlServerDeleteBreakdown
{
private static readonly StatementParser SnowflakeParserInstance = new StatementParser();
@@ -41,14 +39,6 @@ public class DeleteBreakdown : SqlServerDeleteBreakdown
WhereClause.Comment = whereComments.Count > 0 ? string.Join(" ", whereComments) : null;
}
/// <summary>
/// Re-establishes invariants after deserialization, since deserialization bypasses the
/// constructors that normally initialize the breakdown's clause state (SonarQube rule S5766).
/// </summary>
/// <param name="context">The streaming context for the deserialization operation.</param>
[OnDeserialized]
private void OnDeserialized(StreamingContext context) => RevalidateBreakdownState();
/// <summary>
/// Gets the SQL breakdown as a string for Snowflake.
/// </summary>
@@ -1,5 +1,4 @@
using System.Collections;
using System.Runtime.Serialization;
using Strata.SqlTools.SqlBreakdown.Utilities;
using SqlServerInsertBreakdown = Strata.SqlTools.Breakdowns.SqlServer.InsertBreakdown;
using StatementParser = Strata.SqlTools.Statements.Snowflake.StatementParser;
@@ -9,7 +8,6 @@ namespace Strata.SqlTools.Breakdowns.Snowflake;
/// <summary>
/// Represents an INSERT SQL statement breakdown with column and value clauses for Snowflake.
/// </summary>
[Serializable]
public class InsertBreakdown : SqlServerInsertBreakdown
{
private static readonly StatementParser SnowflakeParserInstance = new StatementParser();
@@ -66,14 +64,6 @@ public class InsertBreakdown : SqlServerInsertBreakdown
ValuesClause.Clause = string.Join(",", valuesList);
}
/// <summary>
/// Re-establishes invariants after deserialization, since deserialization bypasses the
/// constructors that normally initialize the breakdown's clause state (SonarQube rule S5766).
/// </summary>
/// <param name="context">The streaming context for the deserialization operation.</param>
[OnDeserialized]
private void OnDeserialized(StreamingContext context) => RevalidateBreakdownState();
#region Parse Methods
/// <summary>
@@ -1,5 +1,4 @@
using System.Collections;
using System.Runtime.Serialization;
using System.Text;
using SqlServerProcedureBreakdown = Strata.SqlTools.Breakdowns.SqlServer.ProcedureBreakdown;
using StatementParser = Strata.SqlTools.Statements.Snowflake.StatementParser;
@@ -9,7 +8,6 @@ namespace Strata.SqlTools.Breakdowns.Snowflake;
/// <summary>
/// Represents a Snowflake stored procedure call breakdown with procedure name and parameters.
/// </summary>
[Serializable]
public class ProcedureBreakdown : SqlServerProcedureBreakdown
{
private static readonly StatementParser SnowflakeParserInstance = new StatementParser();
@@ -47,15 +45,6 @@ public class ProcedureBreakdown : SqlServerProcedureBreakdown
Parameters = parameters ?? new Dictionary<string, string>();
}
/// <summary>
/// Re-establishes invariants after deserialization, since deserialization bypasses the
/// constructors that normally initialize the procedure name and parameter collection
/// (SonarQube rule S5766).
/// </summary>
/// <param name="context">The streaming context for the deserialization operation.</param>
[OnDeserialized]
private void OnDeserialized(StreamingContext context) => RevalidateBreakdownState();
/// <summary>
/// Gets the SQL breakdown as a string for Snowflake.
/// </summary>
@@ -1,5 +1,4 @@
using System.Collections;
using System.Runtime.Serialization;
using System.Text;
using Strata.SqlTools.SqlBreakdown.Classes;
using Strata.SqlTools.SqlBreakdown.Expressions;
@@ -19,7 +18,6 @@ namespace Strata.SqlTools.Breakdowns.Snowflake;
/// Represents a Snowflake SQL query breakdown with all clauses, following Snowflake SQL standards.
/// Handles both :parameter and @parameter syntax for Snowflake compatibility.
/// </summary>
[Serializable]
public class QueryBreakdown : SqlServerQueryBreakdown
{
private const string ExpressionNullErrorMessage = "Expression cannot be null.";
@@ -86,14 +84,6 @@ public class QueryBreakdown : SqlServerQueryBreakdown
OrderByClause.Comment = orderByComments.Count > 0 ? string.Join(" ", orderByComments) : null;
}
/// <summary>
/// Re-establishes invariants after deserialization, since deserialization bypasses the
/// constructors that normally initialize the breakdown's clause state (SonarQube rule S5766).
/// </summary>
/// <param name="context">The streaming context for the deserialization operation.</param>
[OnDeserialized]
private void OnDeserialized(StreamingContext context) => RevalidateBreakdownState();
/// <summary>
/// Adds a parameter to the query using Snowflake's :param format.
/// Also adds @param format for compatibility.
@@ -1,4 +1,3 @@
using System.Runtime.Serialization;
using System.Text;
using Strata.SqlTools.SqlBreakdown.Classes;
using Strata.SqlTools.SqlBreakdown.Interfaces;
@@ -14,7 +13,6 @@ namespace Strata.SqlTools.Breakdowns.Snowflake;
/// time travel, snowflake-specific parameters (:parameter and @parameter syntax),
/// and proper batch handling.
/// </remarks>
[Serializable]
public class QueryBreakdownCollection : SqlBreakdownCollection
{
private readonly List<QueryBreakdown> _queryBreakdowns;
@@ -37,20 +35,6 @@ public class QueryBreakdownCollection : SqlBreakdownCollection
_queryBreakdowns = new List<QueryBreakdown>(queryBreakdowns ?? Enumerable.Empty<QueryBreakdown>());
}
/// <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 (_queryBreakdowns is null)
{
throw new SerializationException("Deserialized QueryBreakdownCollection is missing its backing list.");
}
}
/// <summary>
/// Gets the collection of QueryBreakdown objects.
/// </summary>
@@ -1,5 +1,4 @@
using System.Collections;
using System.Runtime.Serialization;
using System.Text;
using SqlServerUpdateBreakdown = Strata.SqlTools.Breakdowns.SqlServer.UpdateBreakdown;
using StatementParser = Strata.SqlTools.Statements.Snowflake.StatementParser;
@@ -9,7 +8,6 @@ namespace Strata.SqlTools.Breakdowns.Snowflake;
/// <summary>
/// Represents an UPDATE SQL statement breakdown with SET, FROM, and WHERE clauses for Snowflake.
/// </summary>
[Serializable]
public class UpdateBreakdown : SqlServerUpdateBreakdown
{
private static readonly StatementParser SnowflakeParserInstance = new StatementParser();
@@ -46,14 +44,6 @@ public class UpdateBreakdown : SqlServerUpdateBreakdown
WhereClause.Comment = whereComments.Count > 0 ? string.Join(" ", whereComments) : null;
}
/// <summary>
/// Re-establishes invariants after deserialization, since deserialization bypasses the
/// constructors that normally initialize the breakdown's clause state (SonarQube rule S5766).
/// </summary>
/// <param name="context">The streaming context for the deserialization operation.</param>
[OnDeserialized]
private void OnDeserialized(StreamingContext context) => RevalidateBreakdownState();
/// <summary>
/// Gets the SQL breakdown as a string for Snowflake.
/// </summary>