GranularityRounder tasserts on Infinity input via $bucketAuto

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Execution
    • ALL
    • 0
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      The GranularityRounder helpers (granularity_rounder_powers_of_two.cpp and granularity_rounder_preferred_numbers.cpp) do not reject non-finite (infinity) numeric input. When a user pipeline feeds Infinity into $bucketAuto with a granularity (e.g. POWERSOF2), execution reaches representAsChecked<int>(...) with a non-finite double, which trips a tassert (BF-44396).

      Reproducer

      db.fuzzer_coll.aggregate([
        {$sort: {_id: 1}},
        {$bucketAuto: {
           groupBy: {$trunc: {$numberDouble: "Infinity"}},
           buckets: 12,
           output: {num: {$max: {$bitOr: [1611, 46718, 89496]}}},
           granularity: "POWERSOF2"
        }}
      ])
      

      Stack

      representAsChecked<int,double>                       represent_as_util.h:43
      GranularityRounderPowersOfTwo::roundDown             granularity_rounder_powers_of_two.cpp:99
      DocumentSourceBucketAuto::populateNextBucket         document_source_bucket_auto.cpp:320
      DocumentSourceBucketAuto::doGetNext                  document_source_bucket_auto.cpp:111
      

      Tripwire: code 12961701 ("cannot represent value as target type").

      Root cause

      uassertNonNegativeNumber() in both granularity rounder files rejects non-numeric, NaN, and negative values, but not Infinity. Downstream, std::log2(Inf) = Inf, std::ceil(Inf) - 1 = Inf, and then representAsChecked<int>(Inf) fails. (Note: a plain static_cast<int>(Inf) is undefined behavior in C+ — the whole point of representAsChecked is to catch this.)

      Fix

      Extend uassertNonNegativeNumber in both files to also assert std::isfinite(number), converting this into a user-facing uassert with a clear message ("A granularity rounder cannot round infinity").

      Affected branches

      The missing infinity guard is old code, so v7.0, v8.0, v8.2, v8.3, and master all have the latent hole.

      Related

      BF-44396

            Assignee:
            Unassigned
            Reporter:
            Charlie Swanson
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: