This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ant-antlibs-cyclonedx.git
The following commit(s) were added to refs/heads/main by this push:
new 69dd122 properly check for circular references
69dd122 is described below
commit 69dd1221eeaac249f8c6d61c5d7815b824b114ae
Author: Stefan Bodewig <[email protected]>
AuthorDate: Fri May 8 22:50:42 2026 +0200
properly check for circular references
---
src/main/org/apache/ant/cyclonedx/Component.java | 21 ++++++++++++++++++++-
src/tests/antunit/componentbom-test.xml | 14 ++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/src/main/org/apache/ant/cyclonedx/Component.java
b/src/main/org/apache/ant/cyclonedx/Component.java
index c34f820..abe5a3e 100644
--- a/src/main/org/apache/ant/cyclonedx/Component.java
+++ b/src/main/org/apache/ant/cyclonedx/Component.java
@@ -9,9 +9,11 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Stack;
import java.util.stream.Collectors;
import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.types.DataType;
import org.apache.tools.ant.types.Resource;
@@ -229,6 +231,7 @@ public class Component extends DataType {
public void addComponent(Component c) {
checkChildrenAllowed();
nestedComponents.add(c);
+ setChecked(false);
}
public List<Component> getNestedComponents() {
@@ -525,7 +528,7 @@ public class Component extends DataType {
file = fp.getFile();
}
if (file == null || !file.isFile()) {
- throw new BuildException("component resource doesn't provide a
file");
+ throw new BuildException("component resource " + resource + "
doesn't provide a file");
}
component.setHashes(BomUtils.calculateHashes(file, bomVersion));
@@ -609,4 +612,20 @@ public class Component extends DataType {
protected Component getRef() {
return getCheckedRef(Component.class);
}
+
+ @Override
+ protected synchronized void dieOnCircularReference(Stack<Object> stk,
Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (Component c : nestedComponents) {
+ pushAndInvokeCircularReferenceCheck(c, stk, p);
+ }
+ setChecked(true);
+ }
+ }
}
diff --git a/src/tests/antunit/componentbom-test.xml
b/src/tests/antunit/componentbom-test.xml
index 0679bdb..5032b50 100644
--- a/src/tests/antunit/componentbom-test.xml
+++ b/src/tests/antunit/componentbom-test.xml
@@ -199,6 +199,20 @@
</au:expectfailure>
</target>
+ <target name="testComponentsDetectCircularReferences">
+ <au:expectfailure expectedMessage="This data type contains a circular
reference"
+ xmlns:au="antlib:org.apache.ant.antunit">
+ <cdx:componentbom outputdirectory="${output}" format="xml"
+ xmlns:cdx="antlib:org.apache.ant.cyclonedx">
+ <component name="level1" id="top">
+ <component name="level2">
+ <component refid="top"/>
+ </component>
+ </component>
+ </cdx:componentbom>
+ </au:expectfailure>
+ </target>
+
<target name="testMinimalComponentData">
<cdx:componentbom outputdirectory="${output}" format="xml"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">