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

Defective JSON string lets API bson_json_reader_read() crashed rather than returning error

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Critical - P2
    • Resolution: Fixed
    • Affects Version/s: 1.2.0, 1.3.0, 1.3.3
    • Fix Version/s: 1.4.0
    • Component/s: json, libbson
    • Labels:
      None
    • Environment:
      Linux CentOS 7, gcc 4.8.2, g++ 4.8.2
    • Sprint:
      C Driver 2016 sprint 3, C Driver 2016 sprint 4

      Description

      I using bson_json_reader_read() in my service to convert JSON string to BSON data.
      But if the JSON string has defective in MongoDB extended JSON fields, the function bson_json_reader_read() will crash rather than return error.

      These are three cases:
      ---------------------
      case 1
      ---------------------
      JSON string: {"$date" : { "$numberLong" : "1455853006123"}}

      screen output:
      src/bson/bson.c:1607 bson_append_date_time(): precondition failed: key

      crashed service stack by gdb:
      ---------------------
      #0 0x00007ffff5c485c9 in raise () from /lib64/libc.so.6
      #1 0x00007ffff5c49cd8 in abort () from /lib64/libc.so.6
      #2 0x00007ffff6efbd47 in bson_append_date_time () from /usr/lib64/libbson-1.0.so.0
      #3 0x00007ffff6f02fb3 in _bson_json_read_end_map () from /usr/lib64/libbson-1.0.so.0
      #4 0x00007ffff6f0a80d in yajl_do_parse () from /usr/lib64/libbson-1.0.so.0
      #5 0x00007ffff6f0345e in bson_json_reader_read () from /usr/lib64/libbson-1.0.so.0
      #6 0x000000000044066f in MongoDBClient::Json2Bson (
      json="{\"$date\" : { \"$numberLong\" : \"1455853006123\"}}") at MongoDBClient.cpp:99
      #7 0x0000000000444d0b in MongoDBProxyQuestProcessor::singleFind (this=this@entry=0xf8c018, args=
      std::shared_ptr (count 4, weak 0) 0xf4ce00, quest=std::shared_ptr (count 7, weak 0) 0xf4d580,
      hintId=hintId@entry=0, onlyHashTable=onlyHashTable@entry=false)
      at MongoDBProxyQuestProcessor.cpp:136

      ---------------------
      case 2
      ---------------------
      JSON string: {"$oid" : { "$numberLong" : "1455853006123"}}

      screen output:
      src/bson/bson.c:1144 bson_append_int64(): precondition failed: key

      crashed service stack by gdb:
      ---------------------
      #0 0x00007ffff5c485c9 in raise () from /lib64/libc.so.6
      #1 0x00007ffff5c49cd8 in abort () from /lib64/libc.so.6
      #2 0x00007ffff6efb457 in bson_append_int64 () from /usr/lib64/libbson-1.0.so.0
      #3 0x00007ffff6f0320c in _bson_json_read_end_map () from /usr/lib64/libbson-1.0.so.0
      #4 0x00007ffff6f0a80d in yajl_do_parse () from /usr/lib64/libbson-1.0.so.0
      #5 0x00007ffff6f0345e in bson_json_reader_read () from /usr/lib64/libbson-1.0.so.0
      #6 0x000000000044066f in MongoDBClient::Json2Bson (
      json="{\"$oid\" : { \"$numberLong\" : \"1455853006123\"}}") at MongoDBClient.cpp:99
      #7 0x0000000000444d0b in MongoDBProxyQuestProcessor::singleFind (this=this@entry=0xf8c018, args=
      std::shared_ptr (count 4, weak 0) 0xf4d640, quest=std::shared_ptr (count 7, weak 0) 0xf4d680,
      hintId=hintId@entry=0, onlyHashTable=onlyHashTable@entry=false)
      at MongoDBProxyQuestProcessor.cpp:136

      ---------------------
      case 3
      ---------------------
      JSON string:

      {"$oid" : "563b029096f9bc35c61df3a3"}

      screen output:
      src/bson/bson.c:1405 bson_append_oid(): precondition failed: key

      crashed service stack by gdb:
      ---------------------
      #0 0x00007ffff5c485c9 in raise () from /lib64/libc.so.6
      #1 0x00007ffff5c49cd8 in abort () from /lib64/libc.so.6
      #2 0x00007ffff6efb775 in bson_append_oid () from /usr/lib64/libbson-1.0.so.0
      #3 0x00007ffff6f0305b in _bson_json_read_end_map () from /usr/lib64/libbson-1.0.so.0
      #4 0x00007ffff6f0a80d in yajl_do_parse () from /usr/lib64/libbson-1.0.so.0
      #5 0x00007ffff6f0345e in bson_json_reader_read () from /usr/lib64/libbson-1.0.so.0
      #6 0x000000000044066f in MongoDBClient::Json2Bson (json="

      {\"$oid\" : \"563b029096f9bc35c61df3a3\"}

      ")
      at MongoDBClient.cpp:99
      #7 0x0000000000444d0b in MongoDBProxyQuestProcessor::singleFind (this=this@entry=0xf8c018, args=
      std::shared_ptr (count 4, weak 0) 0xf4d440, quest=std::shared_ptr (count 7, weak 0) 0xf4d480,
      hintId=hintId@entry=0, onlyHashTable=onlyHashTable@entry=false)
      at MongoDBProxyQuestProcessor.cpp:136

      ---------------------
      My convert function:
      (Service is development by C++11 with Mongo C Driver.)
      ---------------------

      bson_t* MongoDBClient::Json2Bson(const std::string& json)
      {
      const size_t buffsize = 512;
      bson_json_reader_t *reader = bson_json_data_reader_new(1, buffsize);
      if (reader == NULL)
      return NULL;

      bson_json_data_reader_ingest(reader, (const uint8_t *)json.data(), json.length());

      bson_error_t error;
      bson_t* doc = bson_new();
      bson_t* doc2 = bson_new();

      int state = bson_json_reader_read (reader, doc, &error);
      if (state < 0)

      { bson_destroy (doc); bson_destroy (doc2); bson_json_reader_destroy (reader); LOG_ERROR("convert json %s to bson failed. error: %s", json.c_str(), error.message); return NULL; }

      state = bson_json_reader_read (reader, doc2, &error);
      if (state != 0)

      { bson_destroy (doc); bson_destroy (doc2); bson_json_reader_destroy (reader); LOG_ERROR("convert json %s to bson failed. Json not a single object, reentered.", json.c_str()); return NULL; }

      bson_destroy (doc2);
      bson_json_reader_destroy (reader);

      return doc;
      }

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              jesse A. Jesse Jiryu Davis
              Reporter:
              swxlion Wangxing Shi
              Participants:
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: