Browse Source

limit the number of autocompleted cells in a table

fix https://github.com/markdown-it/markdown-it/issues/1000
pull/1009/head
Alex Kocharin 10 months ago
parent
commit
00b8a93c8f
  1. 14
      lib/rules_block/table.mjs

14
lib/rules_block/table.mjs

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

Loading…
Cancel
Save