mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-22 16:18:08 +02:00
XFA - Overwrite AcroForm dictionary when saving if no datasets in XFA (bug 1720179)
- aims to fix https://bugzilla.mozilla.org/show_bug.cgi?id=1720179 - in some pdfs the XFA array in AcroForm dictionary doesn't contain an entry for 'datasets' (which contains saved data), so basically this patch allows to overwrite the AcroForm dictionary with an updated XFA array when doing an incremental update.
This commit is contained in:
parent
804abb3786
commit
77b9657e57
4 changed files with 140 additions and 4 deletions
|
@ -130,6 +130,11 @@ class Catalog {
|
|||
return shadow(this, "acroForm", acroForm);
|
||||
}
|
||||
|
||||
get acroFormRef() {
|
||||
const value = this._catDict.getRaw("AcroForm");
|
||||
return shadow(this, "acroFormRef", isRef(value) ? value : null);
|
||||
}
|
||||
|
||||
get metadata() {
|
||||
const streamRef = this._catDict.getRaw("Metadata");
|
||||
if (!isRef(streamRef)) {
|
||||
|
|
|
@ -573,6 +573,7 @@ class WorkerMessageHandler {
|
|||
const promises = [
|
||||
pdfManager.onLoadedStream(),
|
||||
pdfManager.ensureCatalog("acroForm"),
|
||||
pdfManager.ensureCatalog("acroFormRef"),
|
||||
pdfManager.ensureDoc("xref"),
|
||||
pdfManager.ensureDoc("startXRef"),
|
||||
];
|
||||
|
@ -597,6 +598,7 @@ class WorkerMessageHandler {
|
|||
return Promise.all(promises).then(function ([
|
||||
stream,
|
||||
acroForm,
|
||||
acroFormRef,
|
||||
xref,
|
||||
startXRef,
|
||||
...refs
|
||||
|
@ -621,15 +623,22 @@ class WorkerMessageHandler {
|
|||
}
|
||||
}
|
||||
|
||||
const xfa = (acroForm instanceof Dict && acroForm.get("XFA")) || [];
|
||||
const xfa = (acroForm instanceof Dict && acroForm.get("XFA")) || null;
|
||||
let xfaDatasets = null;
|
||||
let hasDatasets = false;
|
||||
if (Array.isArray(xfa)) {
|
||||
for (let i = 0, ii = xfa.length; i < ii; i += 2) {
|
||||
if (xfa[i] === "datasets") {
|
||||
xfaDatasets = xfa[i + 1];
|
||||
acroFormRef = null;
|
||||
hasDatasets = true;
|
||||
}
|
||||
}
|
||||
if (xfaDatasets === null) {
|
||||
xfaDatasets = xref.getNewRef();
|
||||
}
|
||||
} else {
|
||||
acroFormRef = null;
|
||||
// TODO: Support XFA streams.
|
||||
warn("Unsupported XFA type.");
|
||||
}
|
||||
|
@ -666,6 +675,9 @@ class WorkerMessageHandler {
|
|||
newRefs,
|
||||
xref,
|
||||
datasetsRef: xfaDatasets,
|
||||
hasDatasets,
|
||||
acroFormRef,
|
||||
acroForm,
|
||||
xfaData,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -146,10 +146,54 @@ function writeXFADataForAcroform(str, newRefs) {
|
|||
return buffer.join("");
|
||||
}
|
||||
|
||||
function updateXFA(xfaData, datasetsRef, newRefs, xref) {
|
||||
if (datasetsRef === null || xref === null) {
|
||||
function updateXFA({
|
||||
xfaData,
|
||||
datasetsRef,
|
||||
hasDatasets,
|
||||
acroFormRef,
|
||||
acroForm,
|
||||
newRefs,
|
||||
xref,
|
||||
xrefInfo,
|
||||
}) {
|
||||
if (xref === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasDatasets) {
|
||||
if (!acroFormRef) {
|
||||
warn("XFA - Cannot save it");
|
||||
return;
|
||||
}
|
||||
|
||||
// We've a XFA array which doesn't contain a datasets entry.
|
||||
// So we'll update the AcroForm dictionary to have an XFA containing
|
||||
// the datasets.
|
||||
const oldXfa = acroForm.get("XFA");
|
||||
const newXfa = oldXfa.slice();
|
||||
newXfa.splice(2, 0, "datasets");
|
||||
newXfa.splice(3, 0, datasetsRef);
|
||||
|
||||
acroForm.set("XFA", newXfa);
|
||||
|
||||
const encrypt = xref.encrypt;
|
||||
let transform = null;
|
||||
if (encrypt) {
|
||||
transform = encrypt.createCipherTransform(
|
||||
acroFormRef.num,
|
||||
acroFormRef.gen
|
||||
);
|
||||
}
|
||||
|
||||
const buffer = [`${acroFormRef.num} ${acroFormRef.gen} obj\n`];
|
||||
writeDict(acroForm, buffer, transform);
|
||||
buffer.push("\n");
|
||||
|
||||
acroForm.set("XFA", oldXfa);
|
||||
|
||||
newRefs.push({ ref: acroFormRef, data: buffer.join("") });
|
||||
}
|
||||
|
||||
if (xfaData === null) {
|
||||
const datasets = xref.fetchIfRef(datasetsRef);
|
||||
xfaData = writeXFADataForAcroform(datasets.getString(), newRefs);
|
||||
|
@ -178,9 +222,21 @@ function incrementalUpdate({
|
|||
newRefs,
|
||||
xref = null,
|
||||
datasetsRef = null,
|
||||
hasDatasets = false,
|
||||
acroFormRef = null,
|
||||
acroForm = null,
|
||||
xfaData = null,
|
||||
}) {
|
||||
updateXFA(xfaData, datasetsRef, newRefs, xref);
|
||||
updateXFA({
|
||||
xfaData,
|
||||
datasetsRef,
|
||||
hasDatasets,
|
||||
acroFormRef,
|
||||
acroForm,
|
||||
newRefs,
|
||||
xref,
|
||||
xrefInfo,
|
||||
});
|
||||
|
||||
const newXref = new Dict(null);
|
||||
const refForXrefTable = xrefInfo.newRef;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue