`SqlParameter` with a `char[]` value copies the whole array, ignoring `Size`
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 62/100
Direzione di ricerca
Il bug si trova nella gestione di char[] in SqlParameter: Validate e GetMetaTypeOnly convertono l'intero array con new string(chars) invece di usare il limite Size. Inizia dai percorsi di codice di SqlParameter.cs citati negli stack trace e verifica se Size viene rispettato lì. Il lavoro è completo quando la conversione usa solo i primi Size caratteri e un test con un char[] grande e un Size piccolo non genera più eccezioni.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Describe the bug
tldr; Don't do new string(chars) instead do new string(chars, 0, Size)
When SqlParameter.Value is a char[] and Size is set to less than the array length, SqlClient converts the entire array to a string, but only sends Size chars.
The issue we saw is that when working with a very large char[] that contained a very small string, we received:
Exception message:
Insufficient memory to continue the execution of the program.
Stack trace:
---> System.OutOfMemoryException: Insufficient memory to continue the execution of the program.
at System.String.Ctor(Char[] value)
at Microsoft.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc)
at Microsoft.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters, Boolean includeReturnValue)
at Microsoft.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, SqlParameterCollection parameters, _SqlRPC& rpc)
at
To reproduce
Run this test:
using System;
using System.Data;
using System.Text;
using Microsoft.Data.SqlClient;
using NServiceBus;
using NUnit.Framework;
[Explicit("Allocates ~4 GiB")]
public class BigBuffer
{
[Test]
public void BigArrayWillThrow()
{
var buffer = new char[1 << 30]; // e.g. a pooled buffer that once held a large payload
"{}".CopyTo(0, buffer, 0, 2);
var parameter = new SqlParameter();
new SqlDialect.MsSqlServer().SetParameterValue(parameter,
new ArraySegment<char>(buffer, 0, 2));
Console.Out.Write(parameter.DbType);
}
}
That test will give:
System.OverflowException : Arithmetic operation resulted in an overflow.
at System.String.Ctor(Char[] value)
at Microsoft.Data.SqlClient.SqlParameter.GetMetaTypeOnly()
at Microsoft.Data.SqlClient.SqlParameter.get_DbType()
at PoisonedWriterPoolTests.BigArrayWillThrow() in /Users/auser/Documents/code/NServiceBus.Persistence.Sql/src/SqlPersistence.Tests/PoisonedWriterPoolTests.cs:line 39
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
The issue we saw in prod was a OOM because the char array could be created into a string, as the CLR didn't have enough contiguous memory to allocate such a string. Either way the fix is the simple new string(chars, 0, Size)
Expected behavior
It should not throw.
Further technical details
Microsoft.Data.SqlClient version: 7.1.1
.NET target: .NET 10
Additional context
Add any other context about the problem here.
- Lingua principale
- C#
- Stelle
- 1k
- Fork
- 352
- Merge medio
- 2g 18h
- PR unite (30g)
- 133
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di dotnet/SqlClient
-
Sync ExecuteReader on an STA thread deadlocks against a StateChange handler that marshals to the UI thread (OpenAsyncRetry path)Forse di nuovo libera @mdaigle l’ha presa 56 giorni fa e non c’è nessuna pull request aperta. ApertaExternal :link:
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
dotnet/SqlClient#4534 · 2 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Area\Tests
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
dotnet/SqlClient#4377 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Managed SNI: TLS handshake ignores Connect Timeout, one stalled handshake blocks every OpenAsync on the poolForse già presa @mdaigle l’ha presa 1 giorno fa. ApertaArea\Managed SNI
dotnet/SqlClient#5045 · 2 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Cancelling `SqlBatch.ExecuteNonQueryAsync` throws `ArgumentOutOfRangeException` from `SqlCommand.GetBatchCommand` instead of a cancellation exceptionForse già presa @cheenamalhotra l’ha presa oggi. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 53/100
dotnet/SqlClient#5042 · 1 commento · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
dotnet/SqlClient#5040 · 9 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di dotnet/SqlClient
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
-
area:repo elsa 3 prio low triaged type:bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
elsa-workflows/elsa-core#9258 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
iokode/OpinionatedFramework#140 ·
-
accessibility effort: small enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
pedersebastian/CustomBossChallenge#185 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100