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

BSON_TYPE_CODE and BSON_TYPE_CODEWSCOPE fail to roundtrip through JSON correctly

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • 1.6.0
    • Affects Version/s: None
    • Component/s: json, libbson
    • None

      Two BSON types, namely BSON_TYPE_CODE and BSON_TYPE_CODEWSCOPE, fail to transition through their JSON representation.

      In case of BSON_TYPE_CODE, its binary data will be different from the source document. That's especially weird because the JSON representation is restored with no difference.

      In case of BSON_TYPE_CODEWSCOPE, both the binary data and the JSON representation will be different from the source document when scope is an empty document (note the additional space between the scope brackets). When scope is not empty, the binary data will differ.

      Example:

      #include <stdio.h>
      #include <bson.h>
      
      void test(const bson_t *src) {
      	char *json = bson_as_json(src, 0); // src -> json
      	bson_t *dst = bson_new_from_json(json, -1, 0); // json -> dst
      	char *json_ = bson_as_json(dst, 0); // dst -> json_
      
      	BSON_ASSERT(json && dst && json_); // No errors
      
      	printf("Testing %s\n", json);
      	printf("... and %s\n", json_);
      	printf("* as JSON - %s\n", strcmp(json, json_) ? "failed!!!" : "OK"); // Compare as JSON
      	printf("* as binary - %s\n", !bson_equal(src, dst) ? "failed!!!" : "OK"); // Compare as binary
      	printf("\n");
      
      	bson_destroy(dst);
      	bson_free(json);
      	bson_free(json_);
      }
      
      int main() {
      	bson_t *b1 = bson_new();
      	bson_t *b2 = bson_new();
      	bson_t *b3 = bson_new();
      	bson_t *b4 = bson_new();
      	bson_t *scope = bson_new();
      
      	// All types roundtrip alright, for example:
      
      	BSON_APPEND_BINARY(b1, "a", 0x80, "abc", 3);
      	BSON_APPEND_MINKEY(b1, "b");
      	BSON_APPEND_REGEX(b1, "c", "abc", "def");
      	test(b1);
      
      	// Except for these guys:
      
      	BSON_APPEND_CODE(b2, "a", "abc");
      	test(b2);
      
      	BSON_APPEND_CODE_WITH_SCOPE(b3, "a", "abc", scope);
      	test(b3);
      
      	BSON_APPEND_BOOL(scope, "bool", 1); // Non-empty scope now
      	BSON_APPEND_CODE_WITH_SCOPE(b4, "a", "abc", scope);
      	test(b4);
      
      	bson_destroy(b1);
      	bson_destroy(b2);
      	bson_destroy(b3);
      	bson_destroy(b4);
      	bson_destroy(scope);
      	return 0;
      }
      

      Output:

      Testing { "a" : { "$binary" : "YWJj", "$type" : "80" }, "b" : { "$minKey" : 1 }, "c" : { "$regex" : "abc", "$options" : "def" } }
      ... and { "a" : { "$binary" : "YWJj", "$type" : "80" }, "b" : { "$minKey" : 1 }, "c" : { "$regex" : "abc", "$options" : "def" } }
      * as JSON - OK
      * as binary - OK
      
      Testing { "a" : { "$code" : "abc" } }
      ... and { "a" : { "$code" : "abc" } }
      * as JSON - OK
      * as binary - failed!!!
      
      Testing { "a" : { "$code" : "abc", "$scope" : { } } }
      ... and { "a" : { "$code" : "abc", "$scope" : {  } } }
      * as JSON - failed!!!
      * as binary - failed!!!
      
      Testing { "a" : { "$code" : "abc", "$scope" : { "bool" : true } } }
      ... and { "a" : { "$code" : "abc", "$scope" : { "bool" : true } } }
      * as JSON - OK
      * as binary - failed!!!
      

        1. libbson2.c
          1 kB
          Arseny Vakhrushev

            Assignee:
            jesse@mongodb.com A. Jesse Jiryu Davis
            Reporter:
            neoxic Arseny Vakhrushev
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: