Investigate and handle invalid JS Date values (NaN) during BSON serialization

XMLWordPrintableJSON

    • Query Integration
    • ALL
    • None
    • None
    • None
    • None
    • None
    • None
    • None

       

      {{h2. Overview

      When a JavaScript Date object has an invalid value — constructed from a non-parseable string (e.g. new Date("foo")) or an out-of-range integer (e.g. new Date(8640000000000001)) — getTime() returns NaN. During JS-to-BSON serialization in ValueWriter, JS::ToInt64(NaN) evaluates to 0 per ECMAScript spec, causing the date to be silently stored as epoch 0 (1970-01-01T00:00:00Z) with no error or warning.

      Current Behavior

      JS Expression getTime() BSON result
      new Date("foo") NaN epoch 0 (silent)
      new Date(8640000000000001) NaN epoch 0 (silent)
      new Date(-8640000000000001) NaN epoch 0 (silent)
      NumberLong(NaN) n/a throws BadValue

      The inconsistency with NumberLong is notable: both are stored as int64_t milliseconds in BSON, but NumberLong already rejects NaN via representAs<int64_t>() while Date silently coerces it to 0.

      This behavior is documented (but not enforced as correct) in jstests/core/query/map_reduce/constructors.js, which explicitly marks Date("foo") as a "valid constructor" in mapReduce and $where contexts.

      Scope of Investigation

      • Decide whether invalid JS Date values should throw BadValue during BSON serialization, consistent with NumberLong.
      • Determine whether the fix should apply to all scripting contexts (legacy MozJS shell, mapReduce, \$where, \$function, WASM \$function) or be scoped to specific contexts.
      • If throwing, update jstests/core/query/map_reduce/constructors.js which marks Date("foo") as valid in mapReduce and \$where contexts.
      • Consider whether NumberInt (which also silently converts NaN to 0 via ECMAScript ToInt32 semantics) should be addressed in the same pass.

      Relevant Code

      • src/mongo/scripting/mozjs/common/valuewriter.cppJSProto_Date case in _writeObject()
      • src/mongo/scripting/mozjs/wasm/bridge/bridge_test.cppReturnDateBeyondMaxBoundary, ReturnDateBeyondMinBoundary, {
        Unknown macro: {ReturnDateFromInvalidString}

        }

      • jstests/core/query/map_reduce/constructors.jsdateConstructors valid list}}

            Assignee:
            Unassigned
            Reporter:
            Calvin Nguyen
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: