test: every fixture picture is a PNG a browser accepts
The 1x1 fixture carried an IDAT from a different image: its CRC fails and the zlib stream is truncated. Chromium and WebKit render it anyway, Firefox reports "Image corrupt or truncated", and the same bytes sat in eleven fixtures.
This commit is contained in:
1 parent
055839655e
commit
bd38c955ae
12 files changed
+14
-14
No files matched your search
@@ -7,7 +7,7 @@ import { HEADER_SHADE } from '../src/lib/editor/extensions/tableHeaderRow';
|
||||
|
||||
type N = { type: string; attrs?: any; content?: N[]; marks?: any[]; text?: string };
|
||||
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
|
||||
const text = (t: string, marks?: any[]) => ({ type: 'text', text: t, ...(marks ? { marks } : {}) });
|
||||
const para = (content: any, attrs: any = {}) => ({ type: 'paragraph', attrs, content: Array.isArray(content) ? content : [text(content)] });
|
||||
@@ -429,7 +429,7 @@ describe('DOCX different first page (w:titlePg)', () => {
|
||||
});
|
||||
|
||||
it('round-trips an inline image in the default footer and the first-page header', async () => {
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
const image = (w: number, h: number): N => ({ type: 'image', attrs: { src: PNG, alt: 'Logo', width: w, height: h, wrap: 'inline' } });
|
||||
const withImgs = {
|
||||
...hf,
|
||||
|
||||
+1
-1
@@ -344,7 +344,7 @@ function list(r: Rng, kind: 'bulletList' | 'orderedList', depth: number,
|
||||
}
|
||||
|
||||
// A tiny valid PNG; only its bytes matter for the round-trip (no image decoding).
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
|
||||
// A styled table as the editor authors it: name + look on the table, the style's fill,
|
||||
// borders and `region` materialized onto the cells (paintTable). Both importers
|
||||
|
||||
@@ -23,7 +23,7 @@ function check(label: string, cond: boolean, detail?: unknown) {
|
||||
const T = (text: string, ...marks: N[]): N => ({ type: 'text', text, ...(marks.length ? { marks } : {}) });
|
||||
const P = (attrs: N | null, ...content: N[]): N => ({ type: 'paragraph', ...(attrs ? { attrs } : {}), ...(content.length ? { content } : {}) });
|
||||
const LI = (...content: N[]): N => ({ type: 'listItem', content });
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
const IMGN = (width: number, height: number, alt?: string, rotation?: number, wrap?: string): N =>
|
||||
({ type: 'image', attrs: {
|
||||
src: PNG, width, height,
|
||||
|
||||
@@ -260,7 +260,7 @@ await write('12-notes.docx', [{
|
||||
|
||||
// 13. Images: an inline picture in the line, sized in EMU by the lib.
|
||||
const PNG = Buffer.from(
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC',
|
||||
'base64');
|
||||
await write('13-images.docx', [{
|
||||
properties: { page },
|
||||
|
||||
@@ -41,7 +41,7 @@ const CELLM = (colspan: number, rowspan: number, colwidth: number[] | null, text
|
||||
const ROW = (...cells: N[]): N => ({ type: 'tableRow', content: cells });
|
||||
|
||||
// A tiny valid PNG; only its bytes matter for the round-trip (no image decoding).
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
const IMGN = (width: number, height: number, alt?: string, rotation?: number, wrap?: string, wrapOffsetY?: number): N =>
|
||||
({ type: 'image', attrs: {
|
||||
src: PNG, width, height,
|
||||
@@ -1070,7 +1070,7 @@ describe('Leg 3a: different first page header/footer → buildOdt → importOdt'
|
||||
|
||||
describe('Leg 3b: inline images in header/footer → buildOdt → importOdt', () => {
|
||||
it('round-trips an as-char image in a default zone and a first-page zone', async () => {
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
const img = (w: number, h: number): N => ({ type: 'image', attrs: { src: PNG, alt: 'Logo', width: w, height: h, wrap: 'inline' } });
|
||||
const footer: N = { type: 'doc', content: [P({ textAlign: 'center' }, T('Logo '), img(120, 48))] };
|
||||
const headerFirst: N = { type: 'doc', content: [P(null, img(200, 60))] };
|
||||
|
||||
@@ -5,7 +5,7 @@ import { HEADER_SHADE } from '../../src/lib/editor/extensions/tableHeaderRow';
|
||||
|
||||
// 1×1 transparent PNG.
|
||||
const PNG =
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
|
||||
const text = (t: string, marks?: any[]) => ({ type: 'text', text: t, ...(marks ? { marks } : {}) });
|
||||
const para = (content: any, attrs: any = {}) => ({ type: 'paragraph', attrs, content: Array.isArray(content) ? content : [text(content)] });
|
||||
|
||||
@@ -4,7 +4,7 @@ import { importDocx } from '../../src/lib/import/docx';
|
||||
|
||||
// A 1x1 PNG — real bytes so the importer's magic-number sniff accepts the media.
|
||||
const PNG = Uint8Array.from(
|
||||
atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='),
|
||||
atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC'),
|
||||
(c) => c.charCodeAt(0),
|
||||
);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { importDocx } from '../../src/lib/import/docx';
|
||||
|
||||
type N = any;
|
||||
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
const IMG = (attrs: N): N => ({ type: 'image', attrs: { src: PNG, width: 300, height: 200, ...attrs } });
|
||||
const para = (img: N): N => ({ type: 'paragraph', content: [img] });
|
||||
const frames = (d: N) => d.content.flatMap((b: N) => (b.content ?? []).filter((n: N) => n.type === 'image'));
|
||||
|
||||
@@ -9,7 +9,7 @@ import { importDocx } from '../../src/lib/import/docx';
|
||||
|
||||
type N = any;
|
||||
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
const IMG = (attrs: N): N => ({ type: 'image', attrs: { src: PNG, width: 200, height: 120, ...attrs } });
|
||||
|
||||
const doc: N = {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { inlineVerticalAlign } from '../../src/lib/editor/extensions/image';
|
||||
|
||||
type N = any;
|
||||
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
const IMG = (attrs: N): N => ({ type: 'image', attrs: { src: PNG, width: 80, height: 40, ...attrs } });
|
||||
const margins = { top: 2, bottom: 2, left: 2, right: 2 };
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { unzipSync, strFromU8 } from 'fflate';
|
||||
import { buildDocx } from '../../src/lib/export/docx';
|
||||
import { importDocx } from '../../src/lib/import/docx';
|
||||
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
const img = { type: 'image', attrs: { src: PNG, width: 40, height: 30 } };
|
||||
const doc = (kind: 'footnote' | 'endnote') => ({
|
||||
type: 'doc',
|
||||
|
||||
@@ -8,7 +8,7 @@ import { importDocx } from '../../src/lib/import/docx';
|
||||
|
||||
type N = any;
|
||||
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNwaDgAAAKEAYEml6crAAAAAElFTkSuQmCC';
|
||||
const IMG = (attrs: N): N => ({ type: 'image', attrs: { src: PNG, width: 200, height: 120, ...attrs } });
|
||||
|
||||
const docWith = (attrs: N): N => ({
|
||||
|
||||
Reference in new issue
Block a user