@@ -84,32 +84,32 @@ public IEnumerable<IDictionary<string, object>> QueryRange(bool useHeaderRow, st
8484
8585 public IEnumerable < IDictionary < string , object > > QueryRange ( bool useHeaderRow , string sheetName , int startRowIndex , int startColumnIndex , int ? endRowIndex , int ? endColumnIndex )
8686 {
87- if ( startRowIndex <= 0 )
87+ if ( startRowIndex is <= 0 or > ReferenceHelper . MaxRowNumber )
8888 {
89- throw new ArgumentOutOfRangeException ( nameof ( startRowIndex ) , "Start row index is 1-based and must be greater than 0 ." ) ;
89+ throw new ArgumentOutOfRangeException ( nameof ( startRowIndex ) , $ "Start row index must be between 1 and { ReferenceHelper . MaxRowNumber } .") ;
9090 }
91- if ( startColumnIndex <= 0 )
91+ if ( startColumnIndex is <= 0 or > ReferenceHelper . MaxColumnNumber )
9292 {
93- throw new ArgumentOutOfRangeException ( nameof ( startColumnIndex ) , "Start column index is 1-based and must be greater than 0 ." ) ;
93+ throw new ArgumentOutOfRangeException ( nameof ( startColumnIndex ) , $ "Start column index must be between 1 and { ReferenceHelper . MaxColumnNumber } .") ;
9494 }
9595 // convert to 0-based
9696 startColumnIndex -- ;
9797 startRowIndex -- ;
9898
9999 if ( endRowIndex . HasValue )
100100 {
101- if ( endRowIndex . Value <= 0 )
101+ if ( endRowIndex . Value is <= 0 or > ReferenceHelper . MaxRowNumber )
102102 {
103- throw new ArgumentOutOfRangeException ( nameof ( endRowIndex ) , "End row index is 1-based and must be greater than 0 ." ) ;
103+ throw new ArgumentOutOfRangeException ( nameof ( endRowIndex ) , $ "End row index must be between 1 and { ReferenceHelper . MaxRowNumber } .") ;
104104 }
105105 // convert to 0-based
106106 endRowIndex -- ;
107107 }
108108 if ( endColumnIndex . HasValue )
109109 {
110- if ( endColumnIndex . Value <= 0 )
110+ if ( endColumnIndex . Value is <= 0 or > ReferenceHelper . MaxColumnNumber )
111111 {
112- throw new ArgumentOutOfRangeException ( nameof ( endColumnIndex ) , "End column index is 1-based and must be greater than 0 ." ) ;
112+ throw new ArgumentOutOfRangeException ( nameof ( endColumnIndex ) , $ "End column index must be between 1 and { ReferenceHelper . MaxColumnNumber } .") ;
113113 }
114114 // convert to 0-based
115115 endColumnIndex -- ;
@@ -164,15 +164,29 @@ internal IEnumerable<IDictionary<string, object>> InternalQueryRange(bool useHea
164164 var headRows = new Dictionary < int , string > ( ) ;
165165 int rowIndex = - 1 ;
166166 bool isFirstRow = true ;
167+ long synthesizedCellCount = 0 ;
167168 while ( ! reader . EOF )
168169 {
169170 if ( XmlReaderHelper . IsStartElement ( reader , "row" , _ns ) )
170171 {
171172 var nextRowIndex = rowIndex + 1 ;
172- if ( int . TryParse ( reader . GetAttribute ( "r" ) , out int arValue ) )
173- rowIndex = arValue - 1 ; // The row attribute is 1-based
173+ var rowAttribute = reader . GetAttribute ( "r" ) ;
174+ if ( rowAttribute != null )
175+ {
176+ if ( ! int . TryParse ( rowAttribute , NumberStyles . None , CultureInfo . InvariantCulture , out var rowNumber )
177+ || rowNumber is < 1 or > ReferenceHelper . MaxRowNumber )
178+ {
179+ throw new InvalidDataException ( $ "Row index '{ rowAttribute } ' is outside Excel's valid range.") ;
180+ }
181+
182+ rowIndex = rowNumber - 1 ; // The row attribute is 1-based
183+ }
174184 else
185+ {
175186 rowIndex ++ ;
187+ if ( rowIndex >= ReferenceHelper . MaxRowNumber )
188+ throw new InvalidDataException ( "The worksheet contains more rows than Excel supports." ) ;
189+ }
176190
177191 if ( rowIndex < startRowIndex )
178192 {
@@ -188,6 +202,24 @@ internal IEnumerable<IDictionary<string, object>> InternalQueryRange(bool useHea
188202 break ;
189203 }
190204
205+ if ( ! _config . IgnoreEmptyRows && _config . MaxSynthesizedCells . HasValue )
206+ {
207+ var expectedRowIndex = isFirstRow ? startRowIndex : nextRowIndex ;
208+ var emptyRowCount = Math . Max ( 0 , rowIndex - expectedRowIndex ) ;
209+ var columnCount = useHeaderRow
210+ ? Math . Max ( 1 , headRows . Count )
211+ : Math . Max ( 1 , maxColumnIndex - startColumnIndex + 1 ) ;
212+
213+ var selfClosingRowCount = reader . IsEmptyElement ? 1 : 0 ;
214+ synthesizedCellCount += ( long ) ( emptyRowCount + selfClosingRowCount ) * columnCount ;
215+
216+ if ( synthesizedCellCount > _config . MaxSynthesizedCells . Value )
217+ {
218+ throw new InvalidDataException (
219+ $ "The worksheet exceeds the configured limit of { _config . MaxSynthesizedCells . Value } synthesized empty cells.") ;
220+ }
221+ }
222+
191223 foreach ( var row in QueryRow ( reader , isFirstRow , startRowIndex , nextRowIndex , rowIndex , startColumnIndex , endColumnIndex , maxColumnIndex , withoutCR , useHeaderRow , headRows , _mergeCells ) )
192224 {
193225 if ( isFirstRow )
@@ -643,6 +675,8 @@ private CellAndColumn ReadCellAndSetColumnIndex(XmlReader reader, int columnInde
643675 //TODO:need to check only need nextColumnIndex or columnIndex
644676 else if ( ReferenceHelper . ParseReference ( aR , out int referenceColumn , out _ ) )
645677 newColumnIndex = referenceColumn - 1 ; // ParseReference is 1-based
678+ else if ( ! string . IsNullOrEmpty ( aR ) && referenceColumn > ReferenceHelper . MaxColumnNumber )
679+ throw new InvalidDataException ( $ "Cell reference '{ aR } ' is invalid.") ;
646680 else
647681 newColumnIndex = columnIndex ;
648682
0 commit comments