Skip to content

Commit

Permalink
Merge pull request #13966 from calixteman/no_ns
Browse files Browse the repository at this point in the history
XFA - Created data node mustn't belong to datasets namespace
  • Loading branch information
brendandahl authored Sep 3, 2021
2 parents d9d3115 + 57ae3a5 commit a8ce15a
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 8 deletions.
17 changes: 12 additions & 5 deletions src/core/xfa/bind.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import { createDataNode, searchNode } from "./som.js";
import { NamespaceIds } from "./namespaces.js";
import { warn } from "../../shared/util.js";

const NS_DATASETS = NamespaceIds.datasets.id;

function createText(content) {
const node = new Text({});
node[$content] = content;
Expand Down Expand Up @@ -501,8 +503,12 @@ class Binder {
if (dataChildren.length > 0) {
this._bindOccurrences(child, [dataChildren[0]], null);
} else if (this.emptyMerge) {
const nsId =
dataNode[$namespaceId] === NS_DATASETS
? -1
: dataNode[$namespaceId];
const dataChild = (child[$data] = new XmlObject(
dataNode[$namespaceId],
nsId,
child.name || "root"
));
dataNode[$appendChild](dataChild);
Expand Down Expand Up @@ -625,10 +631,11 @@ class Binder {
if (!match) {
// We're in matchTemplate mode so create a node in data to reflect
// what we've in template.
match = child[$data] = new XmlObject(
dataNode[$namespaceId],
child.name
);
const nsId =
dataNode[$namespaceId] === NS_DATASETS
? -1
: dataNode[$namespaceId];
match = child[$data] = new XmlObject(nsId, child.name);
if (this.emptyMerge) {
match[$consumed] = true;
}
Expand Down
5 changes: 4 additions & 1 deletion src/core/xfa/som.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
XFAObjectArray,
XmlObject,
} from "./xfa_object.js";
import { NamespaceIds } from "./namespaces.js";
import { warn } from "../../shared/util.js";

const namePattern = /^[^.[]+/;
Expand Down Expand Up @@ -51,6 +52,7 @@ const shortcuts = new Map([
]);

const somCache = new WeakMap();
const NS_DATASETS = NamespaceIds.datasets.id;

function parseIndex(index) {
index = index.trim();
Expand Down Expand Up @@ -261,7 +263,8 @@ function createNodes(root, path) {
let node = null;
for (const { name, index } of path) {
for (let i = 0, ii = !isFinite(index) ? 0 : index; i <= ii; i++) {
node = new XmlObject(root[$namespaceId], name);
const nsId = root[$namespaceId] === NS_DATASETS ? -1 : root[$namespaceId];
node = new XmlObject(nsId, name);
root[$appendChild](node);
}

Expand Down
7 changes: 5 additions & 2 deletions src/core/xfa/xfa_object.js
Original file line number Diff line number Diff line change
Expand Up @@ -976,16 +976,19 @@ class XmlObject extends XFAObject {
this[$content] = value.toString();
}

[$dump]() {
[$dump](hasNS = false) {
const dumped = Object.create(null);
if (hasNS) {
dumped.$ns = this[$namespaceId];
}
if (this[$content]) {
dumped.$content = this[$content];
}
dumped.$name = this[$nodeName];

dumped.children = [];
for (const child of this[_children]) {
dumped.children.push(child[$dump]());
dumped.children.push(child[$dump](hasNS));
}

dumped.attributes = Object.create(null);
Expand Down
61 changes: 61 additions & 0 deletions test/unit/xfa_parser_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,67 @@ describe("XFAParser", function () {
expect(searchNode(data, data, "A")[0][$dump]()).toEqual(expected);
});

it("should make a basic binding and create a non-existing node with namespaceId equal to -1", 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 name="A">
<subform name="B">
<field name="C">
</field>
<field name="D">
<value>
<text>foobar</text>
</value>
</field>
</subform>
</subform>
</template>
</xdp:xdp>
`;
const root = new XFAParser().parse(xml);
const binder = new Binder(root);
const form = binder.bind();
const data = binder.getData();

expect(
searchNode(form, form, "A.B.D.value.text")[0][$dump]().$content
).toBe("foobar");

// Created nodes mustn't belong to xfa:datasets namespace.
const expected = {
$name: "A",
$ns: -1,
attributes: {},
children: [
{
$name: "B",
$ns: -1,
attributes: {},
children: [
{
$name: "C",
$ns: -1,
attributes: {},
children: [],
},
{
$name: "D",
$ns: -1,
attributes: {},
children: [],
},
],
},
],
};

expect(searchNode(data, data, "A")[0][$dump](/* hasNS */ true)).toEqual(
expected
);
});

it("should make another basic binding", function () {
const xml = `
<?xml version="1.0"?>
Expand Down

0 comments on commit a8ce15a

Please sign in to comment.