From 31cb4bff0f12444315c4a7398787b2563132e163 Mon Sep 17 00:00:00 2001 From: Maxim Date: Thu, 2 May 2024 19:23:44 +0300 Subject: [PATCH] Fix infinite loop in table detection --- .../tables/TableClusterGap.java | 20 +++++++++++++++++++ .../tables/TableRecognizer.java | 1 + .../semanticalgorithms/utils/TableUtils.java | 14 ++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/tables/TableClusterGap.java b/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/tables/TableClusterGap.java index 45cfa6fd..2ed97c6e 100644 --- a/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/tables/TableClusterGap.java +++ b/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/tables/TableClusterGap.java @@ -1,5 +1,7 @@ package org.verapdf.wcag.algorithms.semanticalgorithms.tables; +import java.util.Objects; + public class TableClusterGap { private TableCluster link; private double gap; @@ -24,4 +26,22 @@ public void setGap(double gap) { public double getGap() { return gap; } + + @Override + public int hashCode() { + return Objects.hash(link.hashCode(), gap); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!super.equals(o)) { + return false; + } + TableClusterGap that = (TableClusterGap) o; + return Objects.equals(gap, that.gap) && + Objects.equals(link.getId(), that.getLink().getId()); + } } diff --git a/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/tables/TableRecognizer.java b/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/tables/TableRecognizer.java index bc9fdddc..4c4c5466 100644 --- a/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/tables/TableRecognizer.java +++ b/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/tables/TableRecognizer.java @@ -256,6 +256,7 @@ private List mergeInitialClusters(List> cluster if (j < clusterRow.size() - 1) { TableCluster nextCluster = clusterRow.get(j + 1); + //TODO: this gap could be negative, for example, if clusters intersect double gap = nextCluster.getLeftX() - cluster.getRightX(); cluster.getFirstRow().setRightGap(new TableClusterGap(nextCluster, gap)); nextCluster.getFirstRow().setLeftGap(new TableClusterGap(cluster, gap)); diff --git a/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/utils/TableUtils.java b/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/utils/TableUtils.java index b07439a0..50cc22b4 100644 --- a/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/utils/TableUtils.java +++ b/src/main/java/org/verapdf/wcag/algorithms/semanticalgorithms/utils/TableUtils.java @@ -101,15 +101,27 @@ public static boolean isWeakCluster(TableCluster cluster, List hea if (cluster.getHeader() != null) { return false; } - + Set visitedGaps = new HashSet<>(); TableClusterGap gap = cluster.getMinLeftGap(); while (gap != null && gap.getLink().getHeader() == null) { + if (visitedGaps.contains(gap)) { + gap = null; + break; + } + visitedGaps.add(gap); gap = gap.getLink().getMinLeftGap(); } TableCluster leftHeader = (gap == null) ? null : gap.getLink().getHeader(); + visitedGaps.clear(); + gap = cluster.getMinRightGap(); while (gap != null && gap.getLink().getHeader() == null) { + if (visitedGaps.contains(gap)) { + gap = null; + break; + } + visitedGaps.add(gap); gap = gap.getLink().getMinRightGap(); } TableCluster rightHeader = (gap == null) ? null : gap.getLink().getHeader();