36 lines
2 KiB
Diff
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 );
|
|
}
|
|
}
|