Uploaded image for project: 'C Driver'
  1. C Driver
  2. CDRIVER-3971

Error if appending an "lsid" field would introduce a duplicate field

    • Type: Icon: Improvement Improvement
    • Resolution: Unresolved
    • Priority: Icon: Unknown Unknown
    • None
    • Affects Version/s: None
    • Component/s: libmongoc
    • None

      Assuming an "lsid" field is not prohibited by the command, mongoc_cmd_parts_assemble will use bson_append_document to append an "lsid" field to a command document. In the unlikely event that the command document already has an "lsid" field, this will result in duplicate BSON fields in the outgoing command.

      In turn, this can be difficult to diagnose during debugging. Consider the following scenario in PHP, where an "lsid" string field as manually added to a "findAndModify" command:

      findAndModify command:
      {"findAndModify":"test","query":{"AAA":1},"update":{"$inc":{"AAA":1}},"upsert":true,"new":true,"txnNumber":1,"lsid":{"id":{"$binary":"gUD36a8WS+Sxxs2\/0122IQ==","$type":"04"}},"$db":"test","$clusterTime":{"clusterTime":{"$timestamp":{"t":1619799291,"i":1}},"signature":{"hash":{"$binary":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","$type":"00"},"keyId":0}}}
      
      
      Fatal error: Uncaught MongoDB\Driver\Exception\CommandException: BSON field 'OperationSessionInfo.lsid' is the wrong type 'string', expected type 'object'
      

      APM was used to log outgoing commands as JSON; however, the BSON document is first decoded into a PHP object before being provided to the APM callback. In that case, the last "lsid" field in the document wins.

      I don't think this would be as difficult to debug in libmongoc, since libbson's visitors (used to encode Extended JSON) would still visit both keys. In that case, we might expect to see both "lsid" fields in dumped JSON. For raw BSON iteration (e.g. bson_iter_find), I expect the first field in the document would be returned. In that case, debugging might only report the original "lsid" field from the user.

      In this example, I was purposely using an invalid "lsid" type to coerce an exception; however, another edge case would be providing a valid "lsid" in the command. In that case, libmongoc would still append its own "lsid" field. Presumably, the server would utilize the first "lsid" and ignore the second. This might satisfy the user's original intention since libmongoc's appended "lsid" would be ignored; however, libmongoc might go on to update the session that wasn't actually used for the operation (e.g. last used time).

      FYI: the Driver Sessions spec advises applications not to do this and suggests that behavior is undefined.

            Assignee:
            Unassigned Unassigned
            Reporter:
            jmikola@mongodb.com Jeremy Mikola
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: