Commit 6436d86
feat: support TIFF images in DOCX rendering (#2284)
* feat: support TIFF images in DOCX rendering
TIFF images in DOCX files rendered as broken icons because browsers
cannot natively display image/tiff. Convert TIFF to PNG at import time
using utif2, following the existing EMF/WMF → SVG conversion pattern.
Closes #2064
* fix: enforce pixel limit before TIFF decode to prevent DoS
Reject TIFF images exceeding 100M pixels before allocating RGBA buffers
or canvas, preventing a malicious TIFF with extreme dimensions from
freezing or crashing the tab during import.
* fix: validate TIFF dimensions before decoding and correct .tif MIME type
Move MAX_PIXEL_COUNT check before UTIF.decodeImage/toRGBA8 so oversized
TIFFs are rejected before allocating the RGBA buffer.
Map .tif extension to image/tiff in Content_Types.xml generation to
avoid emitting the invalid MIME type image/tif.
* fix: read TIFF dimensions from raw IFD tags for pre-decode validation
UTIF.decode populates raw tag entries (t256/t257) but .width/.height
are only set after decodeImage. Read from raw tags so the pixel limit
guard works before the expensive decode step without rejecting valid
files.
* fix: address PR review feedback for TIFF support
- Use mimeTypeForExt mapping for .tif data URIs (image/tiff not image/tif)
- Remove unused size arg from convertTiffToPng call
- Add happy-path test asserting valid TIFF produces PNG data URI
* fix: clean up convertTiffToPng signature and add wiring test
- Remove unused Uint8Array/ArrayBufferView branches (only strings are passed)
- Add handleImageNode test verifying convertTiffToPng is called for .tif files
* test: add integration test for TIFF image loading pipeline
Adds a Playwright test that loads a minimal DOCX containing a TIFF image
and verifies the full pipeline: DocxZipper → convertTiffToPng → rendered PNG.
* refactor: replace utif2 with image-js/tiff and deduplicate DocxZipper constants
Replace unmaintained utif2 with actively maintained image-js/tiff for
TIFF decoding. Extract duplicated IMAGE_EXTS and MIME_TYPE_FOR_EXT
mappings in DocxZipper.js to module-level constants.
* fix: pre-decode size guard and 16-bit TIFF normalization
Use decode(buffer, { ignoreImageData: true }) to check dimensions
before allocating pixel data, preventing DoS from small compressed
TIFFs with huge dimensions. Normalize Uint16Array and Float32Array
pixel data to 8-bit for canvas compatibility.
* test: add TIFF MIME, fallback, and branch coverage tests; extract shared dataUriToArrayBuffer helper
Address remaining PR review feedback: add tests for .tif → image/tiff MIME mapping
(import data URI and export Content_Types), TIFF conversion failure fallback alt text,
greyscale/grey+alpha/Uint16/Float32 toRGBA branches, and extract duplicate data-URI-stripping
logic from metafile-converter and tiff-converter into shared dataUriToArrayBuffer in helpers.js.
* fix: revert to utif2 for TIFF decoding
image-js/tiff lacks support for PackBits, JPEG, and CCITT compression
formats commonly found in Word documents. utif2 handles all TIFF
compression types via its toRGBA8 pipeline. Updated tests to match
utif2 API (decode → decodeImage → toRGBA8).
* fix: prefer domEnvironment over global document in createCanvas
- createCanvas() now checks domEnvironment first, fixing silent failures
in JSDOM environments where global document lacks canvas support
- Add dataUriToArrayBuffer unit tests covering all input branches and
both throw paths
- Add explanatory comment for query-string module re-imports in tests
---------
Co-authored-by: G Pardhiv Varma <gpardhivvarma@gmail.com>1 parent 66ad683 commit 6436d86
16 files changed
Lines changed: 545 additions & 73 deletions
File tree
- packages/super-editor
- src/core
- super-converter
- v3/handlers
- wp/helpers
- w/p/helpers
- tests/behavior/tests/importing
- fixtures
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
101 | 101 | | |
102 | 102 | | |
103 | 103 | | |
| 104 | + | |
104 | 105 | | |
105 | 106 | | |
106 | 107 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
8 | 14 | | |
9 | 15 | | |
10 | 16 | | |
| |||
63 | 69 | | |
64 | 70 | | |
65 | 71 | | |
66 | | - | |
67 | | - | |
68 | 72 | | |
69 | 73 | | |
70 | | - | |
| 74 | + | |
71 | 75 | | |
72 | 76 | | |
73 | 77 | | |
74 | 78 | | |
75 | 79 | | |
76 | 80 | | |
77 | | - | |
78 | | - | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
79 | 84 | | |
80 | 85 | | |
81 | 86 | | |
| |||
105 | 110 | | |
106 | 111 | | |
107 | 112 | | |
108 | | - | |
109 | 113 | | |
110 | 114 | | |
111 | | - | |
| 115 | + | |
112 | 116 | | |
113 | 117 | | |
114 | 118 | | |
| |||
131 | 135 | | |
132 | 136 | | |
133 | 137 | | |
134 | | - | |
| 138 | + | |
| 139 | + | |
135 | 140 | | |
136 | 141 | | |
137 | 142 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
338 | 338 | | |
339 | 339 | | |
340 | 340 | | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
341 | 399 | | |
342 | 400 | | |
343 | 401 | | |
| |||
Lines changed: 28 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
36 | 63 | | |
37 | 64 | | |
38 | 65 | | |
| |||
720 | 747 | | |
721 | 748 | | |
722 | 749 | | |
| 750 | + | |
723 | 751 | | |
724 | 752 | | |
Lines changed: 38 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| |||
385 | 386 | | |
386 | 387 | | |
387 | 388 | | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
388 | 426 | | |
389 | 427 | | |
390 | 428 | | |
| |||
Lines changed: 10 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
22 | 26 | | |
23 | 27 | | |
24 | 28 | | |
| |||
Lines changed: 16 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
20 | 24 | | |
21 | 25 | | |
22 | 26 | | |
| |||
packages/super-editor/src/core/super-converter/v3/handlers/wp/helpers/encode-image-node-helpers.js
Lines changed: 19 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
405 | 406 | | |
406 | 407 | | |
407 | 408 | | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
408 | 425 | | |
409 | 426 | | |
410 | 427 | | |
| |||
416 | 433 | | |
417 | 434 | | |
418 | 435 | | |
419 | | - | |
420 | | - | |
| 436 | + | |
| 437 | + | |
421 | 438 | | |
422 | 439 | | |
423 | 440 | | |
| |||
Lines changed: 38 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
24 | 33 | | |
25 | 34 | | |
26 | 35 | | |
| |||
221 | 230 | | |
222 | 231 | | |
223 | 232 | | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
224 | 261 | | |
225 | 262 | | |
226 | 263 | | |
| |||
292 | 329 | | |
293 | 330 | | |
294 | 331 | | |
295 | | - | |
| 332 | + | |
296 | 333 | | |
297 | 334 | | |
298 | 335 | | |
| |||
0 commit comments