///
@@ -188,5 +188,15 @@ private static int GetAfterSelectInsertPoint(SqlString sql)
}
return 0;
}
+
+ ///
+ /// by default for SQL Anywhere,
+ /// .
+ protected override bool EscapeBackslashInStrings { get; set; } = true;
+
+ ///
+ /// by default for SQL Anywhere,
+ /// .
+ protected override bool UseNPrefixForUnicodeStrings => true;
}
}
diff --git a/src/NHibernate/Dialect/SybaseSQLAnywhere10Dialect.cs b/src/NHibernate/Dialect/SybaseSQLAnywhere10Dialect.cs
index 290e626671f..ac5aa44f8e0 100644
--- a/src/NHibernate/Dialect/SybaseSQLAnywhere10Dialect.cs
+++ b/src/NHibernate/Dialect/SybaseSQLAnywhere10Dialect.cs
@@ -969,5 +969,15 @@ public override IDataBaseSchema GetDataBaseSchema(DbConnection connection)
///
/// SQL Anywhere has a micro-second resolution.
public override long TimestampResolutionInTicks => 10L;
+
+ ///
+ /// by default for SQL Anywhere,
+ /// .
+ protected override bool EscapeBackslashInStrings { get; set; } = true;
+
+ ///
+ /// by default for SQL Anywhere,
+ /// .
+ protected override bool UseNPrefixForUnicodeStrings => true;
}
}
diff --git a/src/NHibernate/Type/AbstractStringType.cs b/src/NHibernate/Type/AbstractStringType.cs
index 9d47aaf07ff..72949c1093c 100644
--- a/src/NHibernate/Type/AbstractStringType.cs
+++ b/src/NHibernate/Type/AbstractStringType.cs
@@ -134,10 +134,9 @@ public object StringToObject(string xml)
#region ILiteralType Members
+ ///
public string ObjectToSQLString(object value, Dialect.Dialect dialect)
- {
- return "'" + (string)value + "'";
- }
+ => dialect.ToStringLiteral((string)value, SqlType);
#endregion
diff --git a/src/NHibernate/nhibernate-configuration.xsd b/src/NHibernate/nhibernate-configuration.xsd
index 08d922ad963..123b2c35e60 100644
--- a/src/NHibernate/nhibernate-configuration.xsd
+++ b/src/NHibernate/nhibernate-configuration.xsd
@@ -176,6 +176,14 @@
+
+
+
+ Indicates if the database needs to have backslash escaped in string literals. The default is
+ dialect dependent.
+
+
+
From 2d21ff390c5990d77e3112eced55dd5e44b020b2 Mon Sep 17 00:00:00 2001
From: Alex Zaytsev
Date: Mon, 3 Jun 2024 21:33:40 +1000
Subject: [PATCH 13/26] Fix argument name
---
src/NHibernate/Dialect/Dialect.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/NHibernate/Dialect/Dialect.cs b/src/NHibernate/Dialect/Dialect.cs
index eb91762c66c..c76992e197c 100644
--- a/src/NHibernate/Dialect/Dialect.cs
+++ b/src/NHibernate/Dialect/Dialect.cs
@@ -2100,7 +2100,7 @@ public virtual string ToStringLiteral(string value, SqlType type)
if (value == null)
throw new ArgumentNullException(nameof(value));
if (type == null)
- throw new ArgumentNullException(nameof(value));
+ throw new ArgumentNullException(nameof(type));
var literal = new StringBuilder(value);
if (EscapeBackslashInStrings)
From 0dcbfca66de57cad2bf2a6ec88846ed63b23540e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericdelaporte@users.noreply.github.com>
Date: Mon, 13 May 2024 21:25:32 +0200
Subject: [PATCH 14/26] Fix a test failing due to new Unicode support
---
src/NHibernate.Test/SqlCommandTest/SqlInsertBuilderFixture.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/NHibernate.Test/SqlCommandTest/SqlInsertBuilderFixture.cs b/src/NHibernate.Test/SqlCommandTest/SqlInsertBuilderFixture.cs
index ec1d5c0cb4e..ce076e007bd 100644
--- a/src/NHibernate.Test/SqlCommandTest/SqlInsertBuilderFixture.cs
+++ b/src/NHibernate.Test/SqlCommandTest/SqlInsertBuilderFixture.cs
@@ -56,7 +56,7 @@ public void Commented()
insert.SetTableName("test_insert_builder");
#pragma warning disable CS0618 // Type or member is obsolete
- insert.AddColumn("stringColumn", "aSQLValue", (ILiteralType)NHibernateUtil.String);
+ insert.AddColumn("stringColumn", "aSQLValue", (ILiteralType)NHibernateUtil.AnsiString);
#pragma warning restore CS0618 // Type or member is obsolete
insert.SetComment("Test insert");
string expectedSql =
From 2da9e9e5fdb1419fd0631b32840ca0fd98ae3d21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericdelaporte@users.noreply.github.com>
Date: Sun, 26 May 2024 19:15:53 +0200
Subject: [PATCH 15/26] Fix the char type
---
src/NHibernate/Type/AbstractCharType.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/NHibernate/Type/AbstractCharType.cs b/src/NHibernate/Type/AbstractCharType.cs
index 5efb630c16c..d47e3c5b21c 100644
--- a/src/NHibernate/Type/AbstractCharType.cs
+++ b/src/NHibernate/Type/AbstractCharType.cs
@@ -51,9 +51,7 @@ public override void Set(DbCommand cmd, object value, int index, ISessionImpleme
}
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
- {
- return '\'' + value.ToString() + '\'';
- }
+ => dialect.ToStringLiteral(value.ToString(), SqlType);
// 6.0 TODO: rename "xml" parameter as "value": it is not a xml string. The fact it generally comes from a xml
// attribute value is irrelevant to the method behavior.
From 02bcc42d0c17b644f268db29e710aecd9e712b6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericdelaporte@users.noreply.github.com>
Date: Sun, 9 Jun 2024 18:03:06 +0200
Subject: [PATCH 16/26] Fix types handled as SQL strings
Not including EnumStringType which ObjectToSQLString is invalid.
---
src/NHibernate/Type/CharBooleanType.cs | 5 +----
src/NHibernate/Type/EnumCharType.cs | 4 +---
src/NHibernate/Type/UriType.cs | 4 +---
3 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/src/NHibernate/Type/CharBooleanType.cs b/src/NHibernate/Type/CharBooleanType.cs
index 9cde87c6697..c721640ef09 100644
--- a/src/NHibernate/Type/CharBooleanType.cs
+++ b/src/NHibernate/Type/CharBooleanType.cs
@@ -3,7 +3,6 @@
using System.Data.Common;
using NHibernate.Engine;
using NHibernate.SqlTypes;
-using NHibernate.Util;
namespace NHibernate.Type
{
@@ -57,9 +56,7 @@ private string ToCharacter(object value)
}
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
- {
- return "'" + ToCharacter(value) + "'";
- }
+ => dialect.ToStringLiteral(ToCharacter(value), SqlType);
// 6.0 TODO: rename "xml" parameter as "value": it is not a xml string. The fact it generally comes from a xml
// attribute value is irrelevant to the method behavior.
diff --git a/src/NHibernate/Type/EnumCharType.cs b/src/NHibernate/Type/EnumCharType.cs
index ece3684ff6f..d73490ff19e 100644
--- a/src/NHibernate/Type/EnumCharType.cs
+++ b/src/NHibernate/Type/EnumCharType.cs
@@ -171,8 +171,6 @@ public override object FromStringValue(string xml)
}
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
- {
- return '\'' + GetValue(value).ToString() + '\'';
- }
+ => dialect.ToStringLiteral(GetValue(value).ToString(), SqlType);
}
}
diff --git a/src/NHibernate/Type/UriType.cs b/src/NHibernate/Type/UriType.cs
index 68f319606d3..100c3704a35 100644
--- a/src/NHibernate/Type/UriType.cs
+++ b/src/NHibernate/Type/UriType.cs
@@ -84,9 +84,7 @@ public override object FromStringValue(string xml)
}
public string ObjectToSQLString(object value, Dialect.Dialect dialect)
- {
- return "'" + ((Uri)value).OriginalString + "'";
- }
+ => dialect.ToStringLiteral(((Uri) value).OriginalString, SqlType);
///
public override object Assemble(object cached, ISessionImplementor session, object owner)
From edc417726fbba276f9543c9b89dd643374ebf182 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericdelaporte@users.noreply.github.com>
Date: Mon, 10 Jun 2024 01:20:04 +0200
Subject: [PATCH 17/26] Add a minimal fix for numeric types
---
src/NHibernate/Type/ByteType.cs | 2 +-
src/NHibernate/Type/DecimalType.cs | 2 +-
src/NHibernate/Type/DoubleType.cs | 2 +-
src/NHibernate/Type/Int16Type.cs | 2 +-
src/NHibernate/Type/Int32Type.cs | 2 +-
src/NHibernate/Type/Int64Type.cs | 2 +-
src/NHibernate/Type/SByteType.cs | 2 +-
src/NHibernate/Type/SingleType.cs | 2 +-
src/NHibernate/Type/UInt16Type.cs | 2 +-
src/NHibernate/Type/UInt32Type.cs | 2 +-
src/NHibernate/Type/UInt64Type.cs | 2 +-
11 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/NHibernate/Type/ByteType.cs b/src/NHibernate/Type/ByteType.cs
index 7c90bd6738a..41e0d4107c0 100644
--- a/src/NHibernate/Type/ByteType.cs
+++ b/src/NHibernate/Type/ByteType.cs
@@ -54,7 +54,7 @@ public override string Name
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToByte(value).ToString();
}
// 6.0 TODO: rename "xml" parameter as "value": it is not a xml string. The fact it generally comes from a xml
diff --git a/src/NHibernate/Type/DecimalType.cs b/src/NHibernate/Type/DecimalType.cs
index 158fa028fc7..bc6250343b4 100644
--- a/src/NHibernate/Type/DecimalType.cs
+++ b/src/NHibernate/Type/DecimalType.cs
@@ -66,7 +66,7 @@ public override object FromStringValue(string xml)
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToDecimal(value).ToString();
}
// 6.0 TODO: rename "xml" parameter as "value": it is not a xml string. The fact it generally comes from a xml
diff --git a/src/NHibernate/Type/DoubleType.cs b/src/NHibernate/Type/DoubleType.cs
index 4a8cf3406a9..f5f224948cd 100644
--- a/src/NHibernate/Type/DoubleType.cs
+++ b/src/NHibernate/Type/DoubleType.cs
@@ -66,7 +66,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToDouble(value).ToString();
}
}
}
diff --git a/src/NHibernate/Type/Int16Type.cs b/src/NHibernate/Type/Int16Type.cs
index f517be93424..47b3d842715 100644
--- a/src/NHibernate/Type/Int16Type.cs
+++ b/src/NHibernate/Type/Int16Type.cs
@@ -114,7 +114,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToInt16(value).ToString();
}
}
}
diff --git a/src/NHibernate/Type/Int32Type.cs b/src/NHibernate/Type/Int32Type.cs
index 9602842ae3b..6c4bf801bad 100644
--- a/src/NHibernate/Type/Int32Type.cs
+++ b/src/NHibernate/Type/Int32Type.cs
@@ -114,7 +114,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToInt32(value).ToString();
}
}
}
diff --git a/src/NHibernate/Type/Int64Type.cs b/src/NHibernate/Type/Int64Type.cs
index 5bad9a7513b..505117e065a 100644
--- a/src/NHibernate/Type/Int64Type.cs
+++ b/src/NHibernate/Type/Int64Type.cs
@@ -114,7 +114,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToInt64(value).ToString();
}
}
}
diff --git a/src/NHibernate/Type/SByteType.cs b/src/NHibernate/Type/SByteType.cs
index 55021fb22a6..b422087111f 100644
--- a/src/NHibernate/Type/SByteType.cs
+++ b/src/NHibernate/Type/SByteType.cs
@@ -116,7 +116,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToSByte(value).ToString();
}
}
}
diff --git a/src/NHibernate/Type/SingleType.cs b/src/NHibernate/Type/SingleType.cs
index 70ca434e04d..704fb862084 100644
--- a/src/NHibernate/Type/SingleType.cs
+++ b/src/NHibernate/Type/SingleType.cs
@@ -91,7 +91,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToSingle(value).ToString();
}
}
}
diff --git a/src/NHibernate/Type/UInt16Type.cs b/src/NHibernate/Type/UInt16Type.cs
index 10e9d15cd9b..7d5c785c999 100644
--- a/src/NHibernate/Type/UInt16Type.cs
+++ b/src/NHibernate/Type/UInt16Type.cs
@@ -114,7 +114,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToUInt16(value).ToString();
}
}
}
diff --git a/src/NHibernate/Type/UInt32Type.cs b/src/NHibernate/Type/UInt32Type.cs
index 0590278ef68..caab51260e2 100644
--- a/src/NHibernate/Type/UInt32Type.cs
+++ b/src/NHibernate/Type/UInt32Type.cs
@@ -114,7 +114,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToUInt32(value).ToString();
}
}
}
diff --git a/src/NHibernate/Type/UInt64Type.cs b/src/NHibernate/Type/UInt64Type.cs
index a902b6d46fe..8626929eb0d 100644
--- a/src/NHibernate/Type/UInt64Type.cs
+++ b/src/NHibernate/Type/UInt64Type.cs
@@ -113,7 +113,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return value.ToString();
+ return Convert.ToUInt64(value).ToString();
}
}
}
From 77fe3e528ffbcf5508693674afca31e67d2c1153 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericdelaporte@users.noreply.github.com>
Date: Mon, 10 Jun 2024 22:20:54 +0200
Subject: [PATCH 18/26] Minimal fix for the datetime case
---
src/NHibernate/Type/AbstractDateTimeType.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/NHibernate/Type/AbstractDateTimeType.cs b/src/NHibernate/Type/AbstractDateTimeType.cs
index 8f95323cb78..07c32a7ba8a 100644
--- a/src/NHibernate/Type/AbstractDateTimeType.cs
+++ b/src/NHibernate/Type/AbstractDateTimeType.cs
@@ -176,7 +176,7 @@ public override object FromStringValue(string xml)
public override object DefaultValue => BaseDateValue;
///
- public override string ObjectToSQLString(object value, Dialect.Dialect dialect) =>
- "'" + (DateTime) value + "'";
+ public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
+ => dialect.ToStringLiteral(((DateTime) value).ToString(), SqlTypeFactory.GetAnsiString(50));
}
}
From aa91eb7cc7eed2a87e91b2028cdd2395ae400b8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericDelaporte@users.noreply.github.com>
Date: Tue, 11 Jun 2024 19:12:59 +0200
Subject: [PATCH 19/26] Disallow culture injection for numeric types
---
src/NHibernate/Type/ByteType.cs | 3 ++-
src/NHibernate/Type/DecimalType.cs | 3 ++-
src/NHibernate/Type/DoubleType.cs | 3 ++-
src/NHibernate/Type/Int16Type.cs | 7 ++++---
src/NHibernate/Type/Int32Type.cs | 7 ++++---
src/NHibernate/Type/Int64Type.cs | 3 ++-
src/NHibernate/Type/SByteType.cs | 3 ++-
src/NHibernate/Type/SingleType.cs | 3 ++-
src/NHibernate/Type/UInt16Type.cs | 3 ++-
src/NHibernate/Type/UInt32Type.cs | 3 ++-
src/NHibernate/Type/UInt64Type.cs | 3 ++-
11 files changed, 26 insertions(+), 15 deletions(-)
diff --git a/src/NHibernate/Type/ByteType.cs b/src/NHibernate/Type/ByteType.cs
index 41e0d4107c0..7973f81d80f 100644
--- a/src/NHibernate/Type/ByteType.cs
+++ b/src/NHibernate/Type/ByteType.cs
@@ -2,6 +2,7 @@
using System.Collections;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -54,7 +55,7 @@ public override string Name
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToByte(value).ToString();
+ return Convert.ToByte(value).ToString(CultureInfo.InvariantCulture);
}
// 6.0 TODO: rename "xml" parameter as "value": it is not a xml string. The fact it generally comes from a xml
diff --git a/src/NHibernate/Type/DecimalType.cs b/src/NHibernate/Type/DecimalType.cs
index bc6250343b4..07331637901 100644
--- a/src/NHibernate/Type/DecimalType.cs
+++ b/src/NHibernate/Type/DecimalType.cs
@@ -1,6 +1,7 @@
using System;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -66,7 +67,7 @@ public override object FromStringValue(string xml)
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToDecimal(value).ToString();
+ return Convert.ToDecimal(value).ToString(CultureInfo.InvariantCulture);
}
// 6.0 TODO: rename "xml" parameter as "value": it is not a xml string. The fact it generally comes from a xml
diff --git a/src/NHibernate/Type/DoubleType.cs b/src/NHibernate/Type/DoubleType.cs
index f5f224948cd..b3bf4cc5bc8 100644
--- a/src/NHibernate/Type/DoubleType.cs
+++ b/src/NHibernate/Type/DoubleType.cs
@@ -1,6 +1,7 @@
using System;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -66,7 +67,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToDouble(value).ToString();
+ return Convert.ToDouble(value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/Int16Type.cs b/src/NHibernate/Type/Int16Type.cs
index 47b3d842715..2c3d0521ef0 100644
--- a/src/NHibernate/Type/Int16Type.cs
+++ b/src/NHibernate/Type/Int16Type.cs
@@ -1,10 +1,11 @@
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
-using System.Collections.Generic;
-using System.Data;
namespace NHibernate.Type
{
@@ -114,7 +115,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToInt16(value).ToString();
+ return Convert.ToInt16(value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/Int32Type.cs b/src/NHibernate/Type/Int32Type.cs
index 6c4bf801bad..2343dd819bc 100644
--- a/src/NHibernate/Type/Int32Type.cs
+++ b/src/NHibernate/Type/Int32Type.cs
@@ -1,10 +1,11 @@
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
-using System.Collections.Generic;
-using System.Data;
namespace NHibernate.Type
{
@@ -114,7 +115,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToInt32(value).ToString();
+ return Convert.ToInt32(value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/Int64Type.cs b/src/NHibernate/Type/Int64Type.cs
index 505117e065a..e67c835f84a 100644
--- a/src/NHibernate/Type/Int64Type.cs
+++ b/src/NHibernate/Type/Int64Type.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -114,7 +115,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToInt64(value).ToString();
+ return Convert.ToInt64(value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/SByteType.cs b/src/NHibernate/Type/SByteType.cs
index b422087111f..6ccffbaeb83 100644
--- a/src/NHibernate/Type/SByteType.cs
+++ b/src/NHibernate/Type/SByteType.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -116,7 +117,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToSByte(value).ToString();
+ return Convert.ToSByte(value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/SingleType.cs b/src/NHibernate/Type/SingleType.cs
index 704fb862084..7d5d90ce441 100644
--- a/src/NHibernate/Type/SingleType.cs
+++ b/src/NHibernate/Type/SingleType.cs
@@ -1,6 +1,7 @@
using System;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -91,7 +92,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToSingle(value).ToString();
+ return Convert.ToSingle(value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/UInt16Type.cs b/src/NHibernate/Type/UInt16Type.cs
index 7d5c785c999..cf805da6598 100644
--- a/src/NHibernate/Type/UInt16Type.cs
+++ b/src/NHibernate/Type/UInt16Type.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -114,7 +115,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToUInt16(value).ToString();
+ return Convert.ToUInt16(value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/UInt32Type.cs b/src/NHibernate/Type/UInt32Type.cs
index caab51260e2..cd1a8dcc8eb 100644
--- a/src/NHibernate/Type/UInt32Type.cs
+++ b/src/NHibernate/Type/UInt32Type.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -114,7 +115,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToUInt32(value).ToString();
+ return Convert.ToUInt32(value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/UInt64Type.cs b/src/NHibernate/Type/UInt64Type.cs
index 8626929eb0d..74c2501d880 100644
--- a/src/NHibernate/Type/UInt64Type.cs
+++ b/src/NHibernate/Type/UInt64Type.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -113,7 +114,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToUInt64(value).ToString();
+ return Convert.ToUInt64(value).ToString(CultureInfo.InvariantCulture);
}
}
}
From 03936a2d6c460f028cfb41d8f49a314ecf5880d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericDelaporte@users.noreply.github.com>
Date: Tue, 11 Jun 2024 19:17:25 +0200
Subject: [PATCH 20/26] Disallow culture injecton in ticks dependent types
---
src/NHibernate/Type/TicksType.cs | 3 ++-
src/NHibernate/Type/TimeAsTimeSpanType.cs | 7 ++++---
src/NHibernate/Type/TimeSpanType.cs | 7 ++++---
3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/NHibernate/Type/TicksType.cs b/src/NHibernate/Type/TicksType.cs
index 4fc18a007cd..bc82d101df8 100644
--- a/src/NHibernate/Type/TicksType.cs
+++ b/src/NHibernate/Type/TicksType.cs
@@ -1,6 +1,7 @@
using System;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -100,7 +101,7 @@ public override object Seed(ISessionImplementor session)
///
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return '\'' + ((DateTime)value).Ticks.ToString() + '\'';
+ return '\'' + ((DateTime)value).Ticks.ToString(CultureInfo.InvariantCulture) + '\'';
}
}
}
diff --git a/src/NHibernate/Type/TimeAsTimeSpanType.cs b/src/NHibernate/Type/TimeAsTimeSpanType.cs
index e525ecfa555..fd7bd7058c7 100644
--- a/src/NHibernate/Type/TimeAsTimeSpanType.cs
+++ b/src/NHibernate/Type/TimeAsTimeSpanType.cs
@@ -1,10 +1,11 @@
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
-using System.Collections.Generic;
-using System.Data;
namespace NHibernate.Type
{
@@ -141,7 +142,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return '\'' + ((TimeSpan)value).Ticks.ToString() + '\'';
+ return '\'' + ((TimeSpan)value).Ticks.ToString(CultureInfo.InvariantCulture) + '\'';
}
}
}
diff --git a/src/NHibernate/Type/TimeSpanType.cs b/src/NHibernate/Type/TimeSpanType.cs
index 5ca576454b9..1ce300af06b 100644
--- a/src/NHibernate/Type/TimeSpanType.cs
+++ b/src/NHibernate/Type/TimeSpanType.cs
@@ -1,10 +1,11 @@
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
-using System.Collections.Generic;
-using System.Data;
namespace NHibernate.Type
{
@@ -128,7 +129,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return '\'' + ((TimeSpan)value).Ticks.ToString() + '\'';
+ return '\'' + ((TimeSpan)value).Ticks.ToString(CultureInfo.InvariantCulture) + '\'';
}
}
}
From b7c0576931dab45e13de4d17907f83d941ce9419 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Tue, 11 Jun 2024 17:20:09 +0000
Subject: [PATCH 21/26] Generate async files
---
src/NHibernate/Async/Type/ByteType.cs | 1 +
src/NHibernate/Async/Type/Int16Type.cs | 5 +++--
src/NHibernate/Async/Type/Int32Type.cs | 5 +++--
src/NHibernate/Async/Type/Int64Type.cs | 1 +
src/NHibernate/Async/Type/TicksType.cs | 1 +
src/NHibernate/Async/Type/TimeAsTimeSpanType.cs | 5 +++--
src/NHibernate/Async/Type/TimeSpanType.cs | 5 +++--
src/NHibernate/Async/Type/UInt16Type.cs | 1 +
src/NHibernate/Async/Type/UInt32Type.cs | 1 +
src/NHibernate/Async/Type/UInt64Type.cs | 1 +
10 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/src/NHibernate/Async/Type/ByteType.cs b/src/NHibernate/Async/Type/ByteType.cs
index c908d33432e..4ea953fa78d 100644
--- a/src/NHibernate/Async/Type/ByteType.cs
+++ b/src/NHibernate/Async/Type/ByteType.cs
@@ -12,6 +12,7 @@
using System.Collections;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
diff --git a/src/NHibernate/Async/Type/Int16Type.cs b/src/NHibernate/Async/Type/Int16Type.cs
index 95cec493791..0d88cbdd280 100644
--- a/src/NHibernate/Async/Type/Int16Type.cs
+++ b/src/NHibernate/Async/Type/Int16Type.cs
@@ -10,11 +10,12 @@
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
-using System.Collections.Generic;
-using System.Data;
namespace NHibernate.Type
{
diff --git a/src/NHibernate/Async/Type/Int32Type.cs b/src/NHibernate/Async/Type/Int32Type.cs
index e7897e1eafc..592c61d3b4c 100644
--- a/src/NHibernate/Async/Type/Int32Type.cs
+++ b/src/NHibernate/Async/Type/Int32Type.cs
@@ -10,11 +10,12 @@
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
-using System.Collections.Generic;
-using System.Data;
namespace NHibernate.Type
{
diff --git a/src/NHibernate/Async/Type/Int64Type.cs b/src/NHibernate/Async/Type/Int64Type.cs
index a4dae360662..566b0e6b214 100644
--- a/src/NHibernate/Async/Type/Int64Type.cs
+++ b/src/NHibernate/Async/Type/Int64Type.cs
@@ -13,6 +13,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
diff --git a/src/NHibernate/Async/Type/TicksType.cs b/src/NHibernate/Async/Type/TicksType.cs
index 0ffb06b37f6..b6e003cd753 100644
--- a/src/NHibernate/Async/Type/TicksType.cs
+++ b/src/NHibernate/Async/Type/TicksType.cs
@@ -11,6 +11,7 @@
using System;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
diff --git a/src/NHibernate/Async/Type/TimeAsTimeSpanType.cs b/src/NHibernate/Async/Type/TimeAsTimeSpanType.cs
index 185baa88eba..4ea5f86697d 100644
--- a/src/NHibernate/Async/Type/TimeAsTimeSpanType.cs
+++ b/src/NHibernate/Async/Type/TimeAsTimeSpanType.cs
@@ -10,11 +10,12 @@
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
-using System.Collections.Generic;
-using System.Data;
namespace NHibernate.Type
{
diff --git a/src/NHibernate/Async/Type/TimeSpanType.cs b/src/NHibernate/Async/Type/TimeSpanType.cs
index 0917413671c..9364c6599c6 100644
--- a/src/NHibernate/Async/Type/TimeSpanType.cs
+++ b/src/NHibernate/Async/Type/TimeSpanType.cs
@@ -10,11 +10,12 @@
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
-using System.Collections.Generic;
-using System.Data;
namespace NHibernate.Type
{
diff --git a/src/NHibernate/Async/Type/UInt16Type.cs b/src/NHibernate/Async/Type/UInt16Type.cs
index b30c8ee87a4..7384a0c8464 100644
--- a/src/NHibernate/Async/Type/UInt16Type.cs
+++ b/src/NHibernate/Async/Type/UInt16Type.cs
@@ -13,6 +13,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
diff --git a/src/NHibernate/Async/Type/UInt32Type.cs b/src/NHibernate/Async/Type/UInt32Type.cs
index b5aa62179c0..a1f3bf5838a 100644
--- a/src/NHibernate/Async/Type/UInt32Type.cs
+++ b/src/NHibernate/Async/Type/UInt32Type.cs
@@ -13,6 +13,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
diff --git a/src/NHibernate/Async/Type/UInt64Type.cs b/src/NHibernate/Async/Type/UInt64Type.cs
index 08e7c68a1e6..bee61c38a9c 100644
--- a/src/NHibernate/Async/Type/UInt64Type.cs
+++ b/src/NHibernate/Async/Type/UInt64Type.cs
@@ -13,6 +13,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
+using System.Globalization;
using NHibernate.Engine;
using NHibernate.SqlTypes;
From ea888be468cb3a2811c1c1275e944e7910225952 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericdelaporte@users.noreply.github.com>
Date: Wed, 12 Jun 2024 23:30:54 +0200
Subject: [PATCH 22/26] Switch to cast instead of convert
---
src/NHibernate/Type/ByteType.cs | 2 +-
src/NHibernate/Type/DecimalType.cs | 2 +-
src/NHibernate/Type/DoubleType.cs | 2 +-
src/NHibernate/Type/Int16Type.cs | 2 +-
src/NHibernate/Type/Int32Type.cs | 2 +-
src/NHibernate/Type/Int64Type.cs | 2 +-
src/NHibernate/Type/SByteType.cs | 2 +-
src/NHibernate/Type/SingleType.cs | 2 +-
src/NHibernate/Type/UInt16Type.cs | 2 +-
src/NHibernate/Type/UInt32Type.cs | 2 +-
src/NHibernate/Type/UInt64Type.cs | 2 +-
11 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/NHibernate/Type/ByteType.cs b/src/NHibernate/Type/ByteType.cs
index 7973f81d80f..c780427b2ae 100644
--- a/src/NHibernate/Type/ByteType.cs
+++ b/src/NHibernate/Type/ByteType.cs
@@ -55,7 +55,7 @@ public override string Name
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToByte(value).ToString(CultureInfo.InvariantCulture);
+ return ((byte)value).ToString(CultureInfo.InvariantCulture);
}
// 6.0 TODO: rename "xml" parameter as "value": it is not a xml string. The fact it generally comes from a xml
diff --git a/src/NHibernate/Type/DecimalType.cs b/src/NHibernate/Type/DecimalType.cs
index 07331637901..df6f0b60f4a 100644
--- a/src/NHibernate/Type/DecimalType.cs
+++ b/src/NHibernate/Type/DecimalType.cs
@@ -67,7 +67,7 @@ public override object FromStringValue(string xml)
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToDecimal(value).ToString(CultureInfo.InvariantCulture);
+ return ((decimal)value).ToString(CultureInfo.InvariantCulture);
}
// 6.0 TODO: rename "xml" parameter as "value": it is not a xml string. The fact it generally comes from a xml
diff --git a/src/NHibernate/Type/DoubleType.cs b/src/NHibernate/Type/DoubleType.cs
index b3bf4cc5bc8..b7df9359bb9 100644
--- a/src/NHibernate/Type/DoubleType.cs
+++ b/src/NHibernate/Type/DoubleType.cs
@@ -67,7 +67,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToDouble(value).ToString(CultureInfo.InvariantCulture);
+ return ((double)value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/Int16Type.cs b/src/NHibernate/Type/Int16Type.cs
index 2c3d0521ef0..af018c60ab0 100644
--- a/src/NHibernate/Type/Int16Type.cs
+++ b/src/NHibernate/Type/Int16Type.cs
@@ -115,7 +115,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToInt16(value).ToString(CultureInfo.InvariantCulture);
+ return ((short)value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/Int32Type.cs b/src/NHibernate/Type/Int32Type.cs
index 2343dd819bc..2ec84eecf19 100644
--- a/src/NHibernate/Type/Int32Type.cs
+++ b/src/NHibernate/Type/Int32Type.cs
@@ -115,7 +115,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToInt32(value).ToString(CultureInfo.InvariantCulture);
+ return ((int)value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/Int64Type.cs b/src/NHibernate/Type/Int64Type.cs
index e67c835f84a..64a6cf37a63 100644
--- a/src/NHibernate/Type/Int64Type.cs
+++ b/src/NHibernate/Type/Int64Type.cs
@@ -115,7 +115,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToInt64(value).ToString(CultureInfo.InvariantCulture);
+ return ((long)value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/SByteType.cs b/src/NHibernate/Type/SByteType.cs
index 6ccffbaeb83..f3cbefa7503 100644
--- a/src/NHibernate/Type/SByteType.cs
+++ b/src/NHibernate/Type/SByteType.cs
@@ -117,7 +117,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToSByte(value).ToString(CultureInfo.InvariantCulture);
+ return ((sbyte)value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/SingleType.cs b/src/NHibernate/Type/SingleType.cs
index 7d5d90ce441..4d299bb1c17 100644
--- a/src/NHibernate/Type/SingleType.cs
+++ b/src/NHibernate/Type/SingleType.cs
@@ -92,7 +92,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToSingle(value).ToString(CultureInfo.InvariantCulture);
+ return ((float)value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/UInt16Type.cs b/src/NHibernate/Type/UInt16Type.cs
index cf805da6598..90421392d8f 100644
--- a/src/NHibernate/Type/UInt16Type.cs
+++ b/src/NHibernate/Type/UInt16Type.cs
@@ -115,7 +115,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToUInt16(value).ToString(CultureInfo.InvariantCulture);
+ return ((ushort)value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/UInt32Type.cs b/src/NHibernate/Type/UInt32Type.cs
index cd1a8dcc8eb..897dca99a19 100644
--- a/src/NHibernate/Type/UInt32Type.cs
+++ b/src/NHibernate/Type/UInt32Type.cs
@@ -115,7 +115,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToUInt32(value).ToString(CultureInfo.InvariantCulture);
+ return ((uint)value).ToString(CultureInfo.InvariantCulture);
}
}
}
diff --git a/src/NHibernate/Type/UInt64Type.cs b/src/NHibernate/Type/UInt64Type.cs
index 74c2501d880..5665a1077d1 100644
--- a/src/NHibernate/Type/UInt64Type.cs
+++ b/src/NHibernate/Type/UInt64Type.cs
@@ -114,7 +114,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return Convert.ToUInt64(value).ToString(CultureInfo.InvariantCulture);
+ return ((ulong)value).ToString(CultureInfo.InvariantCulture);
}
}
}
From 27bc4bfcbcdf1afa5cb1b2794c741d4bdaa34f8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericdelaporte@users.noreply.github.com>
Date: Thu, 13 Jun 2024 00:20:57 +0200
Subject: [PATCH 23/26] Add injection test for other datetime types
---
.../NHSpecificTest/GH3516/FixtureByCode.cs | 47 ++++++++++++++-----
.../NHSpecificTest/GH3516/Entity.cs | 4 ++
.../NHSpecificTest/GH3516/FixtureByCode.cs | 47 ++++++++++++++-----
3 files changed, 74 insertions(+), 24 deletions(-)
diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH3516/FixtureByCode.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH3516/FixtureByCode.cs
index 8b909f9c37b..41138e979a8 100644
--- a/src/NHibernate.Test/Async/NHSpecificTest/GH3516/FixtureByCode.cs
+++ b/src/NHibernate.Test/Async/NHSpecificTest/GH3516/FixtureByCode.cs
@@ -17,6 +17,7 @@
using NHibernate.SqlTypes;
using NHibernate.Type;
using NUnit.Framework;
+using NUnit.Framework.Internal;
namespace NHibernate.Test.NHSpecificTest.GH3516
{
@@ -24,6 +25,9 @@ namespace NHibernate.Test.NHSpecificTest.GH3516
[TestFixture]
public class FixtureByCodeAsync : TestCaseMappingByCode
{
+
+ private readonly HashSet _unsupportedProperties = new();
+
protected override HbmMapping GetMappings()
{
var mapper = new ModelMapper();
@@ -46,24 +50,30 @@ protected override HbmMapping GetMappings()
if (TestDialect.SupportsSqlType(SqlTypeFactory.SByte))
rc.Property(x => x.SByteProperty);
else
- _unsupportedNumericalProperties.Add(nameof(Entity.SByteProperty));
+ _unsupportedProperties.Add(nameof(Entity.SByteProperty));
if (TestDialect.SupportsSqlType(SqlTypeFactory.UInt16))
rc.Property(x => x.UShortProperty);
else
- _unsupportedNumericalProperties.Add(nameof(Entity.UShortProperty));
+ _unsupportedProperties.Add(nameof(Entity.UShortProperty));
if (TestDialect.SupportsSqlType(SqlTypeFactory.UInt32))
rc.Property(x => x.UIntProperty);
else
- _unsupportedNumericalProperties.Add(nameof(Entity.UIntProperty));
+ _unsupportedProperties.Add(nameof(Entity.UIntProperty));
if (TestDialect.SupportsSqlType(SqlTypeFactory.UInt64))
rc.Property(x => x.ULongProperty);
else
- _unsupportedNumericalProperties.Add(nameof(Entity.ULongProperty));
+ _unsupportedProperties.Add(nameof(Entity.ULongProperty));
- rc.Property(x => x.DateProperty);
+ rc.Property(x => x.DateTimeProperty);
+ rc.Property(x => x.DateProperty, m => m.Type(NHibernateUtil.Date));
+ if (TestDialect.SupportsSqlType(SqlTypeFactory.DateTimeOffSet))
+ rc.Property(x => x.DateTimeOffsetProperty);
+ else
+ _unsupportedProperties.Add(nameof(Entity.DateTimeOffsetProperty));
+ rc.Property(x => x.TimeProperty, m => m.Type(NHibernateUtil.Time));
});
mapper.Class(rc =>
@@ -287,12 +297,10 @@ public void SqlInjectionWithUriAsync(string propertyName)
nameof(Entity.ULongProperty)
};
- private readonly HashSet _unsupportedNumericalProperties = new();
-
[TestCaseSource(nameof(NumericalTypesInjections))]
public async Task SqlInjectionInNumericalTypeAsync(string propertyName)
{
- Assume.That(_unsupportedNumericalProperties, Does.Not.Contains((object)propertyName), $"The {propertyName} property is unsupported by the dialect");
+ Assume.That(_unsupportedProperties, Does.Not.Contains((object)propertyName), $"The {propertyName} property is unsupported by the dialect");
Entity.ArbitraryStringValue = "0; drop table Entity; --";
using (var session = OpenSession())
@@ -332,17 +340,32 @@ public async Task SqlInjectionInNumericalTypeAsync(string propertyName)
}
}
- [Test]
- public void SqlInjectionWithDatetimeAsync()
+ private static readonly string[] DateTypesInjections =
{
+ nameof(Entity.DateTimeProperty),
+ nameof(Entity.DateProperty),
+ nameof(Entity.DateTimeOffsetProperty),
+ nameof(Entity.TimeProperty)
+ };
+
+ [TestCaseSource(nameof(DateTypesInjections))]
+ public void SqlInjectionWithDatetimeAsync(string propertyName)
+ {
+ Assume.That(_unsupportedProperties, Does.Not.Contains((object) propertyName), $"The {propertyName} property is unsupported by the dialect");
+
var wickedCulture = new CultureInfo("en-US");
- wickedCulture.DateTimeFormat.ShortDatePattern = "yyyy-MM-ddTHH:mm:ss\\'\"; drop table Entity; --\"";
+ if (propertyName == nameof(Entity.TimeProperty))
+ wickedCulture.DateTimeFormat.ShortTimePattern = "HH:mm:ss\\'\"; drop table Entity; --\"";
+ else
+ wickedCulture.DateTimeFormat.ShortDatePattern = "yyyy-MM-ddTHH:mm:ss\\'\"; drop table Entity; --\"";
CultureInfo.CurrentCulture = wickedCulture;
CultureInfo.CurrentUICulture = wickedCulture;
using var session = OpenSession();
- var query = session.CreateQuery($"from Entity e where e.DateProperty = Entity.StaticDateProperty");
+ var staticPropertyName = propertyName == nameof(Entity.DateTimeOffsetProperty) ?
+ nameof(Entity.StaticDateTimeOffsetProperty) : nameof(Entity.StaticDateProperty);
+ var query = session.CreateQuery($"from Entity e where e.{propertyName} = Entity.{staticPropertyName}");
IList list = null;
Assume.That(() => list = query.List(), Throws.Nothing,
"The first execution of the query failed, the injection has likely failed");
diff --git a/src/NHibernate.Test/NHSpecificTest/GH3516/Entity.cs b/src/NHibernate.Test/NHSpecificTest/GH3516/Entity.cs
index d2e24df2bb2..0d82b5c5eca 100644
--- a/src/NHibernate.Test/NHSpecificTest/GH3516/Entity.cs
+++ b/src/NHibernate.Test/NHSpecificTest/GH3516/Entity.cs
@@ -22,7 +22,10 @@ public class Entity
public virtual uint UIntProperty { get; set; }
public virtual ulong ULongProperty { get; set; }
+ public virtual DateTime DateTimeProperty { get; set; } = StaticDateProperty;
public virtual DateTime DateProperty { get; set; } = StaticDateProperty;
+ public virtual DateTimeOffset DateTimeOffsetProperty { get; set; } = StaticDateProperty;
+ public virtual DateTime TimeProperty { get; set; } = StaticDateProperty;
public const string NameWithSingleQuote = "'; drop table Entity; --";
public const string NameWithEscapedSingleQuote = @"\'; drop table Entity; --";
@@ -37,6 +40,7 @@ public class Entity
public static readonly Uri UriWithEscapedSingleQuote = new(@"https://somewhere/?sql=\'; drop table Entity; --");
public static readonly DateTime StaticDateProperty = DateTime.Today;
+ public static readonly DateTimeOffset StaticDateTimeOffsetProperty = DateTimeOffset.Now;
}
public enum CharEnum
diff --git a/src/NHibernate.Test/NHSpecificTest/GH3516/FixtureByCode.cs b/src/NHibernate.Test/NHSpecificTest/GH3516/FixtureByCode.cs
index ce5cf96c428..827ab79fe79 100644
--- a/src/NHibernate.Test/NHSpecificTest/GH3516/FixtureByCode.cs
+++ b/src/NHibernate.Test/NHSpecificTest/GH3516/FixtureByCode.cs
@@ -7,12 +7,16 @@
using NHibernate.SqlTypes;
using NHibernate.Type;
using NUnit.Framework;
+using NUnit.Framework.Internal;
namespace NHibernate.Test.NHSpecificTest.GH3516
{
[TestFixture]
public class FixtureByCode : TestCaseMappingByCode
{
+
+ private readonly HashSet _unsupportedProperties = new();
+
protected override HbmMapping GetMappings()
{
var mapper = new ModelMapper();
@@ -35,24 +39,30 @@ protected override HbmMapping GetMappings()
if (TestDialect.SupportsSqlType(SqlTypeFactory.SByte))
rc.Property(x => x.SByteProperty);
else
- _unsupportedNumericalProperties.Add(nameof(Entity.SByteProperty));
+ _unsupportedProperties.Add(nameof(Entity.SByteProperty));
if (TestDialect.SupportsSqlType(SqlTypeFactory.UInt16))
rc.Property(x => x.UShortProperty);
else
- _unsupportedNumericalProperties.Add(nameof(Entity.UShortProperty));
+ _unsupportedProperties.Add(nameof(Entity.UShortProperty));
if (TestDialect.SupportsSqlType(SqlTypeFactory.UInt32))
rc.Property(x => x.UIntProperty);
else
- _unsupportedNumericalProperties.Add(nameof(Entity.UIntProperty));
+ _unsupportedProperties.Add(nameof(Entity.UIntProperty));
if (TestDialect.SupportsSqlType(SqlTypeFactory.UInt64))
rc.Property(x => x.ULongProperty);
else
- _unsupportedNumericalProperties.Add(nameof(Entity.ULongProperty));
+ _unsupportedProperties.Add(nameof(Entity.ULongProperty));
- rc.Property(x => x.DateProperty);
+ rc.Property(x => x.DateTimeProperty);
+ rc.Property(x => x.DateProperty, m => m.Type(NHibernateUtil.Date));
+ if (TestDialect.SupportsSqlType(SqlTypeFactory.DateTimeOffSet))
+ rc.Property(x => x.DateTimeOffsetProperty);
+ else
+ _unsupportedProperties.Add(nameof(Entity.DateTimeOffsetProperty));
+ rc.Property(x => x.TimeProperty, m => m.Type(NHibernateUtil.Time));
});
mapper.Class(rc =>
@@ -276,12 +286,10 @@ public void SqlInjectionWithUri(string propertyName)
nameof(Entity.ULongProperty)
};
- private readonly HashSet _unsupportedNumericalProperties = new();
-
[TestCaseSource(nameof(NumericalTypesInjections))]
public void SqlInjectionInNumericalType(string propertyName)
{
- Assume.That(_unsupportedNumericalProperties, Does.Not.Contains((object)propertyName), $"The {propertyName} property is unsupported by the dialect");
+ Assume.That(_unsupportedProperties, Does.Not.Contains((object)propertyName), $"The {propertyName} property is unsupported by the dialect");
Entity.ArbitraryStringValue = "0; drop table Entity; --";
using (var session = OpenSession())
@@ -321,17 +329,32 @@ public void SqlInjectionInNumericalType(string propertyName)
}
}
- [Test]
- public void SqlInjectionWithDatetime()
+ private static readonly string[] DateTypesInjections =
{
+ nameof(Entity.DateTimeProperty),
+ nameof(Entity.DateProperty),
+ nameof(Entity.DateTimeOffsetProperty),
+ nameof(Entity.TimeProperty)
+ };
+
+ [TestCaseSource(nameof(DateTypesInjections))]
+ public void SqlInjectionWithDatetime(string propertyName)
+ {
+ Assume.That(_unsupportedProperties, Does.Not.Contains((object) propertyName), $"The {propertyName} property is unsupported by the dialect");
+
var wickedCulture = new CultureInfo("en-US");
- wickedCulture.DateTimeFormat.ShortDatePattern = "yyyy-MM-ddTHH:mm:ss\\'\"; drop table Entity; --\"";
+ if (propertyName == nameof(Entity.TimeProperty))
+ wickedCulture.DateTimeFormat.ShortTimePattern = "HH:mm:ss\\'\"; drop table Entity; --\"";
+ else
+ wickedCulture.DateTimeFormat.ShortDatePattern = "yyyy-MM-ddTHH:mm:ss\\'\"; drop table Entity; --\"";
CultureInfo.CurrentCulture = wickedCulture;
CultureInfo.CurrentUICulture = wickedCulture;
using var session = OpenSession();
- var query = session.CreateQuery($"from Entity e where e.DateProperty = Entity.StaticDateProperty");
+ var staticPropertyName = propertyName == nameof(Entity.DateTimeOffsetProperty) ?
+ nameof(Entity.StaticDateTimeOffsetProperty) : nameof(Entity.StaticDateProperty);
+ var query = session.CreateQuery($"from Entity e where e.{propertyName} = Entity.{staticPropertyName}");
IList list = null;
Assume.That(() => list = query.List(), Throws.Nothing,
"The first execution of the query failed, the injection has likely failed");
From 0c3506394cd7da6439e4b1edb2fe56560e68082a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericdelaporte@users.noreply.github.com>
Date: Thu, 13 Jun 2024 00:21:13 +0200
Subject: [PATCH 24/26] Fix other datetime types
---
src/NHibernate/Type/DateTimeOffSetType.cs | 4 +---
src/NHibernate/Type/DateType.cs | 4 ++--
src/NHibernate/Type/TimeType.cs | 4 +---
3 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/src/NHibernate/Type/DateTimeOffSetType.cs b/src/NHibernate/Type/DateTimeOffSetType.cs
index 37837aec289..78a9c80661b 100644
--- a/src/NHibernate/Type/DateTimeOffSetType.cs
+++ b/src/NHibernate/Type/DateTimeOffSetType.cs
@@ -155,8 +155,6 @@ public override object FromStringValue(string xml)
}
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
- {
- return "'" + ((DateTimeOffset) value) + "'";
- }
+ => dialect.ToStringLiteral(((DateTimeOffset) value).ToString(), SqlTypeFactory.GetAnsiString(50));
}
}
diff --git a/src/NHibernate/Type/DateType.cs b/src/NHibernate/Type/DateType.cs
index 76d3fbb99e9..1a3bac85c5c 100644
--- a/src/NHibernate/Type/DateType.cs
+++ b/src/NHibernate/Type/DateType.cs
@@ -93,8 +93,8 @@ public override string ToString(object val) =>
public override object DefaultValue => customBaseDate;
///
- public override string ObjectToSQLString(object value, Dialect.Dialect dialect) =>
- "\'" + ((DateTime)value).ToShortDateString() + "\'";
+ public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
+ => dialect.ToStringLiteral(((DateTime) value).ToShortDateString(), SqlTypeFactory.GetAnsiString(50));
// Since v5
[Obsolete("Its only parameter, BaseValue, is obsolete.")]
diff --git a/src/NHibernate/Type/TimeType.cs b/src/NHibernate/Type/TimeType.cs
index be487f81cff..b808619ae70 100644
--- a/src/NHibernate/Type/TimeType.cs
+++ b/src/NHibernate/Type/TimeType.cs
@@ -171,8 +171,6 @@ public override object DefaultValue
}
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
- {
- return "'" + ((DateTime)value).ToShortTimeString() + "'";
- }
+ => dialect.ToStringLiteral(((DateTime) value).ToShortTimeString(), SqlTypeFactory.GetAnsiString(50));
}
}
From e80b76631044f69352263148098683d536df0973 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericdelaporte@users.noreply.github.com>
Date: Thu, 13 Jun 2024 00:36:29 +0200
Subject: [PATCH 25/26] Add a Guid injection test
---
.../NHSpecificTest/GH3516/FixtureByCode.cs | 26 +++++++++++++++++--
.../NHSpecificTest/GH3516/Entity.cs | 2 ++
.../NHSpecificTest/GH3516/FixtureByCode.cs | 26 +++++++++++++++++--
3 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH3516/FixtureByCode.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH3516/FixtureByCode.cs
index 41138e979a8..f63dcb43745 100644
--- a/src/NHibernate.Test/Async/NHSpecificTest/GH3516/FixtureByCode.cs
+++ b/src/NHibernate.Test/Async/NHSpecificTest/GH3516/FixtureByCode.cs
@@ -74,6 +74,8 @@ protected override HbmMapping GetMappings()
else
_unsupportedProperties.Add(nameof(Entity.DateTimeOffsetProperty));
rc.Property(x => x.TimeProperty, m => m.Type(NHibernateUtil.Time));
+
+ rc.Property(x => x.GuidProperty);
});
mapper.Class(rc =>
@@ -100,7 +102,7 @@ protected override void OnSetUp()
using var transaction = session.BeginTransaction();
session.Save(
new Entity
- {
+ {
Name = Entity.NameWithSingleQuote,
FirstChar = Entity.QuoteInitial,
CharacterEnum = CharEnum.SingleQuote,
@@ -300,7 +302,7 @@ public void SqlInjectionWithUriAsync(string propertyName)
[TestCaseSource(nameof(NumericalTypesInjections))]
public async Task SqlInjectionInNumericalTypeAsync(string propertyName)
{
- Assume.That(_unsupportedProperties, Does.Not.Contains((object)propertyName), $"The {propertyName} property is unsupported by the dialect");
+ Assume.That(_unsupportedProperties, Does.Not.Contains((object) propertyName), $"The {propertyName} property is unsupported by the dialect");
Entity.ArbitraryStringValue = "0; drop table Entity; --";
using (var session = OpenSession())
@@ -373,5 +375,25 @@ public void SqlInjectionWithDatetimeAsync(string propertyName)
Assert.That(async () => list = await (query.ListAsync()), Throws.Nothing,
"The second execution of the query failed although the first one did not: the injection has succeeded");
}
+
+ private static readonly string[] GuidInjections =
+ {
+ Entity.NameWithSingleQuote, Entity.NameWithEscapedSingleQuote
+ };
+
+ [TestCaseSource(nameof(GuidInjections))]
+ public void SqlInjectionWithGuidAsync(string injection)
+ {
+ Entity.ArbitraryStringValue = $"{Guid.NewGuid()}{injection}";
+ using var session = OpenSession();
+
+ var query = session.CreateQuery($"from Entity e where e.GuidProperty = Entity.{nameof(Entity.ArbitraryStringValue)}");
+ IList list = null;
+ Assume.That(() => list = query.List(), Throws.Nothing,
+ "The first execution of the query failed, the injection has likely failed");
+ // Execute again to check the table is still here.
+ Assert.That(async () => list = await (query.ListAsync()), Throws.Nothing,
+ "The second execution of the query failed although the first one did not: the injection has succeeded");
+ }
}
}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH3516/Entity.cs b/src/NHibernate.Test/NHSpecificTest/GH3516/Entity.cs
index 0d82b5c5eca..0326e557526 100644
--- a/src/NHibernate.Test/NHSpecificTest/GH3516/Entity.cs
+++ b/src/NHibernate.Test/NHSpecificTest/GH3516/Entity.cs
@@ -27,6 +27,8 @@ public class Entity
public virtual DateTimeOffset DateTimeOffsetProperty { get; set; } = StaticDateProperty;
public virtual DateTime TimeProperty { get; set; } = StaticDateProperty;
+ public virtual Guid GuidProperty { get; set; } = Guid.Empty;
+
public const string NameWithSingleQuote = "'; drop table Entity; --";
public const string NameWithEscapedSingleQuote = @"\'; drop table Entity; --";
diff --git a/src/NHibernate.Test/NHSpecificTest/GH3516/FixtureByCode.cs b/src/NHibernate.Test/NHSpecificTest/GH3516/FixtureByCode.cs
index 827ab79fe79..235fad90b75 100644
--- a/src/NHibernate.Test/NHSpecificTest/GH3516/FixtureByCode.cs
+++ b/src/NHibernate.Test/NHSpecificTest/GH3516/FixtureByCode.cs
@@ -63,6 +63,8 @@ protected override HbmMapping GetMappings()
else
_unsupportedProperties.Add(nameof(Entity.DateTimeOffsetProperty));
rc.Property(x => x.TimeProperty, m => m.Type(NHibernateUtil.Time));
+
+ rc.Property(x => x.GuidProperty);
});
mapper.Class(rc =>
@@ -89,7 +91,7 @@ protected override void OnSetUp()
using var transaction = session.BeginTransaction();
session.Save(
new Entity
- {
+ {
Name = Entity.NameWithSingleQuote,
FirstChar = Entity.QuoteInitial,
CharacterEnum = CharEnum.SingleQuote,
@@ -289,7 +291,7 @@ public void SqlInjectionWithUri(string propertyName)
[TestCaseSource(nameof(NumericalTypesInjections))]
public void SqlInjectionInNumericalType(string propertyName)
{
- Assume.That(_unsupportedProperties, Does.Not.Contains((object)propertyName), $"The {propertyName} property is unsupported by the dialect");
+ Assume.That(_unsupportedProperties, Does.Not.Contains((object) propertyName), $"The {propertyName} property is unsupported by the dialect");
Entity.ArbitraryStringValue = "0; drop table Entity; --";
using (var session = OpenSession())
@@ -362,5 +364,25 @@ public void SqlInjectionWithDatetime(string propertyName)
Assert.That(() => list = query.List(), Throws.Nothing,
"The second execution of the query failed although the first one did not: the injection has succeeded");
}
+
+ private static readonly string[] GuidInjections =
+ {
+ Entity.NameWithSingleQuote, Entity.NameWithEscapedSingleQuote
+ };
+
+ [TestCaseSource(nameof(GuidInjections))]
+ public void SqlInjectionWithGuid(string injection)
+ {
+ Entity.ArbitraryStringValue = $"{Guid.NewGuid()}{injection}";
+ using var session = OpenSession();
+
+ var query = session.CreateQuery($"from Entity e where e.GuidProperty = Entity.{nameof(Entity.ArbitraryStringValue)}");
+ IList list = null;
+ Assume.That(() => list = query.List(), Throws.Nothing,
+ "The first execution of the query failed, the injection has likely failed");
+ // Execute again to check the table is still here.
+ Assert.That(() => list = query.List(), Throws.Nothing,
+ "The second execution of the query failed although the first one did not: the injection has succeeded");
+ }
}
}
From a1cebb2bf6167113f74b1452978ced30a4c1d2e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?=
<12201973+fredericdelaporte@users.noreply.github.com>
Date: Thu, 13 Jun 2024 00:36:39 +0200
Subject: [PATCH 26/26] Fix the Guid type
---
src/NHibernate/Type/GuidType.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/NHibernate/Type/GuidType.cs b/src/NHibernate/Type/GuidType.cs
index a883f3a6b5a..70d26f1d950 100644
--- a/src/NHibernate/Type/GuidType.cs
+++ b/src/NHibernate/Type/GuidType.cs
@@ -88,7 +88,7 @@ public override object DefaultValue
public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
{
- return "'" + value + "'";
+ return dialect.ToStringLiteral(value.ToString(), SqlTypeFactory.GetAnsiString(50));
}
}
}