diff --git a/.evergreen/scripts/compile-libmongocrypt.sh b/.evergreen/scripts/compile-libmongocrypt.sh index 1debf6c95e5..b58aa0122d5 100755 --- a/.evergreen/scripts/compile-libmongocrypt.sh +++ b/.evergreen/scripts/compile-libmongocrypt.sh @@ -14,7 +14,7 @@ compile_libmongocrypt() { # Run `.evergreen/scripts/kms-divergence-check.sh` to ensure that there is no divergence in the copied files. declare -r version="1.15.1" - git clone -q --depth=1 https://github.com/mongodb/libmongocrypt --branch "${version:?}" || return + git clone -q --depth=1 https://github.com/connorsmacd/libmongocrypt --branch qe-json-mixing-error.MONGOCRYPT-793 || return declare -a crypt_cmake_flags=( "-DMONGOCRYPT_MONGOC_DIR=${mongoc_dir}" diff --git a/src/libmongoc/tests/client_side_encryption_prose/lookup/schema-non-csfle.json b/src/libmongoc/tests/client_side_encryption_prose/lookup/schema-non-csfle.json new file mode 100644 index 00000000000..3edd12c8f4c --- /dev/null +++ b/src/libmongoc/tests/client_side_encryption_prose/lookup/schema-non-csfle.json @@ -0,0 +1,3 @@ +{ + "bsonType": "object" +} diff --git a/src/libmongoc/tests/test-libmongoc.c b/src/libmongoc/tests/test-libmongoc.c index 0c622efbc1b..a0b188d5e7a 100644 --- a/src/libmongoc/tests/test-libmongoc.c +++ b/src/libmongoc/tests/test-libmongoc.c @@ -2268,6 +2268,8 @@ WIRE_VERSION_CHECKS(24) WIRE_VERSION_CHECKS(25) /* wire version 26 begins with the 8.1 release. */ WIRE_VERSION_CHECKS(26) +/* wire version 27 begins with the 8.2 release. */ +WIRE_VERSION_CHECKS(27) int test_framework_skip_if_no_dual_ip_hostname(void) diff --git a/src/libmongoc/tests/test-libmongoc.h b/src/libmongoc/tests/test-libmongoc.h index e3d05d2db06..c092962abdb 100644 --- a/src/libmongoc/tests/test-libmongoc.h +++ b/src/libmongoc/tests/test-libmongoc.h @@ -214,6 +214,8 @@ WIRE_VERSION_CHECK_DECLS(24) WIRE_VERSION_CHECK_DECLS(25) /* wire version 26 begins with the 8.1 release. */ WIRE_VERSION_CHECK_DECLS(26) +/* wire version 27 begins with the 8.2 release. */ +WIRE_VERSION_CHECK_DECLS(27) #undef WIRE_VERSION_CHECK_DECLS diff --git a/src/libmongoc/tests/test-mongoc-client-side-encryption.c b/src/libmongoc/tests/test-mongoc-client-side-encryption.c index 72c051e0c9c..ac28dfcea0e 100644 --- a/src/libmongoc/tests/test-mongoc-client-side-encryption.c +++ b/src/libmongoc/tests/test-mongoc-client-side-encryption.c @@ -6619,6 +6619,18 @@ test_lookup_setup(void) mongoc_collection_destroy(coll); } + // Create db.non_csfle_schema: + { + drop_coll(db, "non_csfle_schema"); + bson_t *schema = get_bson_from_json_file(TESTDIR "schema-non-csfle.json"); + bson_t *create_opts = BCON_NEW("validator", "{", "$jsonSchema", BCON_DOCUMENT(schema), "}"); + mongoc_collection_t *coll = mongoc_database_create_collection(db, "non_csfle_schema", create_opts, &error); + ASSERT_OR_PRINT(coll, error); + mongoc_collection_destroy(coll); + bson_destroy(create_opts); + bson_destroy(schema); + } + mongoc_database_destroy(db); } #undef TESTDIR @@ -6699,6 +6711,19 @@ test_lookup_setup(void) mongoc_collection_destroy(coll_unencrypted); } + // Insert to db.non_csfle_schema + { + mongoc_collection_t *coll = mongoc_client_get_collection(client, "db", "non_csfle_schema"); + ok = mongoc_collection_insert_one( + coll, MAKE_BSON({"non_csfle_schema" : "non_csfle_schema"}), NULL, NULL, &error); + ASSERT_OR_PRINT(ok, error); + mongoc_collection_destroy(coll); + // Find document with unencrypted client to check it is not encrypted. + mongoc_collection_t *coll_unencrypted = mongoc_client_get_collection(setup_client, "db", "non_csfle_schema"); + ASSERT_COLL_MATCHES_ONE(coll_unencrypted, MAKE_BSON({"non_csfle_schema" : "non_csfle_schema"})); + mongoc_collection_destroy(coll_unencrypted); + } + mongoc_client_destroy(client); } @@ -6909,7 +6934,66 @@ test_lookup(void *unused) ] }); - ASSERT_AGG_ERROR(coll, pipeline, "not supported"); + if (test_framework_get_server_version() < test_framework_str_to_version("8.2.0")) { + ASSERT_AGG_ERROR(coll, pipeline, "not supported"); + } else { + // The error domain differs depending on the query analysis component: + // * `crypt_shared`: `MONGOC_ERROR_CLIENT_SIDE_ENCRYPTION` + // * `mongocryptd`: `MONGOC_ERROR_QUERY` + + static const char *const expected_error_substring = + "Cannot specify both encryptionInformation and csfleEncryptionSchemas unless csfleEncryptionSchemas only " + "contains non-encryption JSON schema validators"; + + if (mongoc_client_get_crypt_shared_version(client)) { + ASSERT_AGG_ERROR(coll, pipeline, expected_error_substring); + } else { + mongoc_cursor_t *const cursor = mongoc_collection_aggregate(coll, 0, pipeline, NULL, NULL); + const bson_t *got; + ASSERT(!mongoc_cursor_next(cursor, &got)); + ASSERT(mongoc_cursor_error(cursor, &error)); + static const uint32_t expected_error_code = 10026002u; + ASSERT_ERROR_CONTAINS(error, MONGOC_ERROR_QUERY, expected_error_code, expected_error_substring); + mongoc_cursor_destroy(cursor); + } + } + + mongoc_collection_destroy(coll); + mongoc_client_destroy(client); + } +} + +static void +test_lookup_post82(void *unused) +{ + BSON_UNUSED(unused); + test_lookup_setup(); + bson_error_t error; + + // Case 10: db.qe joins db.non_csfle_schema: + { + mongoc_client_t *client = create_encrypted_client(); + mongoc_collection_t *coll = mongoc_client_get_collection(client, "db", "qe"); + + bson_t *pipeline = MAKE_BSON({ + "pipeline" : [ + {"$match" : {"qe" : "qe"}}, + { + "$lookup" : { + "from" : "non_csfle_schema", + "as" : "matched", + "pipeline" : [ + {"$match" : {"non_csfle_schema" : "non_csfle_schema"}}, + {"$project" : {"_id" : 0, "__safeContent__" : 0}} + ] + } + }, + {"$project" : {"_id" : 0, "__safeContent__" : 0}} + ] + }); + + bson_t *expect = MAKE_BSON({"qe" : "qe", "matched" : [ {"non_csfle_schema" : "non_csfle_schema"} ]}); + ASSERT_AGG_RETURNS_ONE(coll, pipeline, expect); mongoc_collection_destroy(coll); mongoc_client_destroy(client); } @@ -7388,6 +7472,14 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_26 /* require server 8.1+ */, test_framework_skip_if_single, /* QE not supported on standalone */ test_framework_skip_if_no_client_side_encryption); + TestSuite_AddFull(suite, + "/client_side_encryption/test_lookup/post-8.2", + test_lookup_post82, + NULL, + NULL, + test_framework_skip_if_max_wire_version_less_than_27, /* require server 8.2+ */ + test_framework_skip_if_single, /* QE not supported on standalone */ + test_framework_skip_if_no_client_side_encryption); TestSuite_AddFull(suite, "/client_side_encryption/test_lookup/pre-8.1", test_lookup_pre81,