Skip to content

$includeAndReturnOutput locals (resolved, captured, …) shadow variables in the included view #3518

Description

@bpamiri

Summary

Global.cfc's $includeAndReturnOutput() includes the view template inside its own function scope, so every bare local it declares is visible to the included template. The 4.1.0 rewrite introduced bare locals — local.resolved, includeState, captured, fallbacks, fbCount, fbIndex — where 4.0.5 used the collision-safe local.$wheels. Any app view that declares its own resolved (or captured / state / …) controller variable now resolves to the framework's local instead.

Reproduction

A controller action sets a resolved variable and calls renderView(action="index"), where the view does:

showResolved = StructKeyExists(variables, "resolved") && IsStruct(resolved);

StructKeyExists(variables, "resolved") is true (the controller's struct is there), but bare resolved — and therefore IsStruct(resolved) — resolves to the template-path string stored in local.resolved, so showResolved is false and the view silently renders the wrong branch.

Impact

Any app whose views use resolved, captured, fallbacks, includeState, state, or similar names breaks silently. This is the same shadowing class as #3053 (local.url in public/Application.cfc), here in the one framework function that includes user templates — so it can hit any app.

Proposed fix

$-prefix all locals in the function ($resolved, $captured, $includeState, $fallbacks, $fbCount, $fbIndex), matching the 4.0.5 convention. Happy to open a PR with the change and a pinning spec.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions