Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/MiniExcel.Core/Helpers/CellReferenceConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,21 @@ public static bool TryParseCellReference(string? value, out int column, out int
return false;
}

if (position == 0)
if (position == 0 || position == value.Length)
return false;

return int.TryParse(value[position..], NumberStyles.None, CultureInfo.InvariantCulture, out row)
&& row is > 0 and <= MaxRowNumber;
// Parsed by hand rather than with int.TryParse on a substring, which allocated for every cell
for (; position < value.Length; position++)
{
var digit = value[position] - '0';
row = row * 10 + digit;
if (digit is < 0 or > 9 || row > MaxRowNumber)
{
row = 0;
return false;
}
}

return row > 0;
}
}
19 changes: 15 additions & 4 deletions src/MiniExcel.OpenXml/Utils/XmlReaderHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,27 @@ public static async Task SkipToNextSiblingAsync(this XmlReader reader, Cancellat
}
}

// Called for every element and cell, so these loop instead of allocating a LINQ closure per call
public static bool IsStartElement(this XmlReader reader, string name, params string[] nss)
{
return nss.Any(s => reader.IsStartElement(name, s));
foreach (var ns in nss)
{
if (reader.IsStartElement(name, ns))
return true;
}

return false;
}

public static string? GetAttribute(this XmlReader reader, string name, params string[] nss)
{
return nss
.Select(ns => reader.GetAttribute(name, ns))
.FirstOrDefault(at => at is not null);
foreach (var ns in nss)
{
if (reader.GetAttribute(name, ns) is { } attribute)
return attribute;
}

return null;
}

// Copied and modified from ExcelDataReader - @MIT License
Expand Down
18 changes: 18 additions & 0 deletions tests/MiniExcel.OpenXml.Tests/Issues/MiniExcelGithubIssuesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ public void CellReferenceConverterEnforcesWorksheetLimits()
Assert.False(CellReferenceConverter.TryParseCellReference("A1048577", out _, out _));
}

[Theory]
[InlineData("B3", 2, 3)]
[InlineData("b03", 2, 3)]
[InlineData("A", 0, 0)]
[InlineData("A0", 0, 0)]
[InlineData("A1x", 0, 0)]
[InlineData("A-1", 0, 0)]
[InlineData("A99999999999", 0, 0)]
public void CellReferenceConverterParsesRowNumbers(string reference, int expectedColumn, int expectedRow)
{
var parsed = CellReferenceConverter.TryParseCellReference(reference, out var column, out var row);

Assert.Equal(expectedRow > 0, parsed);
Assert.Equal(expectedRow, row);
if (parsed)
Assert.Equal(expectedColumn, column);
}

[Fact]
public void QueryRangeAcceptsMaximumWorksheetCoordinates()
{
Expand Down
Loading