Skip to content

Commit

Permalink
GH-4833: Copy triple structures to avoid infinite loops
Browse files Browse the repository at this point in the history
The current implementation of the algorithm for the hierachical JSON-LD
output changes references of the triples stored in `List`s and keeps
adding these references to the output. This can leed to infinite loops
when traversing the result. Making copies of the contained lists avoids
this.
  • Loading branch information
domkun authored and JervenBolleman committed Nov 25, 2023
1 parent cdb38ad commit a1973a3
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,7 @@
*******************************************************************************/
package org.eclipse.rdf4j.rio.jsonld;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -127,7 +121,16 @@ private static Object expandContextInDepth(Object input) {
if (graph.containsKey(objectsPredId) && !currentNode.get(ID).equals(objectsPredId)
&& !currentTreeNode.hasPassedThrough(objectsPredId)) {
children.add(objectsPredId);
objectsPredSubjPairs.set(i, (Map<String, Object>) graph.get(objectsPredId));
Map<String, Object> tuples = (Map<String, Object>) graph.get(objectsPredId);
Map<String, Object> copiedTuples = tuples.entrySet().stream().map(tuple -> {
Map.Entry<String, Object> entry = new AbstractMap.SimpleEntry<>(tuple);
if (tuple.getValue() instanceof List) {
List<Object> copy = new ArrayList<>((Collection<?>) tuple.getValue());
entry.setValue(copy);
}
return entry;
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
objectsPredSubjPairs.set(i, copiedTuples);
frontier.add(new TreeNode(objectsPredSubjPairs.get(i), currentTreeNode));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,35 @@ public void testOrderDuplicatedChild() throws IOException {
verifyOutput();
}

/**
*
* @throws IOException
* @see <a href="https://github.com/eclipse-rdf4j/rdf4j/issues/4833s">GH-4833</a>
*/
@Test
public void testMultipleLoops() throws IOException {
addStatement(vf.createIRI("sch:node1"), vf.createIRI("sch:pred1"), vf.createIRI("sch:node2"));

addStatement(vf.createIRI("sch:node2"), vf.createIRI("sch:pred2"), vf.createIRI("sch:node3"));
addStatement(vf.createIRI("sch:node2"), vf.createIRI("sch:pred2"), vf.createIRI("sch:node4"));
addStatement(vf.createIRI("sch:node2"), vf.createIRI("sch:pred2"), vf.createIRI("sch:node5"));

addStatement(vf.createIRI("sch:node2"), vf.createIRI("sch:pred3"), vf.createIRI("sch:node1"));

addStatement(vf.createIRI("sch:node3"), vf.createIRI("sch:pred4"), vf.createIRI("sch:node2"));
addStatement(vf.createIRI("sch:node3"), vf.createIRI("sch:pred5"), vf.createIRI("sch:node6"));

addStatement(vf.createIRI("sch:node4"), vf.createIRI("sch:pred4"), vf.createIRI("sch:node2"));

addStatement(vf.createIRI("sch:node5"), vf.createIRI("sch:pred4"), vf.createIRI("sch:node2"));
addStatement(vf.createIRI("sch:node5"), vf.createIRI("sch:pred5"), vf.createIRI("sch:node6"));

addStatement(vf.createIRI("sch:node6"), vf.createIRI("sch:pred6"), vf.createIRI("sch:node3"));

verifyOutput();

}

private void addStatement(Resource subject, IRI predicate, Value object, Resource context) {
model.add(vf.createStatement(subject, predicate, object, context));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[ {
"@id" : "sch:node2",
"sch:pred2" : [ {
"@id" : "sch:node3",
"sch:pred4" : [ {
"@id" : "sch:node2"
} ],
"sch:pred5" : [ {
"@id" : "sch:node6",
"sch:pred6" : [ {
"@id" : "sch:node3"
} ]
} ]
}, {
"@id" : "sch:node4",
"sch:pred4" : [ {
"@id" : "sch:node2"
} ]
}, {
"@id" : "sch:node5",
"sch:pred4" : [ {
"@id" : "sch:node2"
} ],
"sch:pred5" : [ {
"@id" : "sch:node6",
"sch:pred6" : [ {
"@id" : "sch:node3",
"sch:pred4" : [ {
"@id" : "sch:node2"
} ],
"sch:pred5" : [ {
"@id" : "sch:node6"
} ]
} ]
} ]
} ],
"sch:pred3" : [ {
"@id" : "sch:node1",
"sch:pred1" : [ {
"@id" : "sch:node2"
} ]
} ]
} ]

0 comments on commit a1973a3

Please sign in to comment.