[406262] [xsl][validation] StackOverflow when checking for circular
includes on next level import
diff --git a/bundles/org.eclipse.wst.xsl.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.xsl.core/META-INF/MANIFEST.MF
index 3b5ed4f..5abf2bd 100644
--- a/bundles/org.eclipse.wst.xsl.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.xsl.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name.0
Bundle-SymbolicName: org.eclipse.wst.xsl.core;singleton:=true
-Bundle-Version: 1.1.300.qualifier
+Bundle-Version: 1.1.301.qualifier
Bundle-Activator: org.eclipse.wst.xsl.core.internal.XSLCorePlugin
Require-Bundle: org.apache.xalan;bundle-version="[2.7.1,2.8.0)",
org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
diff --git a/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/model/StylesheetModel.java b/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/model/StylesheetModel.java
index 339301e..098ad9d 100644
--- a/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/model/StylesheetModel.java
+++ b/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/model/StylesheetModel.java
@@ -16,6 +16,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.Stack;
import org.eclipse.core.resources.IFile;
import org.eclipse.wst.xsl.core.XSLCore;
@@ -195,6 +196,7 @@
for (Import inc : stylesheet.getImports()) {
handleInclude(inc);
}
+ circularReference = checkCycles();
if (Debug.debugXSLModel) {
long end = System.currentTimeMillis();
System.out
@@ -202,6 +204,36 @@
}
}
+ private boolean checkCycles() {
+ Set<IFile> seen = new HashSet<IFile>();
+ IFile mainFile = getStylesheet().getFile();
+ if (checkCycles(mainFile, seen)) return true;
+
+ // For the remaining files, assume
+ seen.add(mainFile);
+ for (IFile file : files) {
+ if (file.equals(mainFile)) continue;
+ if (checkCycles(file, seen)) return true;
+ }
+ return false;
+ }
+
+ public static boolean checkCycles(IFile included, Set<IFile> seen) {
+ if (seen.contains(included)) return true;
+ seen.add(included);
+
+ StylesheetModel includedModel = XSLCore.getInstance().getStylesheet(
+ included);
+
+ for (Include inc : includedModel.getIncludes()) {
+ IFile includedFile = inc.getHrefAsFile();
+ if (checkCycles(includedFile, seen)) return true;
+ }
+
+ seen.remove(included);
+ return false;
+ }
+
private void handleInclude(Include include) {
IFile file = include.getHrefAsFile();
@@ -209,12 +241,6 @@
return;
}
- if (stylesheet.getFile().equals(file) || files.contains(file)) {
- circularReference = true;
- return;
- } else if (isNestedInclude(include, stylesheet.getFile())) {
- circularReference = true;
- }
files.add(file);
StylesheetModel includedModel = XSLCore.getInstance().getStylesheet(
@@ -239,26 +265,6 @@
}
}
- /**
- * Is the current stylesheet nested in one of the included stylesheets
- *
- * @return
- */
- private boolean isNestedInclude(Include include, IFile compareTo) {
- StylesheetModel includedModel = XSLCore.getInstance().getStylesheet(
- include.getHrefAsFile());
-
- for (Include inc : includedModel.getIncludes()) {
- if (inc.getHrefAsFile().equals(compareTo)
- || isNestedInclude(inc, compareTo)) {
- return true;
- }
- }
-
- return false;
-
- }
-
@Override
public Type getModelType() {
return Type.STYLESHEET_MODEL;