java-topology/defects/hibernate-orm-0001/patch/hibernate-orm-0001-fk-secondpass-list-contains.patch

36 lines
2 KiB
Diff

# UNDF: UNDF-2026-000000828
# UNDF:
# Defect: hibernate-orm-0001
# Component: org.hibernate.boot.internal.InFlightMetadataCollectorImpl
# Pattern: CWE-407 — List.contains() in recursive FK ordering
# Severity: HIGH
# Complexity: O(N²) in buildRecursiveOrderedFkSecondPasses → O(N) with LinkedHashSet
# Description: buildRecursiveOrderedFkSecondPasses recursively walks FK
# dependencies and calls orderedFkSecondPasses.contains(fkSecondPass) on
# an ArrayList before inserting at position 0 (also O(N) for the shift).
# With N foreign keys, the contains check alone is O(N²). Fix: maintain
# a companion HashSet for O(1) membership test. The add(0, ...) shift
# cost remains but the contains() becomes O(1).
--- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java
@@ -1835,12 +1835,14 @@
private void buildRecursiveOrderedFkSecondPasses(
List<FkSecondPass> orderedFkSecondPasses,
+ Set<FkSecondPass> orderedFkSecondPassSet,
Map<String, Set<FkSecondPass>> isADependencyOf,
String startTable,
String currentTable) {
final Set<FkSecondPass> dependencies = isADependencyOf.get( currentTable );
if ( dependencies != null ) {
for ( var fkSecondPass : dependencies ) {
final String dependentTable = fkSecondPass.getValue().getTable().getQualifiedTableName().render();
if ( dependentTable.compareTo( startTable ) != 0 ) {
- buildRecursiveOrderedFkSecondPasses( orderedFkSecondPasses, isADependencyOf, startTable, dependentTable );
+ buildRecursiveOrderedFkSecondPasses( orderedFkSecondPasses, orderedFkSecondPassSet, isADependencyOf, startTable, dependentTable );
}
- if ( !orderedFkSecondPasses.contains( fkSecondPass ) ) {
+ if ( !orderedFkSecondPassSet.contains( fkSecondPass ) ) {
+ orderedFkSecondPassSet.add( fkSecondPass );
orderedFkSecondPasses.add( 0, fkSecondPass );
}
}