Simplify writeObject function

It'll avoid to have the duplication of the code to get the encrypt transform,
and last but not least, it'll avoid to forget about encryption.
This commit is contained in:
Calixte Denizet 2023-09-08 19:29:29 +02:00
parent b903b3030a
commit 52cc1220e4
3 changed files with 24 additions and 98 deletions

View File

@ -55,7 +55,6 @@ import {
} from "./default_appearance.js"; } from "./default_appearance.js";
import { Dict, isName, isRefsEqual, Name, Ref, RefSet } from "./primitives.js"; import { Dict, isName, isRefsEqual, Name, Ref, RefSet } from "./primitives.js";
import { Stream, StringStream } from "./stream.js"; import { Stream, StringStream } from "./stream.js";
import { writeDict, writeObject } from "./writer.js";
import { BaseStream } from "./base_stream.js"; import { BaseStream } from "./base_stream.js";
import { bidi } from "./bidi.js"; import { bidi } from "./bidi.js";
import { Catalog } from "./catalog.js"; import { Catalog } from "./catalog.js";
@ -64,6 +63,7 @@ import { FileSpec } from "./file_spec.js";
import { JpegStream } from "./jpeg_stream.js"; import { JpegStream } from "./jpeg_stream.js";
import { ObjectLoader } from "./object_loader.js"; import { ObjectLoader } from "./object_loader.js";
import { OperatorList } from "./operator_list.js"; import { OperatorList } from "./operator_list.js";
import { writeObject } from "./writer.js";
import { XFAFactory } from "./xfa/factory.js"; import { XFAFactory } from "./xfa/factory.js";
class AnnotationFactory { class AnnotationFactory {
@ -336,13 +336,7 @@ class AnnotationFactory {
baseFont.set("Encoding", Name.get("WinAnsiEncoding")); baseFont.set("Encoding", Name.get("WinAnsiEncoding"));
const buffer = []; const buffer = [];
baseFontRef = xref.getNewTemporaryRef(); baseFontRef = xref.getNewTemporaryRef();
const transform = xref.encrypt await writeObject(baseFontRef, baseFont, buffer, xref);
? xref.encrypt.createCipherTransform(
baseFontRef.num,
baseFontRef.gen
)
: null;
await writeObject(baseFontRef, baseFont, buffer, transform);
dependencies.push({ ref: baseFontRef, data: buffer.join("") }); dependencies.push({ ref: baseFontRef, data: buffer.join("") });
} }
promises.push( promises.push(
@ -369,19 +363,13 @@ class AnnotationFactory {
const buffer = []; const buffer = [];
if (smaskStream) { if (smaskStream) {
const smaskRef = xref.getNewTemporaryRef(); const smaskRef = xref.getNewTemporaryRef();
const transform = xref.encrypt await writeObject(smaskRef, smaskStream, buffer, xref);
? xref.encrypt.createCipherTransform(smaskRef.num, smaskRef.gen)
: null;
await writeObject(smaskRef, smaskStream, buffer, transform);
dependencies.push({ ref: smaskRef, data: buffer.join("") }); dependencies.push({ ref: smaskRef, data: buffer.join("") });
imageStream.dict.set("SMask", smaskRef); imageStream.dict.set("SMask", smaskRef);
buffer.length = 0; buffer.length = 0;
} }
const imageRef = (image.imageRef = xref.getNewTemporaryRef()); const imageRef = (image.imageRef = xref.getNewTemporaryRef());
const transform = xref.encrypt await writeObject(imageRef, imageStream, buffer, xref);
? xref.encrypt.createCipherTransform(imageRef.num, imageRef.gen)
: null;
await writeObject(imageRef, imageStream, buffer, transform);
dependencies.push({ ref: imageRef, data: buffer.join("") }); dependencies.push({ ref: imageRef, data: buffer.join("") });
image.imageStream = image.smaskStream = null; image.imageStream = image.smaskStream = null;
} }
@ -1634,20 +1622,14 @@ class MarkupAnnotation extends Annotation {
if (ap) { if (ap) {
const apRef = xref.getNewTemporaryRef(); const apRef = xref.getNewTemporaryRef();
annotationDict = this.createNewDict(annotation, xref, { apRef }); annotationDict = this.createNewDict(annotation, xref, { apRef });
const transform = xref.encrypt await writeObject(apRef, ap, buffer, xref);
? xref.encrypt.createCipherTransform(apRef.num, apRef.gen)
: null;
await writeObject(apRef, ap, buffer, transform);
dependencies.push({ ref: apRef, data: buffer.join("") }); dependencies.push({ ref: apRef, data: buffer.join("") });
} else { } else {
annotationDict = this.createNewDict(annotation, xref, {}); annotationDict = this.createNewDict(annotation, xref, {});
} }
buffer.length = 0; buffer.length = 0;
const transform = xref.encrypt await writeObject(annotationRef, annotationDict, buffer, xref);
? xref.encrypt.createCipherTransform(annotationRef.num, annotationRef.gen)
: null;
await writeObject(annotationRef, annotationDict, buffer, transform);
return { ref: annotationRef, data: buffer.join("") }; return { ref: annotationRef, data: buffer.join("") };
} }
@ -2063,11 +2045,6 @@ class WidgetAnnotation extends Annotation {
dict.set("MK", maybeMK); dict.set("MK", maybeMK);
} }
const encrypt = xref.encrypt;
const originalTransform = encrypt
? encrypt.createCipherTransform(this.ref.num, this.ref.gen)
: null;
const buffer = []; const buffer = [];
const changes = [ const changes = [
// data for the original object // data for the original object
@ -2080,11 +2057,6 @@ class WidgetAnnotation extends Annotation {
dict.set("AP", AP); dict.set("AP", AP);
AP.set("N", newRef); AP.set("N", newRef);
let newTransform = null;
if (encrypt) {
newTransform = encrypt.createCipherTransform(newRef.num, newRef.gen);
}
const resources = this._getSaveFieldResources(xref); const resources = this._getSaveFieldResources(xref);
const appearanceStream = new StringStream(appearance); const appearanceStream = new StringStream(appearance);
const appearanceDict = (appearanceStream.dict = new Dict(xref)); const appearanceDict = (appearanceStream.dict = new Dict(xref));
@ -2103,7 +2075,7 @@ class WidgetAnnotation extends Annotation {
appearanceDict.set("Matrix", rotationMatrix); appearanceDict.set("Matrix", rotationMatrix);
} }
await writeObject(newRef, appearanceStream, buffer, newTransform); await writeObject(newRef, appearanceStream, buffer, xref);
changes.push( changes.push(
// data for the new AP // data for the new AP
@ -2118,7 +2090,7 @@ class WidgetAnnotation extends Annotation {
} }
dict.set("M", `D:${getModificationDate()}`); dict.set("M", `D:${getModificationDate()}`);
await writeObject(this.ref, dict, buffer, originalTransform); await writeObject(this.ref, dict, buffer, xref);
changes[0].data = buffer.join(""); changes[0].data = buffer.join("");
@ -2980,18 +2952,8 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
dict.set("MK", maybeMK); dict.set("MK", maybeMK);
} }
const encrypt = evaluator.xref.encrypt; const buffer = [];
let originalTransform = null; await writeObject(this.ref, dict, buffer, evaluator.xref);
if (encrypt) {
originalTransform = encrypt.createCipherTransform(
this.ref.num,
this.ref.gen
);
}
const buffer = [`${this.ref.num} ${this.ref.gen} obj\n`];
await writeDict(dict, buffer, originalTransform);
buffer.push("\nendobj\n");
return [{ ref: this.ref, data: buffer.join(""), xfa }]; return [{ ref: this.ref, data: buffer.join(""), xfa }];
} }
@ -3034,23 +2996,16 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
}; };
const name = Name.get(value ? this.data.buttonValue : "Off"); const name = Name.get(value ? this.data.buttonValue : "Off");
let parentBuffer = null; const buffer = [];
const encrypt = evaluator.xref.encrypt; let parentData = null;
if (value) { if (value) {
if (this.parent instanceof Ref) { if (this.parent instanceof Ref) {
const parent = evaluator.xref.fetch(this.parent); const parent = evaluator.xref.fetch(this.parent);
let parentTransform = null;
if (encrypt) {
parentTransform = encrypt.createCipherTransform(
this.parent.num,
this.parent.gen
);
}
parent.set("V", name); parent.set("V", name);
parentBuffer = [`${this.parent.num} ${this.parent.gen} obj\n`]; await writeObject(this.parent, parent, buffer, evaluator.xref);
await writeDict(parent, parentBuffer, parentTransform); parentData = buffer.join("");
parentBuffer.push("\nendobj\n"); buffer.length = 0;
} else if (this.parent instanceof Dict) { } else if (this.parent instanceof Dict) {
this.parent.set("V", name); this.parent.set("V", name);
} }
@ -3064,25 +3019,10 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
dict.set("MK", maybeMK); dict.set("MK", maybeMK);
} }
let originalTransform = null; await writeObject(this.ref, dict, buffer, evaluator.xref);
if (encrypt) {
originalTransform = encrypt.createCipherTransform(
this.ref.num,
this.ref.gen
);
}
const buffer = [`${this.ref.num} ${this.ref.gen} obj\n`];
await writeDict(dict, buffer, originalTransform);
buffer.push("\nendobj\n");
const newRefs = [{ ref: this.ref, data: buffer.join(""), xfa }]; const newRefs = [{ ref: this.ref, data: buffer.join(""), xfa }];
if (parentBuffer !== null) { if (parentData) {
newRefs.push({ newRefs.push({ ref: this.parent, data: parentData, xfa: null });
ref: this.parent,
data: parentBuffer.join(""),
xfa: null,
});
} }
return newRefs; return newRefs;

View File

@ -321,16 +321,7 @@ class Page {
const savedDict = pageDict.get("Annots"); const savedDict = pageDict.get("Annots");
pageDict.set("Annots", annotationsArray); pageDict.set("Annots", annotationsArray);
const buffer = []; const buffer = [];
await writeObject(this.ref, pageDict, buffer, this.xref);
let transform = null;
if (this.xref.encrypt) {
transform = this.xref.encrypt.createCipherTransform(
this.ref.num,
this.ref.gen
);
}
await writeObject(this.ref, pageDict, buffer, transform);
if (savedDict) { if (savedDict) {
pageDict.set("Annots", savedDict); pageDict.set("Annots", savedDict);
} }

View File

@ -25,7 +25,8 @@ import { SimpleDOMNode, SimpleXMLParser } from "./xml_parser.js";
import { BaseStream } from "./base_stream.js"; import { BaseStream } from "./base_stream.js";
import { calculateMD5 } from "./crypto.js"; import { calculateMD5 } from "./crypto.js";
async function writeObject(ref, obj, buffer, transform) { async function writeObject(ref, obj, buffer, { encrypt = null }) {
const transform = encrypt?.createCipherTransform(ref.num, ref.gen);
buffer.push(`${ref.num} ${ref.gen} obj\n`); buffer.push(`${ref.num} ${ref.gen} obj\n`);
if (obj instanceof Dict) { if (obj instanceof Dict) {
await writeDict(obj, buffer, transform); await writeDict(obj, buffer, transform);
@ -101,7 +102,7 @@ async function writeStream(stream, buffer, transform) {
} }
} }
if (transform !== null) { if (transform) {
string = transform.encryptString(string); string = transform.encryptString(string);
} }
@ -132,7 +133,7 @@ async function writeValue(value, buffer, transform) {
} else if (Array.isArray(value)) { } else if (Array.isArray(value)) {
await writeArray(value, buffer, transform); await writeArray(value, buffer, transform);
} else if (typeof value === "string") { } else if (typeof value === "string") {
if (transform !== null) { if (transform) {
value = transform.encryptString(value); value = transform.encryptString(value);
} }
buffer.push(`(${escapeString(value)})`); buffer.push(`(${escapeString(value)})`);
@ -253,14 +254,8 @@ async function updateAcroform({
dict.set("NeedAppearances", true); dict.set("NeedAppearances", true);
} }
const encrypt = xref.encrypt;
let transform = null;
if (encrypt) {
transform = encrypt.createCipherTransform(acroFormRef.num, acroFormRef.gen);
}
const buffer = []; const buffer = [];
await writeObject(acroFormRef, dict, buffer, transform); await writeObject(acroFormRef, dict, buffer, xref);
newRefs.push({ ref: acroFormRef, data: buffer.join("") }); newRefs.push({ ref: acroFormRef, data: buffer.join("") });
} }