mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-11-24 08:33:16 +08:00
Compare commits
16 Commits
f74abdc07a
...
2170a4ac73
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2170a4ac73 | ||
|
|
446b6f208b | ||
|
|
0c3cf6ba70 | ||
|
|
ed13a80b37 | ||
|
|
40dfdf10d0 | ||
|
|
8f25a8a09b | ||
|
|
de43ba19bd | ||
|
|
3f727ff3de | ||
|
|
0895c84117 | ||
|
|
be56cc3a02 | ||
|
|
5c3705bc01 | ||
|
|
1f69332272 | ||
|
|
95d01ed845 | ||
|
|
570b4fd661 | ||
|
|
9f95bc9970 | ||
|
|
a97b241fe3 |
@@ -1,4 +1,4 @@
|
||||
using SqlSugar;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
|
||||
namespace OrmTest
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Demo;
|
||||
using Demo;
|
||||
using SqlSeverTest;
|
||||
using SqlSeverTest.UserTestCases;
|
||||
using SqlSeverTest.UserTestCases.UnitTest;
|
||||
@@ -150,6 +150,7 @@ namespace OrmTest
|
||||
UCustom01.Init();
|
||||
UCustom02.Init();
|
||||
UCustom03.Init();
|
||||
//UnitUtilConvert.Init(); pull unit test is error
|
||||
Bulk();
|
||||
Filter();
|
||||
Insert();
|
||||
@@ -163,6 +164,7 @@ namespace OrmTest
|
||||
Queryable();
|
||||
Queryable2();
|
||||
QueryableAsync();
|
||||
SecurityParameterHandling();
|
||||
//Thread();
|
||||
//Thread2();
|
||||
//Thread3();
|
||||
|
||||
@@ -0,0 +1,563 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OrmTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Security Parameter Handling Test Suite
|
||||
/// Tests SQL injection prevention, parameter escaping, and special character handling
|
||||
/// Ensures that SqlSugar properly sanitizes and parameterizes user input to prevent SQL injection attacks
|
||||
/// </summary>
|
||||
public partial class NewUnitTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Main entry point for security parameter handling tests
|
||||
/// Executes all 4 test functions covering 20+ attack vectors
|
||||
/// </summary>
|
||||
public static void SecurityParameterHandling()
|
||||
{
|
||||
Console.WriteLine("=== Starting Security Parameter Handling Tests ===");
|
||||
|
||||
// Test 1: Basic SQL injection attack vectors
|
||||
TestBasicSQLInjectionVectors();
|
||||
|
||||
// Test 2: Advanced SQL injection techniques
|
||||
TestAdvancedSQLInjectionTechniques();
|
||||
|
||||
// Test 3: Special character escaping and handling
|
||||
TestSpecialCharacterEscaping();
|
||||
|
||||
// Test 4: Parameter validation and edge cases
|
||||
TestParameterValidationEdgeCases();
|
||||
|
||||
Console.WriteLine("=== All Security Parameter Handling Tests Passed ===");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test Function 1: Basic SQL Injection Attack Vectors
|
||||
/// Tests common SQL injection patterns including:
|
||||
/// - Single quote injection
|
||||
/// - Comment-based injection
|
||||
/// - UNION-based injection
|
||||
/// - Boolean-based blind injection
|
||||
/// - Tautology-based injection
|
||||
/// </summary>
|
||||
private static void TestBasicSQLInjectionVectors()
|
||||
{
|
||||
Console.WriteLine("\n--- Test 1: Basic SQL Injection Vectors ---");
|
||||
var db = Db;
|
||||
|
||||
// Initialize test table
|
||||
db.CodeFirst.InitTables<SecurityTestEntity>();
|
||||
db.DbMaintenance.TruncateTable<SecurityTestEntity>();
|
||||
|
||||
// Insert test data
|
||||
var testData = new List<SecurityTestEntity>
|
||||
{
|
||||
new SecurityTestEntity { Id = 1, Username = "admin", Password = "password123", Email = "admin@test.com" },
|
||||
new SecurityTestEntity { Id = 2, Username = "user1", Password = "pass456", Email = "user1@test.com" },
|
||||
new SecurityTestEntity { Id = 3, Username = "user2", Password = "pass789", Email = "user2@test.com" }
|
||||
};
|
||||
db.Insertable(testData).ExecuteCommand();
|
||||
|
||||
// Attack Vector 1: Single quote injection attempt
|
||||
// Malicious input: ' OR '1'='1
|
||||
string maliciousUsername1 = "' OR '1'='1";
|
||||
var result1 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousUsername1)
|
||||
.ToList();
|
||||
if (result1.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Single quote injection not properly handled");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 1 Blocked: Single quote injection");
|
||||
|
||||
// Attack Vector 2: Comment-based injection
|
||||
// Malicious input: admin'--
|
||||
string maliciousUsername2 = "admin'--";
|
||||
var result2 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousUsername2)
|
||||
.ToList();
|
||||
if (result2.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Comment-based injection not properly handled");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 2 Blocked: Comment-based injection");
|
||||
|
||||
// Attack Vector 3: UNION-based injection
|
||||
// Malicious input: ' UNION SELECT NULL, NULL, NULL--
|
||||
string maliciousUsername3 = "' UNION SELECT NULL, NULL, NULL--";
|
||||
var result3 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousUsername3)
|
||||
.ToList();
|
||||
if (result3.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: UNION-based injection not properly handled");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 3 Blocked: UNION-based injection");
|
||||
|
||||
// Attack Vector 4: Boolean-based blind injection
|
||||
// Malicious input: ' OR 1=1--
|
||||
string maliciousUsername4 = "' OR 1=1--";
|
||||
var result4 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousUsername4)
|
||||
.ToList();
|
||||
if (result4.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Boolean-based injection not properly handled");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 4 Blocked: Boolean-based blind injection");
|
||||
|
||||
// Attack Vector 5: Tautology-based injection
|
||||
// Malicious input: admin' OR 'a'='a
|
||||
string maliciousUsername5 = "admin' OR 'a'='a";
|
||||
var result5 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousUsername5)
|
||||
.ToList();
|
||||
if (result5.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Tautology-based injection not properly handled");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 5 Blocked: Tautology-based injection");
|
||||
|
||||
// Attack Vector 6: Stacked queries injection
|
||||
// Malicious input: '; DROP TABLE SecurityTestEntity--
|
||||
string maliciousUsername6 = "'; DROP TABLE SecurityTestEntity--";
|
||||
var result6 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousUsername6)
|
||||
.ToList();
|
||||
if (result6.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Stacked queries injection not properly handled");
|
||||
}
|
||||
// Verify table still exists
|
||||
var tableExists = db.DbMaintenance.IsAnyTable("SecurityTestEntity", false);
|
||||
if (!tableExists)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Table was dropped by injection attack");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 6 Blocked: Stacked queries injection");
|
||||
|
||||
db.DbMaintenance.TruncateTable<SecurityTestEntity>();
|
||||
Console.WriteLine("Test 1 Completed Successfully\n");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test Function 2: Advanced SQL Injection Techniques
|
||||
/// Tests sophisticated attack patterns including:
|
||||
/// - Time-based blind injection
|
||||
/// - Error-based injection
|
||||
/// - Second-order injection
|
||||
/// - Encoded injection attempts
|
||||
/// - Hex encoding attacks
|
||||
/// </summary>
|
||||
private static void TestAdvancedSQLInjectionTechniques()
|
||||
{
|
||||
Console.WriteLine("\n--- Test 2: Advanced SQL Injection Techniques ---");
|
||||
var db = Db;
|
||||
|
||||
db.CodeFirst.InitTables<SecurityTestEntity>();
|
||||
db.DbMaintenance.TruncateTable<SecurityTestEntity>();
|
||||
|
||||
var testData = new List<SecurityTestEntity>
|
||||
{
|
||||
new SecurityTestEntity { Id = 1, Username = "testuser", Password = "testpass", Email = "test@example.com" }
|
||||
};
|
||||
db.Insertable(testData).ExecuteCommand();
|
||||
|
||||
// Attack Vector 7: Time-based blind injection
|
||||
// Malicious input: '; WAITFOR DELAY '00:00:05'--
|
||||
string maliciousInput7 = "'; WAITFOR DELAY '00:00:05'--";
|
||||
var startTime = DateTime.Now;
|
||||
var result7 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousInput7)
|
||||
.ToList();
|
||||
var elapsed = (DateTime.Now - startTime).TotalSeconds;
|
||||
if (elapsed > 3 || result7.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Time-based injection not properly handled");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 7 Blocked: Time-based blind injection");
|
||||
|
||||
// Attack Vector 8: Error-based injection
|
||||
// Malicious input: ' AND 1=CONVERT(int, (SELECT @@version))--
|
||||
string maliciousInput8 = "' AND 1=CONVERT(int, (SELECT @@version))--";
|
||||
var result8 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousInput8)
|
||||
.ToList();
|
||||
if (result8.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Error-based injection not properly handled");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 8 Blocked: Error-based injection");
|
||||
|
||||
// Attack Vector 9: Second-order injection (stored malicious data)
|
||||
// Insert malicious data and then query it
|
||||
string maliciousData9 = "'; DELETE FROM SecurityTestEntity--";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 2,
|
||||
Username = maliciousData9,
|
||||
Password = "pass",
|
||||
Email = "mal@test.com"
|
||||
}).ExecuteCommand();
|
||||
|
||||
var storedData = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousData9)
|
||||
.First();
|
||||
if (storedData == null || storedData.Username != maliciousData9)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Second-order injection data not stored correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 9 Blocked: Second-order injection");
|
||||
|
||||
// Attack Vector 10: URL encoded injection
|
||||
// Malicious input: %27%20OR%20%271%27%3D%271 (decoded: ' OR '1'='1)
|
||||
string maliciousInput10 = "%27%20OR%20%271%27%3D%271";
|
||||
var result10 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousInput10)
|
||||
.ToList();
|
||||
if (result10.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: URL encoded injection not properly handled");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 10 Blocked: URL encoded injection");
|
||||
|
||||
// Attack Vector 11: Hex encoding attack
|
||||
// Malicious input: 0x27204F52202731273D2731 (hex for ' OR '1'='1)
|
||||
string maliciousInput11 = "0x27204F52202731273D2731";
|
||||
var result11 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousInput11)
|
||||
.ToList();
|
||||
if (result11.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Hex encoding attack not properly handled");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 11 Blocked: Hex encoding attack");
|
||||
|
||||
// Attack Vector 12: Batch query injection
|
||||
// Malicious input: '; SELECT * FROM SecurityTestEntity; --
|
||||
string maliciousInput12 = "'; SELECT * FROM SecurityTestEntity; --";
|
||||
var result12 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == maliciousInput12)
|
||||
.ToList();
|
||||
if (result12.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Batch query injection not properly handled");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 12 Blocked: Batch query injection");
|
||||
|
||||
db.DbMaintenance.TruncateTable<SecurityTestEntity>();
|
||||
Console.WriteLine("Test 2 Completed Successfully\n");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test Function 3: Special Character Escaping and Handling
|
||||
/// Tests proper handling of special characters including:
|
||||
/// - Quotes (single and double)
|
||||
/// - Backslashes
|
||||
/// - Null bytes
|
||||
/// - Unicode characters
|
||||
/// - Control characters
|
||||
/// - Wildcards
|
||||
/// </summary>
|
||||
private static void TestSpecialCharacterEscaping()
|
||||
{
|
||||
Console.WriteLine("\n--- Test 3: Special Character Escaping ---");
|
||||
var db = Db;
|
||||
|
||||
db.CodeFirst.InitTables<SecurityTestEntity>();
|
||||
db.DbMaintenance.TruncateTable<SecurityTestEntity>();
|
||||
|
||||
// Attack Vector 13: Multiple single quotes
|
||||
string specialChar13 = "test''user''name";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 1,
|
||||
Username = specialChar13,
|
||||
Password = "pass",
|
||||
Email = "test@test.com"
|
||||
}).ExecuteCommand();
|
||||
var result13 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == specialChar13)
|
||||
.First();
|
||||
if (result13 == null || result13.Username != specialChar13)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Multiple single quotes not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 13 Handled: Multiple single quotes");
|
||||
|
||||
// Attack Vector 14: Backslashes
|
||||
string specialChar14 = "test\\user\\name";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 2,
|
||||
Username = specialChar14,
|
||||
Password = "pass",
|
||||
Email = "test@test.com"
|
||||
}).ExecuteCommand();
|
||||
var result14 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == specialChar14)
|
||||
.First();
|
||||
if (result14 == null || result14.Username != specialChar14)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Backslashes not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 14 Handled: Backslashes");
|
||||
|
||||
// Attack Vector 15: Double quotes
|
||||
string specialChar15 = "test\"user\"name";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 3,
|
||||
Username = specialChar15,
|
||||
Password = "pass",
|
||||
Email = "test@test.com"
|
||||
}).ExecuteCommand();
|
||||
var result15 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == specialChar15)
|
||||
.First();
|
||||
if (result15 == null || result15.Username != specialChar15)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Double quotes not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 15 Handled: Double quotes");
|
||||
|
||||
// Attack Vector 16: Percent sign (LIKE wildcard)
|
||||
string specialChar16 = "test%user%name";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 4,
|
||||
Username = specialChar16,
|
||||
Password = "pass",
|
||||
Email = "test@test.com"
|
||||
}).ExecuteCommand();
|
||||
var result16 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == specialChar16)
|
||||
.First();
|
||||
if (result16 == null || result16.Username != specialChar16)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Percent signs not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 16 Handled: Percent signs (wildcards)");
|
||||
|
||||
// Attack Vector 17: Underscore (LIKE wildcard)
|
||||
string specialChar17 = "test_user_name";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 5,
|
||||
Username = specialChar17,
|
||||
Password = "pass",
|
||||
Email = "test@test.com"
|
||||
}).ExecuteCommand();
|
||||
var result17 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == specialChar17)
|
||||
.First();
|
||||
if (result17 == null || result17.Username != specialChar17)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Underscores not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 17 Handled: Underscores (wildcards)");
|
||||
|
||||
// Attack Vector 18: Unicode characters
|
||||
string specialChar18 = "测试用户名";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 6,
|
||||
Username = specialChar18,
|
||||
Password = "pass",
|
||||
Email = "test@test.com"
|
||||
}).ExecuteCommand();
|
||||
var result18 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == specialChar18)
|
||||
.First();
|
||||
if (result18 == null || result18.Username != specialChar18)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Unicode characters not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 18 Handled: Unicode characters");
|
||||
|
||||
// Attack Vector 19: Semicolons
|
||||
string specialChar19 = "test;user;name";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 7,
|
||||
Username = specialChar19,
|
||||
Password = "pass",
|
||||
Email = "test@test.com"
|
||||
}).ExecuteCommand();
|
||||
var result19 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == specialChar19)
|
||||
.First();
|
||||
if (result19 == null || result19.Username != specialChar19)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Semicolons not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 19 Handled: Semicolons");
|
||||
|
||||
db.DbMaintenance.TruncateTable<SecurityTestEntity>();
|
||||
Console.WriteLine("Test 3 Completed Successfully\n");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test Function 4: Parameter Validation and Edge Cases
|
||||
/// Tests edge cases and boundary conditions including:
|
||||
/// - Null values
|
||||
/// - Empty strings
|
||||
/// - Very long strings
|
||||
/// - Mixed attack vectors
|
||||
/// - Case sensitivity
|
||||
/// </summary>
|
||||
private static void TestParameterValidationEdgeCases()
|
||||
{
|
||||
Console.WriteLine("\n--- Test 4: Parameter Validation Edge Cases ---");
|
||||
var db = Db;
|
||||
|
||||
db.CodeFirst.InitTables<SecurityTestEntity>();
|
||||
db.DbMaintenance.TruncateTable<SecurityTestEntity>();
|
||||
|
||||
// Attack Vector 20: Empty string
|
||||
string emptyString = "";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 1,
|
||||
Username = emptyString,
|
||||
Password = "pass",
|
||||
Email = "test@test.com"
|
||||
}).ExecuteCommand();
|
||||
var result20 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == emptyString)
|
||||
.First();
|
||||
if (result20 == null || result20.Username != emptyString)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Empty string not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 20 Handled: Empty string");
|
||||
|
||||
// Attack Vector 21: Very long string with injection attempt
|
||||
string longString = new string('a', 1000) + "' OR '1'='1";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 2,
|
||||
Username = longString,
|
||||
Password = "pass",
|
||||
Email = "test@test.com"
|
||||
}).ExecuteCommand();
|
||||
var result21 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == longString)
|
||||
.First();
|
||||
if (result21 == null || result21.Username != longString)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Very long string not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 21 Handled: Very long string with injection");
|
||||
|
||||
// Attack Vector 22: Mixed case SQL keywords
|
||||
string mixedCase = "' Or '1'='1";
|
||||
var result22 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == mixedCase)
|
||||
.ToList();
|
||||
if (result22.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Mixed case SQL keywords not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 22 Blocked: Mixed case SQL keywords");
|
||||
|
||||
// Attack Vector 23: Multiple attack vectors combined
|
||||
string combined = "'; DROP TABLE SecurityTestEntity; SELECT * FROM SecurityTestEntity WHERE '1'='1";
|
||||
var result23 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == combined)
|
||||
.ToList();
|
||||
if (result23.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Combined attack vectors not handled correctly");
|
||||
}
|
||||
var tableStillExists = db.DbMaintenance.IsAnyTable("SecurityTestEntity", false);
|
||||
if (!tableStillExists)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Table was affected by combined attack");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 23 Blocked: Multiple combined attack vectors");
|
||||
|
||||
// Attack Vector 24: Whitespace variations
|
||||
string whitespace = " ' OR '1'='1 ";
|
||||
var result24 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == whitespace)
|
||||
.ToList();
|
||||
if (result24.Count != 0)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Whitespace variations not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 24 Blocked: Whitespace variations");
|
||||
|
||||
// Attack Vector 25: Line breaks and tabs
|
||||
string lineBreaks = "test\r\n\t' OR '1'='1";
|
||||
db.Insertable(new SecurityTestEntity
|
||||
{
|
||||
Id = 3,
|
||||
Username = lineBreaks,
|
||||
Password = "pass",
|
||||
Email = "test@test.com"
|
||||
}).ExecuteCommand();
|
||||
var result25 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username == lineBreaks)
|
||||
.First();
|
||||
if (result25 == null || result25.Username != lineBreaks)
|
||||
{
|
||||
throw new Exception("Security Test Failed: Line breaks and tabs not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 25 Handled: Line breaks and tabs");
|
||||
|
||||
// Attack Vector 26: Parameter with LIKE pattern injection
|
||||
string likePattern = "%' OR '1'='1' OR username LIKE '%";
|
||||
var result26 = db.Queryable<SecurityTestEntity>()
|
||||
.Where(x => x.Username.Contains(likePattern))
|
||||
.ToList();
|
||||
// Should not return all records
|
||||
if (result26.Count > 1)
|
||||
{
|
||||
throw new Exception("Security Test Failed: LIKE pattern injection not handled correctly");
|
||||
}
|
||||
Console.WriteLine("✓ Attack Vector 26 Blocked: LIKE pattern injection");
|
||||
|
||||
db.DbMaintenance.TruncateTable<SecurityTestEntity>();
|
||||
Console.WriteLine("Test 4 Completed Successfully\n");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test entity class for security testing
|
||||
/// Represents a typical user table with common fields that are often targeted in SQL injection attacks
|
||||
/// </summary>
|
||||
[SugarTable("SecurityTestEntity")]
|
||||
public class SecurityTestEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Primary key identifier
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Username field - commonly targeted for SQL injection
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 2000)]
|
||||
public string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Password field - sensitive data that must be protected
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 200)]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Email field - another common injection target
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 200)]
|
||||
public string Email { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
//using SqlSugar;
|
||||
//using SqlSugar.Extensions;
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
|
||||
//namespace OrmTest
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// UtilConvert utility class tests
|
||||
// /// UtilConvert 实用工具类测试
|
||||
// /// </summary>
|
||||
// public class UnitUtilConvert
|
||||
// {
|
||||
// public static void Init()
|
||||
// {
|
||||
// Console.WriteLine("=== UtilConvert Tests / UtilConvert 测试 ===");
|
||||
|
||||
// // Test ObjToInt / 测试 ObjToInt
|
||||
// TestObjToInt();
|
||||
|
||||
// // Test ObjToLong / 测试 ObjToLong
|
||||
// //TestObjToLong();
|
||||
|
||||
// // Test ObjToString / 测试 ObjToString
|
||||
// TestObjToString();
|
||||
|
||||
// // Test ObjToDecimal / 测试 ObjToDecimal
|
||||
// TestObjToDecimal();
|
||||
|
||||
// // Test ObjToMoney / 测试 ObjToMoney
|
||||
// TestObjToMoney();
|
||||
|
||||
// // Test ObjToDate / 测试 ObjToDate
|
||||
// TestObjToDate();
|
||||
|
||||
// // Test ObjToBool / 测试 ObjToBool
|
||||
// TestObjToBool();
|
||||
|
||||
// // Test EqualCase / 测试 EqualCase
|
||||
// //TestEqualCase();
|
||||
|
||||
// // Test Edge Cases / 测试边界情况
|
||||
// TestEdgeCases();
|
||||
|
||||
// Console.WriteLine("=== All UtilConvert Tests Passed! / 所有 UtilConvert 测试通过! ===");
|
||||
// }
|
||||
|
||||
// #region ObjToInt Tests / ObjToInt 测试
|
||||
|
||||
// private static void TestObjToInt()
|
||||
// {
|
||||
// // Test 1: Valid integer / 有效整数
|
||||
// object value1 = 123;
|
||||
// Check.Exception(value1.ObjToInt() == 123, "ObjToInt with valid integer");
|
||||
|
||||
// // Test 2: Valid string / 有效字符串
|
||||
// object value2 = "456";
|
||||
// Check.Exception(value2.ObjToInt() == 456, "ObjToInt with valid string");
|
||||
|
||||
// // Test 3: Null value / 空值
|
||||
// object value3 = null;
|
||||
// Check.Exception(value3.ObjToInt() == 0, "ObjToInt with null");
|
||||
|
||||
// // Test 4: DBNull value / DBNull 值
|
||||
// object value4 = DBNull.Value;
|
||||
// Check.Exception(value4.ObjToInt() == 0, "ObjToInt with DBNull");
|
||||
|
||||
// // Test 5: Invalid string / 无效字符串
|
||||
// object value5 = "invalid";
|
||||
// Check.Exception(value5.ObjToInt() == 0, "ObjToInt with invalid string");
|
||||
|
||||
// // Test 6: Enum value / 枚举值
|
||||
// object value6 = DayOfWeek.Monday;
|
||||
// Check.Exception(value6.ObjToInt() == 1, "ObjToInt with enum");
|
||||
|
||||
// // Test 7: With error value - valid / 带错误值 - 有效
|
||||
// object value7 = 789;
|
||||
// Check.Exception(value7.ObjToInt(-1) == 789, "ObjToInt with error value (valid)");
|
||||
|
||||
// // Test 8: With error value - invalid / 带错误值 - 无效
|
||||
// object value8 = "invalid";
|
||||
// Check.Exception(value8.ObjToInt(-1) == -1, "ObjToInt with error value (invalid)");
|
||||
|
||||
// // Test 9: Max value / 最大值
|
||||
// object value9 = int.MaxValue.ToString();
|
||||
// Check.Exception(value9.ObjToInt() == int.MaxValue, "ObjToInt with max value");
|
||||
|
||||
// // Test 10: Min value / 最小值
|
||||
// object value10 = int.MinValue.ToString();
|
||||
// Check.Exception(value10.ObjToInt() == int.MinValue, "ObjToInt with min value");
|
||||
// }
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region ObjToLong Tests / ObjToLong 测试
|
||||
|
||||
// //private static void TestObjToLong()
|
||||
// //{
|
||||
// // // Test 1: Valid long / 有效长整数
|
||||
// // object value1 = 9876543210L;
|
||||
// // Check.Exception(value1.ObjToLong() == 9876543210L, "ObjToLong with valid long");
|
||||
|
||||
// // // Test 2: Valid string / 有效字符串
|
||||
// // object value2 = "1234567890";
|
||||
// // Check.Exception(value2.ObjToLong() == 1234567890L, "ObjToLong with valid string");
|
||||
|
||||
// // // Test 3: Null value / 空值
|
||||
// // object value3 = null;
|
||||
// // Check.Exception(value3.ObjToLong() == 0L, "ObjToLong with null");
|
||||
|
||||
// // // Test 4: Enum value / 枚举值
|
||||
// // object value4 = DayOfWeek.Friday;
|
||||
// // Check.Exception(value4.ObjToLong() == 5L, "ObjToLong with enum");
|
||||
|
||||
// // // Test 5: Max value / 最大值
|
||||
// // object value5 = long.MaxValue.ToString();
|
||||
// // Check.Exception(value5.ObjToLong() == long.MaxValue, "ObjToLong with max value");
|
||||
// //}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region ObjToString Tests / ObjToString 测试
|
||||
|
||||
// private static void TestObjToString()
|
||||
// {
|
||||
// // Test 1: Valid string with whitespace / 带空格的有效字符串
|
||||
// object value1 = " Hello World ";
|
||||
// Check.Exception(value1.ObjToString() == "Hello World", "ObjToString with whitespace");
|
||||
|
||||
// // Test 2: Null value / 空值
|
||||
// object value2 = null;
|
||||
// Check.Exception(value2.ObjToString() == string.Empty, "ObjToString with null");
|
||||
|
||||
// // Test 3: Integer / 整数
|
||||
// object value3 = 12345;
|
||||
// Check.Exception(value3.ObjToString() == "12345", "ObjToString with integer");
|
||||
|
||||
// // Test 4: With error value - valid / 带错误值 - 有效
|
||||
// object value4 = "test";
|
||||
// Check.Exception(value4.ObjToString("default") == "test", "ObjToString with error value (valid)");
|
||||
|
||||
// // Test 5: With error value - null / 带错误值 - 空值
|
||||
// object value5 = null;
|
||||
// Check.Exception(value5.ObjToString("default") == "default", "ObjToString with error value (null)");
|
||||
|
||||
// // Test 6: No trim / 不修剪
|
||||
// //object value6 = " Hello ";
|
||||
// //Check.Exception(value6.ObjToStringNoTrim() == " Hello ", "ObjToStringNoTrim preserves whitespace");
|
||||
|
||||
// // Test 7: Empty string / 空字符串
|
||||
// object value7 = string.Empty;
|
||||
// Check.Exception(value7.ObjToString() == string.Empty, "ObjToString with empty string");
|
||||
// }
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region ObjToDecimal Tests / ObjToDecimal 测试
|
||||
|
||||
// private static void TestObjToDecimal()
|
||||
// {
|
||||
// // Test 1: Valid decimal / 有效小数
|
||||
// object value1 = 123.45m;
|
||||
// Check.Exception(value1.ObjToDecimal() == 123.45m, "ObjToDecimal with valid decimal");
|
||||
|
||||
// // Test 2: Valid string / 有效字符串
|
||||
// object value2 = "678.90";
|
||||
// Check.Exception(value2.ObjToDecimal() == 678.90m, "ObjToDecimal with valid string");
|
||||
|
||||
// // Test 3: Null value / 空值
|
||||
// object value3 = null;
|
||||
// Check.Exception(value3.ObjToDecimal() == 0m, "ObjToDecimal with null");
|
||||
|
||||
// // Test 4: DBNull value / DBNull 值
|
||||
// object value4 = DBNull.Value;
|
||||
// Check.Exception(value4.ObjToDecimal() == 0m, "ObjToDecimal with DBNull");
|
||||
|
||||
// // Test 5: With error value / 带错误值
|
||||
// object value5 = "invalid";
|
||||
// Check.Exception(value5.ObjToDecimal(-1.5m) == -1.5m, "ObjToDecimal with error value");
|
||||
|
||||
// // Test 6: Max value / 最大值
|
||||
// object value6 = decimal.MaxValue;
|
||||
// Check.Exception(value6.ObjToDecimal() == decimal.MaxValue, "ObjToDecimal with max value");
|
||||
|
||||
// // Test 7: Negative value / 负值
|
||||
// object value7 = -123.45m;
|
||||
// Check.Exception(value7.ObjToDecimal() == -123.45m, "ObjToDecimal with negative value");
|
||||
// }
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region ObjToMoney Tests / ObjToMoney 测试
|
||||
|
||||
// private static void TestObjToMoney()
|
||||
// {
|
||||
// // Test 1: Valid double / 有效双精度
|
||||
// object value1 = 999.99;
|
||||
// Check.Exception(value1.ObjToMoney() == 999.99, "ObjToMoney with valid double");
|
||||
|
||||
// // Test 2: Valid string / 有效字符串
|
||||
// object value2 = "1234.56";
|
||||
// Check.Exception(value2.ObjToMoney() == 1234.56, "ObjToMoney with valid string");
|
||||
|
||||
// // Test 3: Null value / 空值
|
||||
// object value3 = null;
|
||||
// Check.Exception(value3.ObjToMoney() == 0.0, "ObjToMoney with null");
|
||||
|
||||
// // Test 4: With error value / 带错误值
|
||||
// object value4 = "invalid";
|
||||
// Check.Exception(value4.ObjToMoney(-100.0) == -100.0, "ObjToMoney with error value");
|
||||
|
||||
// // Test 5: Zero value / 零值
|
||||
// object value5 = 0.0;
|
||||
// Check.Exception(value5.ObjToMoney() == 0.0, "ObjToMoney with zero");
|
||||
// }
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region ObjToDate Tests / ObjToDate 测试
|
||||
|
||||
// private static void TestObjToDate()
|
||||
// {
|
||||
// // Test 1: Valid DateTime / 有效日期时间
|
||||
// var expectedDate = new DateTime(2024, 1, 15);
|
||||
// object value1 = expectedDate;
|
||||
// Check.Exception(value1.ObjToDate() == expectedDate, "ObjToDate with valid DateTime");
|
||||
|
||||
// // Test 2: Valid string / 有效字符串
|
||||
// object value2 = "2024-06-30";
|
||||
// Check.Exception(value2.ObjToDate() == new DateTime(2024, 6, 30), "ObjToDate with valid string");
|
||||
|
||||
// // Test 3: Null value / 空值
|
||||
// object value3 = null;
|
||||
// Check.Exception(value3.ObjToDate() == DateTime.MinValue, "ObjToDate with null");
|
||||
|
||||
// // Test 4: DBNull value / DBNull 值
|
||||
// object value4 = DBNull.Value;
|
||||
// Check.Exception(value4.ObjToDate() == DateTime.MinValue, "ObjToDate with DBNull");
|
||||
|
||||
// // Test 5: With error value / 带错误值
|
||||
// object value5 = "invalid";
|
||||
// var errorDate = new DateTime(2000, 1, 1);
|
||||
// Check.Exception(value5.ObjToDate(errorDate) == errorDate, "ObjToDate with error value");
|
||||
// }
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region ObjToBool Tests / ObjToBool 测试
|
||||
|
||||
// private static void TestObjToBool()
|
||||
// {
|
||||
// // Test 1: True string / True 字符串
|
||||
// object value1 = "true";
|
||||
// Check.Exception(value1.ObjToBool() == true, "ObjToBool with 'true' string");
|
||||
|
||||
// // Test 2: False string / False 字符串
|
||||
// object value2 = "false";
|
||||
// Check.Exception(value2.ObjToBool() == false, "ObjToBool with 'false' string");
|
||||
|
||||
// // Test 3: True boolean / True 布尔值
|
||||
// object value3 = true;
|
||||
// Check.Exception(value3.ObjToBool() == true, "ObjToBool with true boolean");
|
||||
|
||||
// // Test 4: False boolean / False 布尔值
|
||||
// object value4 = false;
|
||||
// Check.Exception(value4.ObjToBool() == false, "ObjToBool with false boolean");
|
||||
|
||||
// // Test 5: Null value / 空值
|
||||
// object value5 = null;
|
||||
// Check.Exception(value5.ObjToBool() == false, "ObjToBool with null");
|
||||
|
||||
// // Test 6: Invalid string / 无效字符串
|
||||
// object value6 = "invalid";
|
||||
// Check.Exception(value6.ObjToBool() == false, "ObjToBool with invalid string");
|
||||
// }
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region EqualCase Tests / EqualCase 测试
|
||||
|
||||
// //private static void TestEqualCase()
|
||||
// //{
|
||||
// // // Test 1: Same case / 相同大小写
|
||||
// // string value1 = "Hello";
|
||||
// // string value2 = "Hello";
|
||||
// // Check.Exception(value1.EqualCase(value2) == true, "EqualCase with same case");
|
||||
|
||||
// // // Test 2: Different case / 不同大小写
|
||||
// // string value3 = "Hello";
|
||||
// // string value4 = "hello";
|
||||
// // Check.Exception(value3.EqualCase(value4) == true, "EqualCase with different case");
|
||||
|
||||
// // // Test 3: Mixed case / 混合大小写
|
||||
// // string value5 = "HeLLo WoRLd";
|
||||
// // string value6 = "hello world";
|
||||
// // Check.Exception(value5.EqualCase(value6) == true, "EqualCase with mixed case");
|
||||
|
||||
// // // Test 4: Different strings / 不同字符串
|
||||
// // string value7 = "Hello";
|
||||
// // string value8 = "World";
|
||||
// // Check.Exception(value7.EqualCase(value8) == false, "EqualCase with different strings");
|
||||
|
||||
// // // Test 5: Both null / 都为空
|
||||
// // string value9 = null;
|
||||
// // string value10 = null;
|
||||
// // Check.Exception(value9.EqualCase(value10) == true, "EqualCase with both null");
|
||||
|
||||
// // // Test 6: One null / 一个为空
|
||||
// // string value11 = "Hello";
|
||||
// // string value12 = null;
|
||||
// // Check.Exception(value11.EqualCase(value12) == false, "EqualCase with one null");
|
||||
// //}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Edge Cases / 边界情况测试
|
||||
|
||||
// private static void TestEdgeCases()
|
||||
// {
|
||||
// // Test 1: Large numbers / 大数字
|
||||
// object largeInt = int.MaxValue;
|
||||
// Check.Exception(largeInt.ObjToInt() == int.MaxValue, "Edge case: int.MaxValue");
|
||||
|
||||
// // Test 2: Small numbers / 小数字
|
||||
// object smallInt = int.MinValue;
|
||||
// Check.Exception(smallInt.ObjToInt() == int.MinValue, "Edge case: int.MinValue");
|
||||
|
||||
// // Test 3: Very long number / 非常长的数字
|
||||
// //object longValue = long.MaxValue;
|
||||
// //Check.Exception(longValue.ObjToLong() == long.MaxValue, "Edge case: long.MaxValue");
|
||||
|
||||
// // Test 4: Very large decimal / 非常大的小数
|
||||
// object decimalValue = decimal.MaxValue;
|
||||
// Check.Exception(decimalValue.ObjToDecimal() == decimal.MaxValue, "Edge case: decimal.MaxValue");
|
||||
|
||||
// // Test 5: Negative decimal / 负小数
|
||||
// object negativeDecimal = -999.99m;
|
||||
// Check.Exception(negativeDecimal.ObjToDecimal() == -999.99m, "Edge case: negative decimal");
|
||||
|
||||
// // Test 6: Zero values / 零值
|
||||
// object zeroInt = 0;
|
||||
// Check.Exception(zeroInt.ObjToInt() == 0, "Edge case: zero int");
|
||||
|
||||
// object zeroDecimal = 0m;
|
||||
// Check.Exception(zeroDecimal.ObjToDecimal() == 0m, "Edge case: zero decimal");
|
||||
// }
|
||||
|
||||
// #endregion
|
||||
// }
|
||||
//}
|
||||
@@ -73,7 +73,7 @@ trim(a.tabname) as name,
|
||||
trim(b.comments) as Description
|
||||
from systables a
|
||||
left join syscomments b on b.tabname = a.tabname
|
||||
where a.tabtype in ('T') and not (a.tabname like 'sys%') AND a.tabname <>'dual' ";
|
||||
where a.tabtype in ('T') and a.tabid > 99";
|
||||
}
|
||||
}
|
||||
protected override string GetViewInfoListSql
|
||||
@@ -85,7 +85,7 @@ trim(a.tabname) as name,
|
||||
trim(b.comments) as Description
|
||||
from systables a
|
||||
left join syscomments b on b.tabname = a.tabname
|
||||
where a.tabtype in ('V') and not (a.tabname like 'sys%') AND a.tabname <>'dual' ";
|
||||
where a.tabtype in ('V') and a.tabid > 99 ";
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -566,7 +566,7 @@ namespace SqlSugar
|
||||
listItemPkColumn = listItemEntity.Columns.Where(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name2).FirstOrDefault();
|
||||
Check.ExceptionEasy(listItemPkColumn == null, $"{navObjectNameColumnInfo.PropertyName} Navigate is error ", $"{navObjectNameColumnInfo.PropertyName}导航配置错误,可能顺序反了。");
|
||||
}
|
||||
var ids = list.Select(it => it.GetType().GetProperty(navColumn.PropertyName).GetValue(it)).SelectMany(it => (it as IEnumerable).Cast<object>()).Distinct().ToList();
|
||||
var ids = list.Select(it => it.GetType().GetProperty(navColumn.PropertyName).GetValue(it)).Where(it=>it!=null).SelectMany(it => (it as IEnumerable).Cast<object>()).Distinct().ToList();
|
||||
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
|
||||
if (IsEnumNumber(navColumn))
|
||||
{
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace SqlSugar
|
||||
Args = new List<MethodCallExpressionArgs>() {
|
||||
new MethodCallExpressionArgs(){
|
||||
IsMember=true,
|
||||
MemberName= formatBuilder.FormatValue(value)
|
||||
MemberName= formatBuilder.FormatValue(UtilMethods.DateOnlyToDateTime(value))
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -319,8 +319,11 @@ namespace SqlSugar
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("(");
|
||||
builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "<>", parameterName);
|
||||
parameters.Add(new SugarParameter(parameterName, item.FieldValue));
|
||||
builder.Append($"OR {item.FieldName.ToSqlFilter()} is null ");
|
||||
builder.Append(")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ namespace SqlSugar
|
||||
var isNvarchar = model.Args.Count == 3;
|
||||
if (inValues != null && inValues.Count > 0)
|
||||
{
|
||||
if (isNvarchar && model.Args[2].MemberValue.Equals(true))
|
||||
if (isNvarchar && model.Args[2].MemberValue?.Equals(true)==true)
|
||||
{
|
||||
inValueString = inValues.ToArray().ToJoinSqlInValsN();
|
||||
}
|
||||
|
||||
@@ -875,7 +875,7 @@ namespace SqlSugar
|
||||
var dateString2 = this.Context.DbMehtods.GetDateString(model.Args.First().MemberName.ObjToString(), model.Args.Last().MemberValue.ObjToString());
|
||||
if (IsSqlServerModel())
|
||||
{
|
||||
return string.Format("FORMAT({0},'{1}','en-US')", model.Args.First().MemberName.ObjToString(), model.Args.Last().MemberValue.ObjToString());
|
||||
return string.Format("FORMAT({0},'{1}')", model.Args.First().MemberName.ObjToString(), model.Args.Last().MemberValue.ObjToString());
|
||||
}
|
||||
if (dateString2 != null) return dateString2;
|
||||
return GeDateFormat(model.Args.Last().MemberValue.ObjToString(), model.Args.First().MemberName.ObjToString());
|
||||
@@ -1135,7 +1135,7 @@ namespace SqlSugar
|
||||
var isMemoryExtensionsContainsArray = false;
|
||||
if (express.Method.DeclaringType.Name == "MemoryExtensions" && methodName == "Contains")
|
||||
{
|
||||
if (express.Arguments.Count() == 2)
|
||||
if (express.Arguments.Count() == 2|| express.Arguments.Count() == 3)
|
||||
{
|
||||
if (express.Arguments.First() is MethodCallExpression callExpression)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Version>5.1.4.207</Version>
|
||||
<Version>5.1.4.208</Version>
|
||||
<Copyright>sun_kai_xuan</Copyright>
|
||||
<PackageProjectUrl>https://github.com/sunkaixuan/SqlSugar</PackageProjectUrl>
|
||||
<PackageLicenseUrl></PackageLicenseUrl>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package >
|
||||
<metadata>
|
||||
<id>SqlSugarCore</id>
|
||||
<version>5.1.4.208-preview14</version>
|
||||
<version>5.1.4.208</version>
|
||||
<authors>sunkaixuan</authors>
|
||||
<owners>果糖大数据科技</owners>
|
||||
<licenseUrl>http://www.apache.org/licenses/LICENSE-2.0.html</licenseUrl>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package >
|
||||
<metadata>
|
||||
<id>SqlSugarCoreNoDrive</id>
|
||||
<version>5.1.4.207</version>
|
||||
<version>5.1.4.208</version>
|
||||
<authors>sunkaixuan</authors>
|
||||
<owners>Landa</owners>
|
||||
<licenseUrl>http://www.apache.org/licenses/LICENSE-2.0.html</licenseUrl>
|
||||
|
||||
@@ -1976,6 +1976,8 @@ namespace SqlSugar
|
||||
|
||||
internal static object DateOnlyToDateTime(object value)
|
||||
{
|
||||
if (value is DateTime)
|
||||
return value;
|
||||
if (value == null) return null;
|
||||
var method = value.GetType().GetMethods().First(it => it.GetParameters().Length == 0 && it.Name == "ToShortDateString");
|
||||
return method.Invoke(value, new object[] { });
|
||||
|
||||
Reference in New Issue
Block a user