@@ -185,43 +185,37 @@ public CspBuilder initialize(FetchDirective fetchDirective, String... values) {
185185 public List <Directive > getMergedDirectives () {
186186 List <Directive > result = new ArrayList <>();
187187 for (Map .Entry <String , Set <String >> entry : directives .entrySet ()) {
188- Set <String > effectiveValues = new HashSet <>();
189188 final String name = entry .getKey ();
190189
191- // Calculate inherited values from fallback chain
192190 if (FetchDirective .isFetchDirective (name )) {
191+ // Calculate inherited values from fallback chain
193192 FetchDirective current = FetchDirective .fromKey (name );
194-
195- // Check if this directive was initialized
196- boolean wasInitialized = initializedFDs .contains (current );
197-
198- // If NOT initialized, traverse fallback chain
199- if (!wasInitialized ) {
200- FetchDirective fallback = current .getFallback ();
201- while (fallback != null && !initializedFDs .contains (fallback )) {
202- fallback = fallback .getFallback ();
203- }
204- if (fallback == null ) {
205- // This could happen if nothing was initialized, in that case, fallback is default-src
206- fallback = FetchDirective .DEFAULT_SRC ;
207- }
208- // If we found an initialized fallback, inherit its values
209- if (directives .containsKey (fallback .toKey ())) {
210- effectiveValues .addAll (directives .get (fallback .toKey ()));
211- }
212- }
213-
214- effectiveValues .addAll (entry .getValue ());
215- result .add (new Directive (name , !wasInitialized , List .copyOf (effectiveValues )));
193+ result .add (new Directive (name , !initializedFDs .contains (current ), List .copyOf (getEffectiveValues (current ))));
216194 } else {
217195 // Non-fetch directives don't inherit
218- effectiveValues .addAll (entry .getValue ());
219- result .add (new Directive (name , null , List .copyOf (effectiveValues )));
196+ result .add (new Directive (name , null , List .copyOf (entry .getValue ())));
220197 }
221198 }
222199 return List .copyOf (result );
223200 }
224201
202+ private Set <String > getEffectiveValues (FetchDirective fetchDirective ) {
203+ if (fetchDirective == null ) {
204+ return Set .of ();
205+ }
206+
207+ final Set <String > currentDirectiveValues = directives .getOrDefault (fetchDirective .toKey (), Set .of ());
208+
209+ if (initializedFDs .contains (fetchDirective )) {
210+ return new HashSet <>(currentDirectiveValues );
211+ }
212+
213+ Set <String > effectiveValues = new HashSet <>();
214+ effectiveValues .addAll (getEffectiveValues (fetchDirective .getFallback ()));
215+ effectiveValues .addAll (currentDirectiveValues );
216+ return effectiveValues ;
217+ }
218+
225219 /**
226220 * Build the final CSP string. Any directives with no values left will have the 'none' value set.
227221 *
0 commit comments