Skip to content

Internal overflow bug in string.Join(string[]) when passing huge strings #5591

@GSPP

Description

@GSPP

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions