Skip to content

Fix IndexOutOfRangeException in LoadFromText when text file has more columns than specified DataTypes#2388

Merged
swmal merged 1 commit into
EPPlusSoftware:develop8from
lievendf:fix/import-data-file-index-out-of-bounds
Jun 18, 2026
Merged

Fix IndexOutOfRangeException in LoadFromText when text file has more columns than specified DataTypes#2388
swmal merged 1 commit into
EPPlusSoftware:develop8from
lievendf:fix/import-data-file-index-out-of-bounds

Conversation

@lievendf

Copy link
Copy Markdown
Contributor

Description

This pull request resolves a System.IndexOutOfRangeException that occurs during ExcelRangeBase.LoadFromText execution when importing text or CSV files.

Root Cause

In src/EPPlus/LoadFunctions/LoadFromTextBase.cs, the ConvertData method checks if the current column index col is out of bounds for the dataType array:

if (isText && (dataType == null || dataType.Length < col))
{
    return string.IsNullOrEmpty(v) ? null : v;
}
else
{
    if(dataType == null || dataType.Length < col)
        return ConvertData(Format, eDataTypes.Unknown, v, col, isText);
    return ConvertData(Format, dataType[col], v, col, isText);
}

The bounds checks use dataType.Length < col. Because col is a 0-based column index, when col is equal to dataType.Length, it is already out of bounds. The off-by-one check allowed execution to bypass the guard and attempt to access dataType[col], resulting in a System.IndexOutOfRangeException.

Solution

Simplified and corrected the bounds checking logic in src/EPPlus/LoadFunctions/LoadFromTextBase.cs's ConvertData method. Introduced a clean boolean flag isOutOfBounds checking col >= dataType.Length and cleanly structured the branches:

protected object ConvertData(T Format, eDataTypes[] dataType, string v, int col, bool isText)
{
    bool isOutOfBounds = dataType == null || col >= dataType.Length;

    if (isOutOfBounds)
    {
        if (isText)
        {
            return string.IsNullOrEmpty(v) ? null : v;
        }
        return ConvertData(Format, eDataTypes.Unknown, v, col, isText);
    }

    return ConvertData(Format, dataType[col], v, col, isText);
}

This ensures that any trailing columns beyond the length of the specified DataTypes array are handled gracefully and default to eDataTypes.Unknown (General) rather than causing a crash.

Unit Tests

Added a new unit test ShouldLoadCsvFormatWithTrailingColumns to src/EPPlusTest/LoadFunctions/LoadFromTextTests.cs to verify the fix and explain the historical issue with clear comments:

[TestMethod]
public void ShouldLoadCsvFormatWithTrailingColumns()
{
    // This test verifies that importing a text/CSV file with more columns than specified in DataTypes does not crash.
    // Previously, an off-by-one bounds check (dataType.Length < col) allowed the loop to attempt accessing dataType[col]
    // when 'col' was equal to 'dataType.Length', resulting in a System.IndexOutOfRangeException.
    // With the fix (col >= dataType.Length), trailing columns beyond the DataTypes array are gracefully imported as Unknown (General).
    AddLine("a;2;extra");
    _format.Delimiter = ';';
    _format.DataTypes = new eDataTypes[] { eDataTypes.String, eDataTypes.Number };
    _worksheet.Cells["A1"].LoadFromText(_lines.ToString(), _format);
    Assert.AreEqual("a", _worksheet.Cells["A1"].Value);
    Assert.AreEqual(2d, _worksheet.Cells["B1"].Value);
    Assert.AreEqual("extra", _worksheet.Cells["C1"].Value);
}

This test runs and passes successfully on both .NET 8.0 and .NET Framework 4.6.2 targets.

@swmal

swmal commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Hello @lievendf - Many thanks for this PR, see my comment on your previous PR about signing our CAA.

@swmal swmal merged commit a108702 into EPPlusSoftware:develop8 Jun 18, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants