Docx writer: prevent crashing when handling invalid tables

Tables with different numbers of cells per row would sometimes crash
pandoc. This fix prevents this by cutting off overlong rows.

Fixes: #8102
This commit is contained in:
Albert Krewinkel 2022-06-04 23:40:49 +02:00
parent 461566aa80
commit cc2849ccd0
No known key found for this signature in database
GPG key ID: 388DC0B21F631124

View file

@ -124,17 +124,29 @@ rowsToPart attr = \case
forM_ cells $ \(Cell cellAttr align rs cs blks) -> do
ridx' <- readSTRef ridx
let nextFreeInRow colindex@(ColIndex c) = do
readArray grid (ridx', colindex) >>= \case
FreeCell -> pure colindex
_ -> nextFreeInRow $ ColIndex (c + 1)
cidx' <- readSTRef cidx >>= nextFreeInRow
writeArray grid (ridx', cidx') . FilledCell $
ContentCell cellAttr align rs cs blks
forM_ (continuationIndices ridx' cidx' rs cs) $ \idx -> do
writeArray grid idx . FilledCell $
ContinuationCell (ridx', cidx')
-- go to new column
writeSTRef cidx cidx'
let idx = (ridx', colindex)
if gbounds `inRange` idx
then readArray grid idx >>= \case
FreeCell -> pure (Just colindex)
_ -> nextFreeInRow $ ColIndex (c + 1)
else pure Nothing -- invalid table
mcidx' <- readSTRef cidx >>= nextFreeInRow
-- If there is a FreeCell in the current row, then fill it
-- with the current cell and mark cells in this and the
-- following rows as continuation cells if necessary.
--
-- Just skip the current table cell if no FreeCell was
-- found; this can only happen with invalid tables.
case mcidx' of
Nothing -> pure () -- no FreeCell left in row -- skip cell
Just cidx' -> do
writeArray grid (ridx', cidx') . FilledCell $
ContentCell cellAttr align rs cs blks
forM_ (continuationIndices ridx' cidx' rs cs) $ \idx -> do
writeArray grid idx . FilledCell $
ContinuationCell (ridx', cidx')
-- go to new column
writeSTRef cidx cidx'
-- go to next row
modifySTRef ridx (incrRowIndex 1)
-- Swap BuilderCells with normal GridCells.