XFA - Avoid infinite loop when creating some nodes in data

This commit is contained in:
Calixte Denizet 2021-06-09 18:56:16 +02:00
parent 63bde1fcfe
commit cddc1d869d
3 changed files with 70 additions and 2 deletions

View File

@ -526,7 +526,10 @@ class Binder {
if (this._isConsumeData()) {
match[$consumed] = true;
}
match = [match];
// Don't bind the value in newly created node because it's empty.
this._bindElement(child, match);
continue;
} else {
if (this._isConsumeData()) {
// Filter out consumed nodes.

View File

@ -245,7 +245,7 @@ function searchNode(
function createNodes(root, path) {
let node = null;
for (const { name, index } of path) {
for (let i = 0; i <= index; i++) {
for (let i = 0, ii = !isFinite(index) ? 0 : index; i <= ii; i++) {
node = new XmlObject(root[$namespaceId], name);
root[$appendChild](node);
}

View File

@ -1289,5 +1289,70 @@ describe("XFAParser", function () {
)
).toEqual(["item1", "item2", "item1", "item2"]);
});
it("should make binding and create nodes in data with some bind tag", 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="root" mergeMode="matchTemplate">
<subform name="A">
<occur max="-1"/>
<bind ref="$.root.foo[*]" match="dataRef"/>
</subform>
<subform name="B">
<occur max="2"/>
<bind ref="$.root.bar[2]" match="dataRef"/>
</subform>
</subform>
</template>
<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
<xfa:data>
<root>
</root>
</xfa:data>
</xfa:datasets>
</xdp:xdp>
`;
const root = new XFAParser().parse(xml);
const binder = new Binder(root);
binder.bind();
const data = binder.getData();
const expected = {
$name: "root",
children: [
{
$name: "root",
children: [
{
$name: "foo",
children: [],
attributes: {},
},
{
$name: "bar",
children: [],
attributes: {},
},
{
$name: "bar",
children: [],
attributes: {},
},
{
$name: "bar",
children: [],
attributes: {},
},
],
attributes: {},
},
],
attributes: {},
};
expect(searchNode(data, data, "root")[0][$dump]()).toEqual(expected);
});
});
});