Skip to content

Commit ba778fa

Browse files
committed
Ensure that at least one character can be converted. Fixes #974
1 parent bdc7721 commit ba778fa

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

src/MySqlConnector/MySqlBulkCopy.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,16 @@ static bool WriteSubstring(string value, ref int inputIndex, ref Encoder? utf8En
619619
if (nextIndex == -1)
620620
nextIndex = value.Length;
621621

622-
utf8Encoder ??= Encoding.UTF8.GetEncoder();
622+
utf8Encoder ??= s_utf8Encoding.GetEncoder();
623623
#if NETSTANDARD1_3
624+
if (output.Length <= 4 && utf8Encoder.GetByteCount(value.ToCharArray(), inputIndex, 1, flush: false) > output.Length)
625+
return false;
624626
var buffer = new byte[output.Length];
625627
utf8Encoder.Convert(value.ToCharArray(), inputIndex, nextIndex - inputIndex, buffer, 0, buffer.Length, nextIndex == value.Length, out var charsUsed, out var bytesUsed, out var completed);
626628
buffer.AsSpan().CopyTo(output);
627629
#else
630+
if (output.Length <= 4 && utf8Encoder.GetByteCount(value.AsSpan(inputIndex, 1), flush: false) > output.Length)
631+
return false;
628632
utf8Encoder.Convert(value.AsSpan(inputIndex, nextIndex - inputIndex), output, nextIndex == value.Length, out var charsUsed, out var bytesUsed, out var completed);
629633
#endif
630634

@@ -659,6 +663,7 @@ static bool WriteBytes(ReadOnlySpan<byte> value, ref int inputIndex, Span<byte>
659663

660664
private static readonly char[] s_specialCharacters = new char[] { '\t', '\\', '\n' };
661665
private static readonly IMySqlConnectorLogger Log = MySqlConnectorLogManager.CreateLogger(nameof(MySqlBulkCopy));
666+
private static readonly Encoding s_utf8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
662667

663668
readonly MySqlConnection m_connection;
664669
readonly MySqlTransaction? m_transaction;

src/MySqlConnector/Utilities/Utility.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ public static unsafe void Convert(this Encoder encoder, ReadOnlySpan<char> chars
7777
encoder.Convert(charsPtr, chars.Length, bytesPtr is null ? (byte*) 1 : bytesPtr, bytes.Length, flush, out charsUsed, out bytesUsed, out completed);
7878
}
7979
}
80+
81+
public static unsafe int GetByteCount(this Encoder encoder, ReadOnlySpan<char> chars, bool flush)
82+
{
83+
fixed (char* charsPtr = &MemoryMarshal.GetReference(chars))
84+
{
85+
// MemoryMarshal.GetNonNullPinnableReference is internal, so fake it by using an invalid but non-null pointer; this
86+
// prevents Convert from throwing an exception when the output buffer is empty
87+
return encoder.GetByteCount(charsPtr, chars.Length, flush);
88+
}
89+
}
8090
#endif
8191

8292
/// <summary>

0 commit comments

Comments
 (0)