string.Join returns an empty string when the total incoming length is a multiple of 1 << 32. This is a bug. It should throw an exception instead.
Warning, this allocates 8GB of memory:
checked
{
long totalDesiredLength = 1L << 32;
var maxLength = 1000000000;
var lengths = new int[] { maxLength, maxLength, maxLength, maxLength, (int)(totalDesiredLength - (long)maxLength * 4) };
var strings = lengths.Select(len => new string('x', len)).ToArray();
Debug.Assert(strings.Sum(x => (long)x.Length) == totalDesiredLength);
var result = string.Join("", strings, 0, strings.Length);
Console.WriteLine(result.Length);
}
The bug is here.
I'd suggest rewriting all that length calculation logic with the long data type and removing all cases of expected overflow.
Note, that the bug can also occur with separator != "".
Another problem is that the exception is inconsistent. It's sometimes OverflowException and sometimes IOOR in UnSafeCharBuffer.AppendString.
I think it never should be any of those. All indexes passed by the caller are valid and overflow is an implementation detail. Probably should be whatever happens when executing new string('x', int.MaxValue) which is OOM.
I don't see a realistic compat problem for this fix because joining such amounts of strings is an extremely unlikely thing to do.
string.Joinreturns an empty string when the total incoming length is a multiple of1 << 32. This is a bug. It should throw an exception instead.Warning, this allocates 8GB of memory:
The bug is here.
I'd suggest rewriting all that length calculation logic with the
longdata type and removing all cases of expected overflow.Note, that the bug can also occur with
separator != "".Another problem is that the exception is inconsistent. It's sometimes
OverflowExceptionand sometimesIOORinUnSafeCharBuffer.AppendString.I think it never should be any of those. All indexes passed by the caller are valid and overflow is an implementation detail. Probably should be whatever happens when executing
new string('x', int.MaxValue)which is OOM.I don't see a realistic compat problem for this fix because joining such amounts of strings is an extremely unlikely thing to do.