LINQ provider: C# lambda parameter names can shadow $reduce/$map/$filter built-in variables

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Declined
    • Priority: Unknown
    • None
    • Affects Version/s: None
    • Component/s: LINQ3
    • None
    • None
    • Dotnet Drivers
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      The LINQ provider uses C# lambda parameter names directly as MongoDB aggregation variable names (via NameGenerator.GetVarName). When a user's lambda parameter name collides with a built-in $reduce variable (value, this), the generated arrayIndexAs (or as in $map/$filter) shadows the built-in, producing silently wrong results.

      Reproduction

      // Data: { A: [1, 2, 3, 4, 5] }
      // Expected: [4, 5] (skip first 3 by index)
      // Actual: null (query returns null due to $$value shadowing)
      collection.AsQueryable()
          .Select(x => x.A.SkipWhile((x, value) => value < 3).ToArray());
      

      The generated $reduce contains arrayIndexAs: "value", which shadows $$value (the accumulator). References to $$value.predicate and $$value.count in the $switch branches then read from the index integer instead of the accumulator document, returning null.

      Changing the parameter name to anything other than value (e.g., idx) produces correct results, confirming the issue is purely the name collision.

      Affected operators

      • $reduce: arrayIndexAs can shadow $$value or $$this
      • $map: as could shadow $$this if a user names their parameter this (pre-existing, not introduced by CSHARP-5973)
      • $filter: same as $map

      Suggested fix

      In the translator, instead of using the C# parameter name directly for arrayIndexAs, generate a unique safe name via the NameGenerator counter (e.g., v__0). Alternatively, validate that the chosen name doesn't conflict with value, this, or any other in-scope variable, and fall back to a generated name if it does.

      Discovered during

      CSHARP-5973 (SkipWhile/TakeWhile index overloads)

            Assignee:
            Unassigned
            Reporter:
            Adelin Mbida Owona
            None
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: