22
33import { isSpace } from '../common/utils.mjs'
44
5+ // Limit the amount of empty autocompleted cells in a table,
6+ // see https://github.com/markdown-it/markdown-it/issues/1000,
7+ //
8+ // Both pulldown-cmark and commonmark-hs limit the number of cells this way to ~200k.
9+ // We set it to 65k, which can expand user input by a factor of x370
10+ // (256x256 square is 1.8kB expanded into 650kB).
11+ const MAX_AUTOCOMPLETED_CELLS = 0x10000
12+
513function getLine ( state , line ) {
614 const pos = state . bMarks [ line ] + state . tShift [ line ]
715 const max = state . eMarks [ line ]
@@ -157,6 +165,7 @@ export default function table (state, startLine, endLine, silent) {
157165 state . push ( 'thead_close' , 'thead' , - 1 )
158166
159167 let tbodyLines
168+ let autocompletedCells = 0
160169
161170 for ( nextLine = startLine + 2 ; nextLine < endLine ; nextLine ++ ) {
162171 if ( state . sCount [ nextLine ] < state . blkIndent ) { break }
@@ -177,6 +186,11 @@ export default function table (state, startLine, endLine, silent) {
177186 if ( columns . length && columns [ 0 ] === '' ) columns . shift ( )
178187 if ( columns . length && columns [ columns . length - 1 ] === '' ) columns . pop ( )
179188
189+ // note: autocomplete count can be negative if user specifies more columns than header,
190+ // but that does not affect intended use (which is limiting expansion)
191+ autocompletedCells += columnCount - columns . length
192+ if ( autocompletedCells > MAX_AUTOCOMPLETED_CELLS ) { break }
193+
180194 if ( nextLine === startLine + 2 ) {
181195 const token_tbo = state . push ( 'tbody_open' , 'tbody' , 1 )
182196 token_tbo . map = tbodyLines = [ startLine + 2 , 0 ]
0 commit comments