Uploaded image for project: 'Python Driver'
  1. Python Driver
  2. PYTHON-2631

Add missing error message when raising InvalidBSON in C extensions

    • Type: Icon: Task Task
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 3.12, 3.11.4, 4.0
    • Affects Version/s: None
    • Component/s: BSON
    • None

      While reviewing the C extensions working on PYTHON-2621 I've found one place where we raise InvalidBSON('') with no error message. It's this check which happens when decoding a field with an invalid length from BSON:

          if (name_length > BSON_MAX_SIZE || position + name_length >= max) {
              PyObject* InvalidBSON = _error("InvalidBSON");
              if (InvalidBSON) {
                  PyErr_SetNone(InvalidBSON);
                  Py_DECREF(InvalidBSON);
              }
              return -1;
          }
      

      https://github.com/mongodb/mongo-python-driver/blob/3.11.3/bson/_cbsonmodule.c#L2621-L2627

      We should raise a better error here. Perhaps:

                  PyErr_SetString(InvalidBSON, "invalid field name");
      

      Here is an example:

      >>> decode(b'\x0b\x00\x00\x00\x02field\x00')
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 970, in decode
          return _bson_to_dict(data, codec_options)
      bson.errors.InvalidBSON
      

      The same BSON decoded without the C extensions yields this error:

      >>> decode(b'\x0b\x00\x00\x00\x02field\x00')
      Traceback (most recent call last):
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 485, in _bson_to_dict
          return _elements_to_dict(data, view, 4, end, opts)
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 471, in _elements_to_dict
          key, value, position = _element_to_dict(data, view, position, obj_end, opts)
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 446, in _element_to_dict
          value, position = _ELEMENT_GETTER[element_type](data, view, position,
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 211, in _get_string
          length = _UNPACK_INT_FROM(data, position)[0]
      struct.error: unpack_from requires a buffer of at least 15 bytes for unpacking 4 bytes at offset 11 (actual buffer size is 11)
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 970, in decode
          return _bson_to_dict(data, codec_options)
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 491, in _bson_to_dict
          reraise(InvalidBSON, exc_value, exc_tb)
        File "/Users/shane/git/mongo-python-driver/bson/py3compat.py", line 53, in reraise
          raise exctype(str(value)).with_traceback(trace)
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 485, in _bson_to_dict
          return _elements_to_dict(data, view, 4, end, opts)
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 471, in _elements_to_dict
          key, value, position = _element_to_dict(data, view, position, obj_end, opts)
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 446, in _element_to_dict
          value, position = _ELEMENT_GETTER[element_type](data, view, position,
        File "/Users/shane/git/mongo-python-driver/bson/__init__.py", line 211, in _get_string
          length = _UNPACK_INT_FROM(data, position)[0]
      bson.errors.InvalidBSON: unpack_from requires a buffer of at least 15 bytes for unpacking 4 bytes at offset 11 (actual buffer size is 11)
      

      This could be a contributing factor to PYTHON-2047.

            Assignee:
            shane.harvey@mongodb.com Shane Harvey
            Reporter:
            shane.harvey@mongodb.com Shane Harvey
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: