diff --git a/CHANGELOG.md b/CHANGELOG.md index b51e793aa..0c4558b73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +### Added +- Stable support for prefix and suffix queries: + - The `prefixPreview` query type is replaced with `prefix`. + - The `suffixPreview` query type is replaced with `suffix`. + - Use the `string` algorithm (formerly `textPreview`) for `prefix`, `suffix`, and `substringPreview` query types. + +### Removed +- Support for the experimental `prefixPreview` and `suffixPreview` query types. + ## 1.18.1 diff --git a/bindings/python/test/test_mongocrypt.py b/bindings/python/test/test_mongocrypt.py index 6a3be5cb9..c49f18b3b 100644 --- a/bindings/python/test/test_mongocrypt.py +++ b/bindings/python/test/test_mongocrypt.py @@ -1030,9 +1030,9 @@ async def test_text_query(self): value = bson.encode({"v": "foo"}) encrypted = await encrypter.encrypt( value, - "textPreview", + "string", key_id=key_id, - query_type="suffixPreview", + query_type="suffix", contention_factor=0, text_opts=text_opts, ) @@ -1500,9 +1500,9 @@ def test_text_query(self): value = bson.encode({"v": "foo"}) encrypted = encrypter.encrypt( value, - "textPreview", + "string", key_id=key_id, - query_type="suffixPreview", + query_type="suffix", contention_factor=0, text_opts=text_opts, ) diff --git a/src/mc-efc-private.h b/src/mc-efc-private.h index 86a4d3f8d..f78379602 100644 --- a/src/mc-efc-private.h +++ b/src/mc-efc-private.h @@ -32,6 +32,9 @@ typedef enum _supported_query_type_flags { SUPPORTS_SUBSTRING_PREVIEW_QUERIES = 1 << 3, SUPPORTS_SUFFIX_QUERIES = 1 << 4, SUPPORTS_PREFIX_QUERIES = 1 << 5, + // prefixPreview and suffixPreview are dropped. Setting this results in an error. + SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES = 1 << 6, + SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES = 1 << 7, } supported_query_type_flags; typedef struct _mc_EncryptedField_t { diff --git a/src/mc-efc.c b/src/mc-efc.c index 432615b5d..ad43a531a 100644 --- a/src/mc-efc.c +++ b/src/mc-efc.c @@ -35,12 +35,14 @@ static bool _parse_query_type_string(const char *queryType, supported_query_type *out = SUPPORTS_RANGE_PREVIEW_DEPRECATED_QUERIES; } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR), qtv)) { *out = SUPPORTS_SUBSTRING_PREVIEW_QUERIES; - } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR), qtv) - || mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIX_STR), qtv)) { + } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIX_STR), qtv)) { *out = SUPPORTS_SUFFIX_QUERIES; - } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR), qtv) - || mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIX_STR), qtv)) { + } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIX_STR), qtv)) { *out = SUPPORTS_PREFIX_QUERIES; + } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR), qtv)) { + *out = SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES; + } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR), qtv)) { + *out = SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES; } else { return false; } @@ -176,6 +178,20 @@ static bool _parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocry return false; } + if (query_types & SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES) { + CLIENT_ERR("Cannot use field '%s' with 'prefixPreview' queries. 'prefixPreview' is unsupported. Use 'prefix' " + "instead.", + field_path); + return false; + } + + if (query_types & SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES) { + CLIENT_ERR("Cannot use field '%s' with 'suffixPreview' queries. 'suffixPreview' is unsupported. Use 'suffix' " + "instead.", + field_path); + return false; + } + /* Prepend a new mc_EncryptedField_t */ mc_EncryptedField_t *ef = bson_malloc0(sizeof(mc_EncryptedField_t)); if (has_keyid) { diff --git a/src/mongocrypt-ctx-encrypt.c b/src/mongocrypt-ctx-encrypt.c index 4df7042ec..5d967db36 100644 --- a/src/mongocrypt-ctx-encrypt.c +++ b/src/mongocrypt-ctx-encrypt.c @@ -1539,7 +1539,7 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t * goto fail; // fallthrough case MONGOCRYPT_INDEX_TYPE_RANGE: marking.u.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_RANGE; break; - case MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW: marking.u.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH; break; + case MONGOCRYPT_INDEX_TYPE_STRING: marking.u.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH; break; default: // This might be unreachable because of other validation. Better safe than // sorry. @@ -1631,7 +1631,7 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t * case MONGOCRYPT_INDEX_TYPE_EQUALITY: case MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED: case MONGOCRYPT_INDEX_TYPE_RANGE: - case MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW: + case MONGOCRYPT_INDEX_TYPE_STRING: // All QE indexed algorithms require contention factor. BSON_ASSERT(ctx->opts.contention_factor.set); // Checked earlier in explicit_encrypt_init. marking.u.fle2.maxContentionFactor = ctx->opts.contention_factor.value; @@ -2088,18 +2088,18 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms if (ctx->opts.query_type.set) { const mongocrypt_query_type_t qt = ctx->opts.query_type.value; if (qt == MONGOCRYPT_QUERY_TYPE_PREFIX) { - if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW)) { - return _mongocrypt_ctx_fail_w_msg(ctx, "prefix query type requires textPreview index type"); + if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) { + return _mongocrypt_ctx_fail_w_msg(ctx, "prefix query type requires string index type"); } } if (qt == MONGOCRYPT_QUERY_TYPE_SUFFIX) { - if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW)) { - return _mongocrypt_ctx_fail_w_msg(ctx, "suffix query type requires textPreview index type"); + if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) { + return _mongocrypt_ctx_fail_w_msg(ctx, "suffix query type requires string index type"); } } if (qt == MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW) { - if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW)) { - return _mongocrypt_ctx_fail_w_msg(ctx, "substringPreview query type requires textPreview index type"); + if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) { + return _mongocrypt_ctx_fail_w_msg(ctx, "substringPreview query type requires string index type"); } } } @@ -2113,14 +2113,14 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set range opts with equality index type"); } - if (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW) { - return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set range opts with textPreview index type"); + if (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING) { + return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set range opts with 'string' algorithm"); } } if (ctx->opts.textopts.set && ctx->opts.index_type.set) { - if (ctx->opts.index_type.value != MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW) { - return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set text opts without textPreview index type"); + if (ctx->opts.index_type.value != MONGOCRYPT_INDEX_TYPE_STRING) { + return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set string opts without string index type"); } } @@ -2147,13 +2147,13 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms } // Check required options for text algorithm are set: - if (ctx->opts.index_type.set && (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW)) { + if (ctx->opts.index_type.set && (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) { if (!ctx->opts.contention_factor.set) { - return _mongocrypt_ctx_fail_w_msg(ctx, "contention factor is required for textPreview algorithm"); + return _mongocrypt_ctx_fail_w_msg(ctx, "contention factor is required for string algorithm"); } if (!ctx->opts.textopts.set) { - return _mongocrypt_ctx_fail_w_msg(ctx, "text opts are required for textPreview algorithm"); + return _mongocrypt_ctx_fail_w_msg(ctx, "string opts are required for string algorithm"); } } @@ -2183,7 +2183,7 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms case MONGOCRYPT_QUERY_TYPE_PREFIX: case MONGOCRYPT_QUERY_TYPE_SUFFIX: case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW: - matches = (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW); + matches = (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING); break; default: CLIENT_ERR("unsupported value for query_type: %d", (int)ctx->opts.query_type.value); diff --git a/src/mongocrypt-ctx.c b/src/mongocrypt-ctx.c index 1462edecd..ab8009214 100644 --- a/src/mongocrypt-ctx.c +++ b/src/mongocrypt-ctx.c @@ -245,8 +245,8 @@ bool mongocrypt_ctx_setopt_algorithm(mongocrypt_ctx_t *ctx, const char *algorith } else if (mstr_eq_ignore_case(algo_str, mstrv_lit(MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR))) { _mongocrypt_ctx_fail_w_msg(ctx, "Algorithm 'rangePreview' is deprecated, please use 'range'"); return false; - } else if (mstr_eq_ignore_case(algo_str, mstrv_lit(MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR))) { - ctx->opts.index_type.value = MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW; + } else if (mstr_eq_ignore_case(algo_str, mstrv_lit(MONGOCRYPT_ALGORITHM_STRING_STR))) { + ctx->opts.index_type.value = MONGOCRYPT_INDEX_TYPE_STRING; ctx->opts.index_type.set = true; } else { char *error = bson_strdup_printf("unsupported algorithm string \"%.*s\"", @@ -1028,15 +1028,11 @@ bool mongocrypt_ctx_setopt_query_type(mongocrypt_ctx_t *ctx, const char *query_t ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUFFIX; ctx->opts.query_type.set = true; } else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR))) { - // TODO: MONGOCRYPT-870 disallow prefixPreview - // _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'prefixPreview' is deprecated, please use 'prefix'"); - ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_PREFIX; - ctx->opts.query_type.set = true; + _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'prefixPreview' is deprecated, please use 'prefix'"); + return false; } else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR))) { - // TODO: MONGOCRYPT-870 disallow suffixPreview - // _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'suffixPreview' is deprecated, please use 'suffix'"); - ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUFFIX; - ctx->opts.query_type.set = true; + _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'suffixPreview' is deprecated, please use 'suffix'"); + return false; } else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR))) { ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW; ctx->opts.query_type.set = true; @@ -1058,7 +1054,7 @@ const char *_mongocrypt_index_type_to_string(mongocrypt_index_type_t val) { case MONGOCRYPT_INDEX_TYPE_EQUALITY: return "Equality"; case MONGOCRYPT_INDEX_TYPE_RANGE: return "Range"; case MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED: return "RangePreview"; - case MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW: return "TextPreview"; + case MONGOCRYPT_INDEX_TYPE_STRING: return "String"; default: return "Unknown"; } } diff --git a/src/mongocrypt-private.h b/src/mongocrypt-private.h index 9f59888fd..b1717fbab 100644 --- a/src/mongocrypt-private.h +++ b/src/mongocrypt-private.h @@ -156,7 +156,7 @@ typedef enum { MONGOCRYPT_INDEX_TYPE_EQUALITY = 2, MONGOCRYPT_INDEX_TYPE_RANGE = 3, MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED = 4, - MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW = 5, + MONGOCRYPT_INDEX_TYPE_STRING = 5, } mongocrypt_index_type_t; bool _mongocrypt_validate_and_copy_string(const char *in, int32_t in_len, char **out) MONGOCRYPT_WARN_UNUSED_RESULT; diff --git a/src/mongocrypt.h b/src/mongocrypt.h index 334d082d7..052f08bcb 100644 --- a/src/mongocrypt.h +++ b/src/mongocrypt.h @@ -716,8 +716,10 @@ bool mongocrypt_ctx_setopt_algorithm(mongocrypt_ctx_t *ctx, const char *algorith // DEPRECATED: support "RangePreview" has been removed in favor of "range". #define MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR "RangePreview" #define MONGOCRYPT_ALGORITHM_RANGE_STR "Range" -/// NOTE: "textPreview" is experimental only and may be removed in a future non-major release. -#define MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR "textPreview" +/// DEPRECATED: "textPreview" has been removed. Use "string". +#define MONGOCRYPT_ALGORITHM_TEXTPREVIEW_DEPRECATED_STR "textPreview" +// String constant for setopt_algorithm "string" explicit encryption. +#define MONGOCRYPT_ALGORITHM_STRING_STR "string" /** * Identify the AWS KMS master key to use for creating a data key. @@ -1555,9 +1557,9 @@ MONGOCRYPT_EXPORT bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *opts); /** - * Set options for explicit encryption with the "textPreview" algorithm. + * Set options for explicit encryption with the "string" algorithm. * - * NOTE: "textPreview" is experimental only and may be removed in a future non-major release. + * NOTE: Use of the "substringPreview" query type is experimental only and may be removed in a future non-major release. * @p opts is a BSON document of the form: * { * "caseSensitive": bool, @@ -1578,6 +1580,8 @@ bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_bin * } * * "prefix" and "suffix" can both be set. + * + * NOTE: Driver public APIs should use the name "string" rather than "text" to refer to options. */ MONGOCRYPT_EXPORT bool mongocrypt_ctx_setopt_algorithm_text(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *opts); diff --git a/test/data/cleanup/text-search/collinfo.json b/test/data/cleanup/text-search/collinfo.json index a64a0e7da..6109a16dc 100644 --- a/test/data/cleanup/text-search/collinfo.json +++ b/test/data/cleanup/text-search/collinfo.json @@ -74,7 +74,7 @@ "path": "textField2", "bsonType": "string", "queries": [{ - "queryType": "suffixPreview", + "queryType": "suffix", "contention": { "$numberLong": "0" }, @@ -84,7 +84,7 @@ "diacriticSensitive": false }, { - "queryType": "prefixPreview", + "queryType": "prefix", "contention": { "$numberLong": "0" }, diff --git a/test/data/cleanup/text-search/encrypted-field-config-map.json b/test/data/cleanup/text-search/encrypted-field-config-map.json index ca45b054b..21d92bf1f 100644 --- a/test/data/cleanup/text-search/encrypted-field-config-map.json +++ b/test/data/cleanup/text-search/encrypted-field-config-map.json @@ -72,7 +72,7 @@ "path": "textField2", "bsonType": "string", "queries": [{ - "queryType": "suffixPreview", + "queryType": "suffix", "contention": { "$numberLong": "0" }, @@ -82,7 +82,7 @@ "diacriticSensitive": false }, { - "queryType": "prefixPreview", + "queryType": "prefix", "contention": { "$numberLong": "0" }, diff --git a/test/data/compact/text-search/collinfo.json b/test/data/compact/text-search/collinfo.json index a64a0e7da..6109a16dc 100644 --- a/test/data/compact/text-search/collinfo.json +++ b/test/data/compact/text-search/collinfo.json @@ -74,7 +74,7 @@ "path": "textField2", "bsonType": "string", "queries": [{ - "queryType": "suffixPreview", + "queryType": "suffix", "contention": { "$numberLong": "0" }, @@ -84,7 +84,7 @@ "diacriticSensitive": false }, { - "queryType": "prefixPreview", + "queryType": "prefix", "contention": { "$numberLong": "0" }, diff --git a/test/data/compact/text-search/encrypted-field-config-map.json b/test/data/compact/text-search/encrypted-field-config-map.json index ca45b054b..21d92bf1f 100644 --- a/test/data/compact/text-search/encrypted-field-config-map.json +++ b/test/data/compact/text-search/encrypted-field-config-map.json @@ -72,7 +72,7 @@ "path": "textField2", "bsonType": "string", "queries": [{ - "queryType": "suffixPreview", + "queryType": "suffix", "contention": { "$numberLong": "0" }, @@ -82,7 +82,7 @@ "diacriticSensitive": false }, { - "queryType": "prefixPreview", + "queryType": "prefix", "contention": { "$numberLong": "0" }, diff --git a/test/data/compact/text-search/encrypted-payload.json b/test/data/compact/text-search/encrypted-payload.json index aa51bb270..1a80b4e14 100644 --- a/test/data/compact/text-search/encrypted-payload.json +++ b/test/data/compact/text-search/encrypted-payload.json @@ -78,7 +78,7 @@ "path": "textField2", "bsonType": "string", "queries": [{ - "queryType": "suffixPreview", + "queryType": "suffix", "contention": { "$numberLong": "0" }, @@ -88,7 +88,7 @@ "diacriticSensitive": false }, { - "queryType": "prefixPreview", + "queryType": "prefix", "contention": { "$numberLong": "0" }, diff --git a/test/data/efc/efc-textSearchFields-badVersionSet.json b/test/data/efc/efc-textSearchFields-badVersionSet.json index 76992885f..7bcc618f6 100644 --- a/test/data/efc/efc-textSearchFields-badVersionSet.json +++ b/test/data/efc/efc-textSearchFields-badVersionSet.json @@ -30,13 +30,13 @@ "bsonType": "string", "queries": [ { - "queryType": "suffixPreview", + "queryType": "suffix", "contention": { "$numberLong": "0" } }, { - "queryType": "prefixPreview", + "queryType": "prefix", "contention": { "$numberLong": "0" } diff --git a/test/data/efc/efc-textSearchFields-goodVersionSet.json b/test/data/efc/efc-textSearchFields-goodVersionSet.json index 87fccdec6..217608fb8 100644 --- a/test/data/efc/efc-textSearchFields-goodVersionSet.json +++ b/test/data/efc/efc-textSearchFields-goodVersionSet.json @@ -30,13 +30,13 @@ "bsonType": "string", "queries": [ { - "queryType": "suffixPreview", + "queryType": "suffix", "contention": { "$numberLong": "0" } }, { - "queryType": "prefixPreview", + "queryType": "prefix", "contention": { "$numberLong": "0" } diff --git a/test/data/efc/efc-textSearchFields.json b/test/data/efc/efc-textSearchFields.json index 8eda94a86..befc3d545 100644 --- a/test/data/efc/efc-textSearchFields.json +++ b/test/data/efc/efc-textSearchFields.json @@ -30,13 +30,13 @@ "bsonType": "string", "queries": [ { - "queryType": "suffixPreview", + "queryType": "suffix", "contention": { "$numberLong": "0" } }, { - "queryType": "prefixPreview", + "queryType": "prefix", "contention": { "$numberLong": "0" } diff --git a/test/data/fle2-insert-text-search-preview/cmd.json b/test/data/fle2-insert-text-search-preview/cmd.json new file mode 100644 index 000000000..ca12d021d --- /dev/null +++ b/test/data/fle2-insert-text-search-preview/cmd.json @@ -0,0 +1,9 @@ +{ + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": "value123" + } + ] +} \ No newline at end of file diff --git a/test/data/fle2-insert-text-search-preview/encrypted-field-map-prefixPreview.json b/test/data/fle2-insert-text-search-preview/encrypted-field-map-prefixPreview.json new file mode 100644 index 000000000..8e7463e34 --- /dev/null +++ b/test/data/fle2-insert-text-search-preview/encrypted-field-map-prefixPreview.json @@ -0,0 +1,24 @@ +{ + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "prefixPreview", + "contention": { + "$numberLong": "0" + } + } + } + ] + } +} diff --git a/test/data/fle2-insert-text-search-preview/encrypted-field-map-suffixPreview.json b/test/data/fle2-insert-text-search-preview/encrypted-field-map-suffixPreview.json new file mode 100644 index 000000000..ae525fd43 --- /dev/null +++ b/test/data/fle2-insert-text-search-preview/encrypted-field-map-suffixPreview.json @@ -0,0 +1,24 @@ +{ + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "suffixPreview", + "contention": { + "$numberLong": "0" + } + } + } + ] + } +} diff --git a/test/test-mongocrypt-ctx-encrypt.c b/test/test-mongocrypt-ctx-encrypt.c index a3f046f17..eb7dd2a01 100644 --- a/test/test-mongocrypt-ctx-encrypt.c +++ b/test/test-mongocrypt-ctx-encrypt.c @@ -2477,8 +2477,8 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { { ee_testcase tc = {0}; tc.desc = "find suffix"; - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; - tc.query_type = MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; + tc.query_type = MONGOCRYPT_QUERY_TYPE_SUFFIX_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); tc.user_key_id = &keyABC_id; @@ -2495,8 +2495,8 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { { ee_testcase tc = {0}; tc.desc = "find prefix"; - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; - tc.query_type = MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; + tc.query_type = MONGOCRYPT_QUERY_TYPE_PREFIX_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); tc.user_key_id = &keyABC_id; @@ -2513,7 +2513,7 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { { ee_testcase tc = {0}; tc.desc = "find suffix"; - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; tc.query_type = MONGOCRYPT_QUERY_TYPE_SUFFIX_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); @@ -2531,7 +2531,7 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { { ee_testcase tc = {0}; tc.desc = "find prefix"; - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; tc.query_type = MONGOCRYPT_QUERY_TYPE_PREFIX_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); @@ -2549,7 +2549,7 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { { ee_testcase tc = {0}; tc.desc = "insert substring"; - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; tc.query_type = MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); @@ -2570,7 +2570,7 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { #include "./data/fle2-insert-text-search/RNG_DATA.h" tc.rng_data = (_test_rng_data_source){.buf = {.data = (uint8_t *)RNG_DATA, .len = sizeof(RNG_DATA) - 1}}; #undef RNG_DATA - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); tc.user_key_id = &keyABC_id; @@ -2590,7 +2590,7 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { #include "./data/fle2-insert-text-search/RNG_DATA.h" tc.rng_data = (_test_rng_data_source){.buf = {.data = (uint8_t *)RNG_DATA, .len = sizeof(RNG_DATA) - 1}}; #undef RNG_DATA - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); tc.user_key_id = &keyABC_id; @@ -2610,7 +2610,7 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { #include "./data/fle2-insert-text-search/RNG_DATA.h" tc.rng_data = (_test_rng_data_source){.buf = {.data = (uint8_t *)RNG_DATA, .len = sizeof(RNG_DATA) - 1}}; #undef RNG_DATA - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); tc.user_key_id = &keyABC_id; @@ -2630,7 +2630,7 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { #include "./data/fle2-insert-text-search/RNG_DATA.h" tc.rng_data = (_test_rng_data_source){.buf = {.data = (uint8_t *)RNG_DATA, .len = sizeof(RNG_DATA) - 1}}; #undef RNG_DATA - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); tc.user_key_id = &keyABC_id; @@ -2651,7 +2651,7 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { #include "./data/fle2-insert-text-search/RNG_DATA.h" tc.rng_data = (_test_rng_data_source){.buf = {.data = (uint8_t *)RNG_DATA, .len = sizeof(RNG_DATA) - 1}}; #undef RNG_DATA - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); tc.user_key_id = &keyABC_id; @@ -2668,12 +2668,12 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) { { ee_testcase tc = {0}; tc.desc = "find prefix on a field with prefix+suffix"; - tc.algorithm = MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR; + tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR; tc.contention_factor = OPT_I64(1); tc.msg = TEST_BSON("{'v': 'abc'}"); tc.user_key_id = &keyABC_id; tc.keys_to_feed[0] = keyABC; - tc.query_type = MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR; + tc.query_type = MONGOCRYPT_QUERY_TYPE_PREFIX_STR; tc.text_opts = TEST_BSON(RAW_STRING({ "caseSensitive" : true, "diacriticSensitive" : true, @@ -4410,6 +4410,91 @@ static void _test_rangePreview_fails(_mongocrypt_tester_t *tester) { bson_free(local_kek); } +// `_test_prefixPreview_suffixPreview_fails` tests that use of "prefixPreview" or "suffixPreview" errors. +static void _test_prefixPreview_suffixPreview_fails(_mongocrypt_tester_t *tester) { +#define TF(suffix) TEST_FILE("./test/data/fle2-insert-text-search-preview/" suffix) + + // local_kek is the KEK used to encrypt the keyMaterial in ./test/data/key-document-local.json + uint8_t local_kek_raw[MONGOCRYPT_KEY_LEN] = {0}; + char *local_kek = kms_message_raw_to_b64(local_kek_raw, sizeof(local_kek_raw)); + mongocrypt_binary_t *kms_providers = + TEST_BSON(BSON_STR({"local" : {"key" : {"$binary" : {"base64" : "%s", "subType" : "00"}}}}), local_kek); + + // Test setting 'prefixPreview' as an explicit encryption queryType results in error. + { + mongocrypt_t *crypt = mongocrypt_new(); + mongocrypt_setopt_kms_providers(crypt, kms_providers); + ASSERT_OK(mongocrypt_init(crypt), crypt); + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + ASSERT_OK(ctx, crypt); + ASSERT_FAILS(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR, -1), + ctx, + "Query type 'prefixPreview' is deprecated"); + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); + } + + // Test setting 'suffixPreview' as an explicit encryption queryType results in error. + { + mongocrypt_t *crypt = mongocrypt_new(); + mongocrypt_setopt_kms_providers(crypt, kms_providers); + ASSERT_OK(mongocrypt_init(crypt), crypt); + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + ASSERT_OK(ctx, crypt); + ASSERT_FAILS(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR, -1), + ctx, + "Query type 'suffixPreview' is deprecated"); + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); + } + + // Test setting 'prefixPreview' from encryptedFields results in error. + { + mongocrypt_t *crypt = mongocrypt_new(); + mongocrypt_setopt_kms_providers(crypt, kms_providers); + ASSERT_OK(mongocrypt_setopt_encrypted_field_config_map(crypt, TF("encrypted-field-map-prefixPreview.json")), + crypt); + ASSERT_OK(mongocrypt_init(crypt), crypt); + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + ASSERT_OK(ctx, crypt); + ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TF("cmd.json")), + ctx, + "Cannot use field 'encrypted' with 'prefixPreview' queries"); + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); + } + + // Test setting 'suffixPreview' from encryptedFields results in error. + { + mongocrypt_t *crypt = mongocrypt_new(); + mongocrypt_setopt_kms_providers(crypt, kms_providers); + ASSERT_OK(mongocrypt_setopt_encrypted_field_config_map(crypt, TF("encrypted-field-map-suffixPreview.json")), + crypt); + ASSERT_OK(mongocrypt_init(crypt), crypt); + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + ASSERT_OK(ctx, crypt); + ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TF("cmd.json")), + ctx, + "Cannot use field 'encrypted' with 'suffixPreview' queries"); + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); + } + + bson_free(local_kek); +#undef TF +} + +// `_test_textPreview_fails` tests that using "textPreview" algorithm errors. +static void _test_textPreview_fails(_mongocrypt_tester_t *tester) { + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + ASSERT_FAILS(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_TEXTPREVIEW_DEPRECATED_STR, -1), + ctx, + "unsupported algorithm"); + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); +} + // `autoencryption_test` defines a test for the automatic encryption context. typedef struct { const char *desc; @@ -6819,6 +6904,8 @@ void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_encrypt_fle2_insert_text_search_payload_with_str_encode_version); INSTALL_TEST(_test_bulkWrite); INSTALL_TEST(_test_rangePreview_fails); + INSTALL_TEST(_test_prefixPreview_suffixPreview_fails); + INSTALL_TEST(_test_textPreview_fails); INSTALL_TEST(_test_no_trimFactor); INSTALL_TEST(_test_range_sends_cryptoParams); INSTALL_TEST(_test_encrypt_retry); diff --git a/test/test-mongocrypt-ctx-setopt.c b/test/test-mongocrypt-ctx-setopt.c index 990147254..ecd955c57 100644 --- a/test/test-mongocrypt-ctx-setopt.c +++ b/test/test-mongocrypt-ctx-setopt.c @@ -925,16 +925,15 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { "'rangePreview' is deprecated"); } - /* It is an error to set range opts with index_type == - * MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW */ + /* It is an error to set range opts with the 'string' algorithm */ { REFRESH; /* Set key ID to get past the 'either key id or key alt name required' * error */ ASSERT_KEY_ID_OK(uuid); ASSERT_OK(mongocrypt_ctx_setopt_algorithm_range(ctx, rangeopts), ctx); - ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR, -1), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "cannot set range opts with textPreview index type"); + ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_STRING_STR, -1), ctx); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "cannot set range opts with 'string' algorithm"); } /* If query type == algorithm == "range", succeeds. */ @@ -971,7 +970,7 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { ASSERT_KEY_ID_OK(uuid); ASSERT_OK(mongocrypt_ctx_setopt_algorithm_text(ctx, textopts), ctx); ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_UNINDEXED_STR, -1), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "cannot set text opts without textPreview index type"); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "cannot set string opts without string index type"); } /* It is an error to set text opts with index_type == @@ -983,7 +982,7 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { ASSERT_KEY_ID_OK(uuid); ASSERT_OK(mongocrypt_ctx_setopt_algorithm_text(ctx, textopts), ctx); ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_INDEXED_STR, -1), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "cannot set text opts without textPreview index type"); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "cannot set string opts without string index type"); } /* It is an error to set text opts with index_type == @@ -995,11 +994,11 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { ASSERT_KEY_ID_OK(uuid); ASSERT_OK(mongocrypt_ctx_setopt_algorithm_text(ctx, textopts), ctx); ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_RANGE_STR, -1), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "cannot set text opts without textPreview index type"); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "cannot set string opts without string index type"); } /* It is an error to set a text query_type with index_type != - * MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW */ + * MONGOCRYPT_INDEX_TYPE_STRING */ { REFRESH; /* Set key ID to get past the 'either key id or key alt name required' @@ -1007,23 +1006,23 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { ASSERT_KEY_ID_OK(uuid); ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR, -1), ctx); ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_RANGE_STR, -1), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "substringPreview query type requires textPreview index type"); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "substringPreview query type requires string index type"); REFRESH; /* Set key ID to get past the 'either key id or key alt name required' * error */ ASSERT_KEY_ID_OK(uuid); - ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR, -1), ctx); + ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_PREFIX_STR, -1), ctx); ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_INDEXED_STR, -1), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "prefix query type requires textPreview index type"); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "prefix query type requires string index type"); REFRESH; /* Set key ID to get past the 'either key id or key alt name required' * error */ ASSERT_KEY_ID_OK(uuid); - ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR, -1), ctx); + ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUFFIX_STR, -1), ctx); ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_RANGE_STR, -1), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "suffix query type requires textPreview index type"); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "suffix query type requires string index type"); REFRESH; /* Set key ID to get past the 'either key id or key alt name required' @@ -1031,7 +1030,7 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { ASSERT_KEY_ID_OK(uuid); ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_PREFIX_STR, -1), ctx); ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_RANGE_STR, -1), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "prefix query type requires textPreview index type"); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "prefix query type requires string index type"); REFRESH; /* Set key ID to get past the 'either key id or key alt name required' @@ -1039,27 +1038,46 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { ASSERT_KEY_ID_OK(uuid); ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUFFIX_STR, -1), ctx); ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_RANGE_STR, -1), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "suffix query type requires textPreview index type"); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "suffix query type requires string index type"); + } + + // Can't use "prefixPreview" or "suffixPreview". + { + mongocrypt_destroy(crypt); + crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + REFRESH_CTX; + ASSERT_KEY_ID_OK(uuid); + ASSERT_FAILS(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR, -1), + ctx, + "'prefixPreview' is deprecated"); + + mongocrypt_destroy(crypt); + crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + REFRESH_CTX; + ASSERT_KEY_ID_OK(uuid); + ASSERT_FAILS(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR, -1), + ctx, + "'suffixPreview' is deprecated"); } - /* It is an error to set a text algorithm without setting text options */ + /* It is an error to set a string algorithm without setting text options */ { REFRESH; /* Set key ID to get past the 'either key id or key alt name required' error */ ASSERT_KEY_ID_OK(uuid); - ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR, -1), ctx); + ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_STRING_STR, -1), ctx); ASSERT_OK(mongocrypt_ctx_setopt_contention_factor(ctx, 0), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "text opts are required for textPreview algorithm"); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "string opts are required for string algorithm"); } - /* It is an error to set a text algorithm without setting contention */ + /* It is an error to set a string algorithm without setting contention */ { REFRESH; /* Set key ID to get past the 'either key id or key alt name required' error */ ASSERT_KEY_ID_OK(uuid); - ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_TEXTPREVIEW_STR, -1), ctx); + ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_STRING_STR, -1), ctx); ASSERT_OK(mongocrypt_ctx_setopt_algorithm_text(ctx, textopts), ctx); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "contention factor is required for textPreview algorithm"); + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "contention factor is required for string algorithm"); } mongocrypt_ctx_destroy(ctx);