From 5dc7f4ade8c9407d8ec947d536332324c438abe4 Mon Sep 17 00:00:00 2001
From: Calixte Denizet <calixte.denizet@gmail.com>
Date: Sun, 6 Jun 2021 16:28:22 +0200
Subject: [PATCH] XFA - CDATA can be xml so parse it when required
---
src/core/xfa/parser.js | 9 +++++++++
src/core/xfa/template.js | 5 +++++
src/core/xfa/xfa_object.js | 6 ++++++
test/unit/xfa_parser_spec.js | 32 ++++++++++++++++++++++++++++++++
4 files changed, 52 insertions(+)
diff --git a/src/core/xfa/parser.js b/src/core/xfa/parser.js
index 326cca0a6..2c2c97289 100644
--- a/src/core/xfa/parser.js
+++ b/src/core/xfa/parser.js
@@ -16,7 +16,9 @@
import {
$acceptWhitespace,
$clean,
+ $content,
$finalize,
+ $isCDATAXml,
$nsAttributes,
$onChild,
$onText,
@@ -150,6 +152,13 @@ class XFAParser extends XMLParserBase {
onEndElement(name) {
const node = this._current;
+ if (node[$isCDATAXml]() && typeof node[$content] === "string") {
+ const parser = new XFAParser();
+ const root = parser.parse(node[$content]);
+ node[$content] = null;
+ node[$onChild](root);
+ }
+
node[$finalize]();
this._current = this._stack.pop();
if (this._current[$onChild](node)) {
diff --git a/src/core/xfa/template.js b/src/core/xfa/template.js
index 1906bb1de..794c684a7 100644
--- a/src/core/xfa/template.js
+++ b/src/core/xfa/template.js
@@ -29,6 +29,7 @@ import {
$hasItem,
$hasSettableValue,
$ids,
+ $isCDATAXml,
$isTransparent,
$namespaceId,
$nodeName,
@@ -1746,6 +1747,10 @@ class ExData extends ContentObject {
this.usehref = attributes.usehref || "";
}
+ [$isCDATAXml]() {
+ return this.contentType === "text/html";
+ }
+
[$onChild](child) {
if (
this.contentType === "text/html" &&
diff --git a/src/core/xfa/xfa_object.js b/src/core/xfa/xfa_object.js
index 1234ae91e..685b805eb 100644
--- a/src/core/xfa/xfa_object.js
+++ b/src/core/xfa/xfa_object.js
@@ -51,6 +51,7 @@ const $hasSettableValue = Symbol();
const $ids = Symbol();
const $indexOf = Symbol();
const $insertAt = Symbol();
+const $isCDATAXml = Symbol();
const $isDataValue = Symbol();
const $isDescendent = Symbol();
const $isTransparent = Symbol();
@@ -148,6 +149,10 @@ class XFAObject {
return false;
}
+ [$isCDATAXml]() {
+ return false;
+ }
+
[$setId](ids) {
if (this.id && this[$namespaceId] === NamespaceIds.template.id) {
ids.set(this.id, this);
@@ -970,6 +975,7 @@ export {
$ids,
$indexOf,
$insertAt,
+ $isCDATAXml,
$isDataValue,
$isDescendent,
$isTransparent,
diff --git a/test/unit/xfa_parser_spec.js b/test/unit/xfa_parser_spec.js
index d080a870c..a0f6f448d 100644
--- a/test/unit/xfa_parser_spec.js
+++ b/test/unit/xfa_parser_spec.js
@@ -256,6 +256,38 @@ describe("XFAParser", function () {
expect(root[$dump]()).toEqual(expected);
});
+ it("should parse a xfa document and parse CDATA when needed", function () {
+ const xml = `
+<?xml version="1.0"?>
+<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
+ <template xmlns="http://www.xfa.org/schema/xfa-template/3.3">
+ <subform>
+ <field>
+ <extras>
+ <exData contentType="text/html" name="foo">
+ <![CDATA[<body xmlns="http://www.w3.org/1999/xhtml">
+ <span>hello</span></body>]]>
+ </exData>
+ </extra>
+ </field>
+ </subform>
+ </template>
+</xdp:xdp>
+ `;
+ const root = new XFAParser().parse(xml);
+ const exdata = searchNode(root, root, "foo")[0];
+ const body = exdata[$dump]().$content[$dump]();
+ const expected = {
+ $name: "body",
+ attributes: {},
+ children: [
+ { $content: "hello", $name: "span", attributes: {}, children: [] },
+ ],
+ };
+
+ expect(body).toEqual(expected);
+ });
+
it("should parse a xfa document and apply some prototypes", function () {
const xml = `
<?xml version="1.0"?>