From db811ac2bb50783c52876e1b53e8e4cb0d2e2302 Mon Sep 17 00:00:00 2001 From: Tom Gillespie Date: Wed, 27 Apr 2022 16:36:24 -0700 Subject: [PATCH] ttlser ListRanker fix infinite loop case for cyclical lists Any cyclical linked list would go infinite while traversing rdf:rest, this resolves the issue and provides a simplified and clear test case. --- ttlser/test/evil.ttl | 41 +++++++++++------------------------- ttlser/ttlser/serializers.py | 17 ++++++++++++++- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/ttlser/test/evil.ttl b/ttlser/test/evil.ttl index 823a2b6f..34d25cf4 100644 --- a/ttlser/test/evil.ttl +++ b/ttlser/test/evil.ttl @@ -1,35 +1,18 @@ -@prefix TEMP: . @prefix ilxtr: . -@prefix owl: . @prefix rdf: . -@prefix rdfs: . -TEMP:271 a owl:Class ; - rdfs:label "electrical stimulation technique" ; - owl:equivalentClass [ a owl:Class ; - owl:intersectionOf [ rdf:first ilxtr:technique ; - rdf:rest [ rdf:first [ a owl:Restriction ; - owl:onProperty ilxtr:hasPrimaryAspect ; - owl:someValuesFrom ] ; - rdf:rest _:sg_0_4, - _:sg_0_6 ] ] ] . +ilxtr:b0 rdf:first ilxtr:x ; + rdf:rest + ilxtr:b1 . -_:sg_0_5 a owl:Restriction ; - owl:onProperty ilxtr:hasProbe, - ilxtr:hasSomething ; - owl:someValuesFrom TEMP:272, - ilxtr:electricalField . +ilxtr:b1 rdf:first ilxtr:y ; + rdf:rest + ilxtr:b2 . -_:sg_0_7 a owl:Restriction ; - owl:onProperty ilxtr:hasProbe, - ilxtr:hasSomething ; - owl:someValuesFrom TEMP:272, - ilxtr:electricalField . +ilxtr:b2 rdf:first ilxtr:z ; + rdf:rest + ilxtr:b3 . -_:sg_0_4 rdf:first _:sg_0_5 ; - rdf:rest _:sg_0_6, - () . - -_:sg_0_6 rdf:first _:sg_0_7 ; - rdf:rest _:sg_0_4, - () . +ilxtr:b3 rdf:first ilxtr:e ; + rdf:rest + ilxtr:b1 . diff --git a/ttlser/ttlser/serializers.py b/ttlser/ttlser/serializers.py index 326eaa89..a425f454 100644 --- a/ttlser/ttlser/serializers.py +++ b/ttlser/ttlser/serializers.py @@ -102,10 +102,25 @@ def __init__(self, node, serializer): self.vals = [] self.nodes = [] # list helper nodes l = self.node - while l: + previous = set() + #count = 0 + #enough = 99999 + while l: # infinite loop posibility item = self.serializer.store.value(l, RDF.first) self.add(item, l) + # if there is a self referential node anywhere in a list + # beyond the first element this goes infinite + previous.add(l) l = self.serializer.store.value(l, RDF.rest) + if l in previous: # cyclical reference case + break + # XXX beware lists where there are multiple rdf:rest + # values for a node, I don't think they will break + # serialization, but they may produce unexpected ranking + #count += 1 + #if count > enough: + #print(self.serializer.store) + #breakpoint() self.vis_vals = [v for v in self.vals if not isinstance(v, BNode)] self.bvals = [v for v in self.vals if isinstance(v, BNode)]