Skip to content

Commit e963902

Browse files
authored
Fix resolver logic for better context logic (#3915)
1 parent 84bf681 commit e963902

File tree

2 files changed

+274
-53
lines changed

2 files changed

+274
-53
lines changed

src/cfnlint/jsonschema/_resolvers_cfn.py

+31-13
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import json
99
from collections import deque
10+
from copy import deepcopy
1011
from typing import Any, Iterator
1112

1213
import regex as re
@@ -243,9 +244,9 @@ def find_in_map(validator: Validator, instance: Any) -> ResolutionResult:
243244
):
244245
yield (
245246
value,
246-
validator.evolve(
247-
context=validator.context.evolve(
248-
path=validator.context.path.evolve(
247+
second_v.evolve(
248+
context=second_v.context.evolve(
249+
path=second_v.context.path.evolve(
249250
value_path=deque(
250251
[
251252
"Mappings",
@@ -282,24 +283,28 @@ def get_azs(validator: Validator, instance: Any) -> ResolutionResult:
282283
yield AVAILABILITY_ZONES.get(instance), v, None
283284

284285

285-
def _join_expansion(validator: Validator, instances: Any) -> Iterator[Any]:
286+
def _join_expansion(
287+
validator: Validator, instances: Any
288+
) -> Iterator[tuple[Any, Validator]]:
286289
if len(instances) == 0:
287290
return
288291

289292
if len(instances) == 1:
290-
for value, _, _ in validator.resolve_value(instances[0]):
293+
for value, instance_validator, _ in validator.resolve_value(instances[0]):
291294
if not isinstance(value, (str, int, float, bool)):
292295
raise ValueError(f"Incorrect value type for {value!r}")
293-
yield [value]
296+
yield [value], instance_validator
294297
return
295298

296299
for value, instance_validator, errs in validator.resolve_value(instances[0]):
297300
if errs:
298301
continue
299302
if not isinstance(value, (str, int, float, bool)):
300303
raise ValueError(f"Incorrect value type for {value!r}")
301-
for values in _join_expansion(instance_validator, instances[1:]):
302-
yield [value] + values
304+
for values, expansion_validator in _join_expansion(
305+
instance_validator, instances[1:]
306+
):
307+
yield [value] + values, expansion_validator
303308

304309

305310
def join(validator: Validator, instance: Any) -> ResolutionResult:
@@ -312,12 +317,21 @@ def join(validator: Validator, instance: Any) -> ResolutionResult:
312317
for delimiter, delimiter_v, _ in validator.resolve_value(instance[0]):
313318
if not delimiter_v.is_type(delimiter, "string"):
314319
continue
315-
for values, values_v, _ in validator.resolve_value(instance[1]):
320+
for values, values_v, _ in delimiter_v.resolve_value(instance[1]):
316321
if not values_v.is_type(values, "array"):
317322
continue
318323
try:
319-
for value in _join_expansion(values_v, values):
320-
yield delimiter.join([str(v) for v in value]), values_v, None
324+
for value, expansion_validator in _join_expansion(values_v, values):
325+
# reset the value path because we could get a Ref value_path
326+
yield delimiter.join(
327+
[str(v) for v in value]
328+
), expansion_validator.evolve(
329+
context=expansion_validator.context.evolve(
330+
path=expansion_validator.context.path.evolve(
331+
value_path=deque([])
332+
)
333+
)
334+
), None
321335
except (ValueError, TypeError):
322336
return
323337

@@ -417,7 +431,7 @@ def sub(validator: Validator, instance: Any) -> ResolutionResult:
417431
return
418432

419433
string = instance[0]
420-
parameters = instance[1]
434+
parameters = deepcopy(instance[1])
421435
if not validator.is_type(string, "string"):
422436
return
423437
if not validator.is_type(parameters, "object"):
@@ -438,7 +452,11 @@ def sub(validator: Validator, instance: Any) -> ResolutionResult:
438452
ref_values=resolved_parameters,
439453
)
440454
)
441-
yield from _sub_string(resolved_validator, string)
455+
for sub_string, sub_validator, _ in _sub_string(resolved_validator, string):
456+
for key in instance[1].keys():
457+
sub_validator.context.ref_values.pop(key, None)
458+
459+
yield sub_string, sub_validator, None
442460

443461
return
444462

0 commit comments

Comments
 (0)