mirror of https://github.com/mongodb/mongo
SERVER-106496 Update vendored libmongocrypt to 1.15.0 (#39707)
GitOrigin-RevId: 1fb827a0ab5ab338afaf5a650debd07f21818183
This commit is contained in:
parent
947af54dcf
commit
a397e38c0e
|
|
@ -1171,7 +1171,7 @@
|
||||||
"author": "MongoDB, Inc.",
|
"author": "MongoDB, Inc.",
|
||||||
"group": "mongodb",
|
"group": "mongodb",
|
||||||
"name": "libmongocrypt",
|
"name": "libmongocrypt",
|
||||||
"version": "1.14.0",
|
"version": "1.15.0",
|
||||||
"description": "Required C library for Client Side and Queryable Encryption in MongoDB",
|
"description": "Required C library for Client Side and Queryable Encryption in MongoDB",
|
||||||
"licenses": [
|
"licenses": [
|
||||||
{
|
{
|
||||||
|
|
@ -1181,8 +1181,8 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"copyright": "Copyright 2019-present MongoDB, Inc.",
|
"copyright": "Copyright 2019-present MongoDB, Inc.",
|
||||||
"cpe": "cpe:2.3:a:mongodb:libmongocrypt:1.14.0:*:*:*:*:*:*:*",
|
"cpe": "cpe:2.3:a:mongodb:libmongocrypt:1.15.0:*:*:*:*:*:*:*",
|
||||||
"purl": "pkg:github/mongodb/libmongocrypt@1.14.0",
|
"purl": "pkg:github/mongodb/libmongocrypt@1.15.0",
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
"name": "internal:team_responsible",
|
"name": "internal:team_responsible",
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ mongo_cc_library(
|
||||||
"dist/src/mc-schema-broker.c",
|
"dist/src/mc-schema-broker.c",
|
||||||
"dist/src/mc-str-encode-string-sets.c",
|
"dist/src/mc-str-encode-string-sets.c",
|
||||||
"dist/src/mc-text-search-str-encode.c",
|
"dist/src/mc-text-search-str-encode.c",
|
||||||
|
"dist/src/mc-textopts.c",
|
||||||
"dist/src/mc-tokens.c",
|
"dist/src/mc-tokens.c",
|
||||||
"dist/src/mc-writer.c",
|
"dist/src/mc-writer.c",
|
||||||
"dist/src/mongocrypt.c",
|
"dist/src/mongocrypt.c",
|
||||||
|
|
|
||||||
|
|
@ -268,12 +268,14 @@ void mc_FLE2IndexedEncryptedValueV2_destroy(mc_FLE2IndexedEncryptedValueV2_t *ie
|
||||||
_mongocrypt_buffer_cleanup(&iev->ServerEncryptedValue);
|
_mongocrypt_buffer_cleanup(&iev->ServerEncryptedValue);
|
||||||
_mongocrypt_buffer_cleanup(&iev->S_KeyId);
|
_mongocrypt_buffer_cleanup(&iev->S_KeyId);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < iev->edge_count; i++) {
|
if (iev->metadata) {
|
||||||
mc_FLE2TagAndEncryptedMetadataBlock_cleanup(&iev->metadata[i]);
|
for (uint32_t i = 0; i < iev->edge_count; i++) {
|
||||||
}
|
mc_FLE2TagAndEncryptedMetadataBlock_cleanup(&iev->metadata[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// Metadata array is dynamically allocated
|
// Metadata array is dynamically allocated
|
||||||
bson_free(iev->metadata);
|
bson_free(iev->metadata);
|
||||||
|
}
|
||||||
|
|
||||||
bson_free(iev);
|
bson_free(iev);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025-present MongoDB, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MC_TEXTOPTS_PRIVATE_H
|
||||||
|
#define MC_TEXTOPTS_PRIVATE_H
|
||||||
|
|
||||||
|
#include <bson/bson.h>
|
||||||
|
|
||||||
|
#include "mc-optional-private.h"
|
||||||
|
#include "mongocrypt-private.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool set;
|
||||||
|
mc_optional_int32_t strMaxLength;
|
||||||
|
int32_t strMinQueryLength;
|
||||||
|
int32_t strMaxQueryLength;
|
||||||
|
} mc_TextOptsPerIndex_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mc_TextOptsPerIndex_t substring;
|
||||||
|
mc_TextOptsPerIndex_t prefix;
|
||||||
|
mc_TextOptsPerIndex_t suffix;
|
||||||
|
|
||||||
|
bool caseSensitive;
|
||||||
|
bool diacriticSensitive;
|
||||||
|
} mc_TextOpts_t;
|
||||||
|
|
||||||
|
/* mc_TextOpts_parse parses a BSON document into mc_TextOpts_t.
|
||||||
|
* The document is expected to have the form:
|
||||||
|
* {
|
||||||
|
* "caseSensitive": bool,
|
||||||
|
* . "diacriticSensitive": bool,
|
||||||
|
* . "prefix": {
|
||||||
|
* . "strMaxQueryLength": Int32,
|
||||||
|
* . "strMinQueryLength": Int32,
|
||||||
|
* . },
|
||||||
|
* . "suffix": {
|
||||||
|
* . "strMaxQueryLength": Int32,
|
||||||
|
* . "strMinQueryLength": Int32,
|
||||||
|
* . },
|
||||||
|
* . "substring": {
|
||||||
|
* . "strMaxLength": Int32,
|
||||||
|
* . "strMaxQueryLength": Int32,
|
||||||
|
* . "strMinQueryLength": Int32,
|
||||||
|
* . },
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
bool mc_TextOpts_parse(mc_TextOpts_t *txo, const bson_t *in, mongocrypt_status_t *status);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mc_TextOpts_to_FLE2TextSearchInsertSpec creates a placeholder value to be
|
||||||
|
* encrypted. It is only expected to be called when query_type is unset. The
|
||||||
|
* output FLE2TextSearchInsertSpec is a BSON document of the form:
|
||||||
|
* https://github.com/mongodb/mongo/blob/219e90bfad3c712c9642da29ee52229908f06bcd/src/mongo/crypto/fle_field_schema.idl#L689
|
||||||
|
*
|
||||||
|
* v is expect to be a BSON document of the form:
|
||||||
|
* { "v": BSON value to encrypt }.
|
||||||
|
*
|
||||||
|
* Preconditions: out must be initialized by caller.
|
||||||
|
*/
|
||||||
|
bool mc_TextOpts_to_FLE2TextSearchInsertSpec(const mc_TextOpts_t *txo,
|
||||||
|
const bson_t *v,
|
||||||
|
bson_t *out,
|
||||||
|
mongocrypt_status_t *status);
|
||||||
|
|
||||||
|
#endif // MC_TEXTOPTS_PRIVATE_H
|
||||||
|
|
@ -0,0 +1,339 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2025-present MongoDB, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mc-textopts-private.h"
|
||||||
|
|
||||||
|
#include "mongocrypt-private.h"
|
||||||
|
#include "mongocrypt-util-private.h" // mc_bson_type_to_string
|
||||||
|
#include "mongocrypt.h"
|
||||||
|
#include <bson/bson.h>
|
||||||
|
|
||||||
|
// Common logic for testing field name, tracking duplication, and presence.
|
||||||
|
#define IF_FIELD(Name) \
|
||||||
|
if (0 == strcmp(field, #Name)) { \
|
||||||
|
if (has_##Name) { \
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Unexpected duplicate field '" #Name "'"); \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
has_##Name = true; \
|
||||||
|
((void)0)
|
||||||
|
|
||||||
|
#define END_IF_FIELD \
|
||||||
|
continue; \
|
||||||
|
} \
|
||||||
|
else((void)0)
|
||||||
|
|
||||||
|
#define ERROR_PREFIX "Error parsing TextOpts: "
|
||||||
|
|
||||||
|
bool mc_TextOptsPerIndex_parse(mc_TextOptsPerIndex_t *txio, bson_iter_t *iter, mongocrypt_status_t *status) {
|
||||||
|
*txio = (mc_TextOptsPerIndex_t){0};
|
||||||
|
txio->set = true;
|
||||||
|
|
||||||
|
bool has_strMaxLength = false, has_strMinQueryLength = false, has_strMaxQueryLength = false;
|
||||||
|
while (bson_iter_next(iter)) {
|
||||||
|
const char *field = bson_iter_key(iter);
|
||||||
|
BSON_ASSERT(field);
|
||||||
|
|
||||||
|
IF_FIELD(strMaxLength);
|
||||||
|
{
|
||||||
|
if (!BSON_ITER_HOLDS_INT32(iter)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'strMaxLength' must be an int32");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const int32_t val = bson_iter_int32(iter);
|
||||||
|
if (val <= 0) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'strMaxLength' must be greater than zero");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
txio->strMaxLength = OPT_I32(val);
|
||||||
|
}
|
||||||
|
END_IF_FIELD;
|
||||||
|
|
||||||
|
IF_FIELD(strMinQueryLength);
|
||||||
|
{
|
||||||
|
if (!BSON_ITER_HOLDS_INT32(iter)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'strMinQueryLength' must be an int32");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const int32_t val = bson_iter_int32(iter);
|
||||||
|
if (val <= 0) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'strMinQueryLength' must be greater than zero");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
txio->strMinQueryLength = val;
|
||||||
|
}
|
||||||
|
END_IF_FIELD;
|
||||||
|
|
||||||
|
IF_FIELD(strMaxQueryLength);
|
||||||
|
{
|
||||||
|
if (!BSON_ITER_HOLDS_INT32(iter)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'strMaxQueryLength' must be an int32");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const int32_t val = bson_iter_int32(iter);
|
||||||
|
if (val <= 0) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'strMaxQueryLength' must be greater than zero");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
txio->strMaxQueryLength = val;
|
||||||
|
}
|
||||||
|
END_IF_FIELD;
|
||||||
|
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Unrecognized field: '%s'", field);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mc_TextOpts_parse(mc_TextOpts_t *txo, const bson_t *in, mongocrypt_status_t *status) {
|
||||||
|
bson_iter_t iter = {0};
|
||||||
|
BSON_ASSERT_PARAM(txo);
|
||||||
|
BSON_ASSERT_PARAM(in);
|
||||||
|
BSON_ASSERT(status || true);
|
||||||
|
bool has_caseSensitive = false, has_diacriticSensitive = false, has_substring = false, has_prefix = false,
|
||||||
|
has_suffix = false;
|
||||||
|
|
||||||
|
*txo = (mc_TextOpts_t){{0}};
|
||||||
|
if (!bson_iter_init(&iter, in)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Invalid BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bson_iter_next(&iter)) {
|
||||||
|
const char *field = bson_iter_key(&iter);
|
||||||
|
IF_FIELD(caseSensitive);
|
||||||
|
{
|
||||||
|
if (!BSON_ITER_HOLDS_BOOL(&iter)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Expected bool for caseSensitive, got: %s",
|
||||||
|
mc_bson_type_to_string(bson_iter_type(&iter)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
txo->caseSensitive = bson_iter_bool(&iter);
|
||||||
|
}
|
||||||
|
END_IF_FIELD;
|
||||||
|
|
||||||
|
IF_FIELD(diacriticSensitive);
|
||||||
|
{
|
||||||
|
if (!BSON_ITER_HOLDS_BOOL(&iter)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Expected bool for diacriticSensitive, got: %s",
|
||||||
|
mc_bson_type_to_string(bson_iter_type(&iter)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
txo->diacriticSensitive = bson_iter_bool(&iter);
|
||||||
|
}
|
||||||
|
END_IF_FIELD;
|
||||||
|
|
||||||
|
IF_FIELD(substring);
|
||||||
|
{
|
||||||
|
bson_iter_t subdoc;
|
||||||
|
if (!BSON_ITER_HOLDS_DOCUMENT(&iter) || !bson_iter_recurse(&iter, &subdoc)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Expected document for substring, got: %s",
|
||||||
|
mc_bson_type_to_string(bson_iter_type(&iter)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mc_TextOptsPerIndex_parse(&txo->substring, &subdoc, status)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!txo->substring.strMaxLength.set) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'strMaxLength' must be set for substring");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_IF_FIELD;
|
||||||
|
|
||||||
|
IF_FIELD(prefix);
|
||||||
|
{
|
||||||
|
bson_iter_t subdoc;
|
||||||
|
if (!BSON_ITER_HOLDS_DOCUMENT(&iter) || !bson_iter_recurse(&iter, &subdoc)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Expected document for prefix, got: %s",
|
||||||
|
mc_bson_type_to_string(bson_iter_type(&iter)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mc_TextOptsPerIndex_parse(&txo->prefix, &subdoc, status)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txo->prefix.strMaxLength.set) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'strMaxLength' is not allowed in 'prefix'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_IF_FIELD;
|
||||||
|
|
||||||
|
IF_FIELD(suffix);
|
||||||
|
{
|
||||||
|
bson_iter_t subdoc;
|
||||||
|
if (!BSON_ITER_HOLDS_DOCUMENT(&iter) || !bson_iter_recurse(&iter, &subdoc)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Expected document for suffix, got: %s",
|
||||||
|
mc_bson_type_to_string(bson_iter_type(&iter)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mc_TextOptsPerIndex_parse(&txo->suffix, &subdoc, status)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txo->suffix.strMaxLength.set) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'strMaxLength' is not allowed in 'suffix'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_IF_FIELD;
|
||||||
|
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Unrecognized field: '%s'", field);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!has_caseSensitive) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'caseSensitive' is required");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!has_diacriticSensitive) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "'diacriticSensitive' is required");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (has_substring && (has_prefix || has_suffix)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Cannot specify 'substring' with 'prefix' or 'suffix'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(has_prefix || has_suffix || has_substring)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "One of 'prefix', 'suffix', or 'substring' is required");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ERROR_PREFIX
|
||||||
|
#define ERROR_PREFIX "Error making FLE2RangeInsertSpec: "
|
||||||
|
|
||||||
|
static bool append_TextOptsPerIndex(const mc_TextOptsPerIndex_t *txio, bson_t *out, mongocrypt_status_t *status) {
|
||||||
|
if (txio->strMaxLength.set) {
|
||||||
|
if (!bson_append_int32(out, "mlen", -1, txio->strMaxLength.value)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bson_append_int32(out, "ub", -1, txio->strMaxQueryLength)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bson_append_int32(out, "lb", -1, txio->strMinQueryLength)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mc_TextOpts_to_FLE2TextSearchInsertSpec(const mc_TextOpts_t *txo,
|
||||||
|
const bson_t *v,
|
||||||
|
bson_t *out,
|
||||||
|
mongocrypt_status_t *status) {
|
||||||
|
BSON_ASSERT_PARAM(txo);
|
||||||
|
BSON_ASSERT_PARAM(v);
|
||||||
|
BSON_ASSERT_PARAM(out);
|
||||||
|
BSON_ASSERT(status || true);
|
||||||
|
|
||||||
|
bson_iter_t v_iter;
|
||||||
|
if (!bson_iter_init_find(&v_iter, v, "v")) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Unable to find 'v' in input");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bson_t child;
|
||||||
|
if (!BSON_APPEND_DOCUMENT_BEGIN(out, "v", &child)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!bson_append_iter(&child, "v", 1, &v_iter)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!bson_append_bool(&child, "casef", -1, txo->caseSensitive)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bson_append_bool(&child, "diacf", -1, txo->diacriticSensitive)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txo->prefix.set) {
|
||||||
|
bson_t insert_spec;
|
||||||
|
if (!BSON_APPEND_DOCUMENT_BEGIN(&child, "prefix", &insert_spec)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!append_TextOptsPerIndex(&txo->prefix, &insert_spec, status)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bson_append_document_end(&child, &insert_spec)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txo->suffix.set) {
|
||||||
|
bson_t insert_spec;
|
||||||
|
if (!BSON_APPEND_DOCUMENT_BEGIN(&child, "suffix", &insert_spec)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!append_TextOptsPerIndex(&txo->suffix, &insert_spec, status)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bson_append_document_end(&child, &insert_spec)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txo->substring.set) {
|
||||||
|
bson_t insert_spec;
|
||||||
|
if (!BSON_APPEND_DOCUMENT_BEGIN(&child, "substr", &insert_spec)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!append_TextOptsPerIndex(&txo->substring, &insert_spec, status)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bson_append_document_end(&child, &insert_spec)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bson_append_document_end(out, &child)) {
|
||||||
|
CLIENT_ERR(ERROR_PREFIX "Error appending to BSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ERROR_PREFIX
|
||||||
|
|
@ -1096,10 +1096,7 @@ static bool _fle2_finalize(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out) {
|
||||||
|
|
||||||
BSON_ASSERT(context_uses_fle2(ctx));
|
BSON_ASSERT(context_uses_fle2(ctx));
|
||||||
BSON_ASSERT(ctx->state == MONGOCRYPT_CTX_READY);
|
BSON_ASSERT(ctx->state == MONGOCRYPT_CTX_READY);
|
||||||
|
BSON_ASSERT(!ectx->explicit);
|
||||||
if (ectx->explicit) {
|
|
||||||
return _mongocrypt_ctx_fail_w_msg(ctx, "explicit encryption is not yet supported. See MONGOCRYPT-409.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_mongocrypt_buffer_to_bson(&ectx->original_cmd, &original_cmd_bson)) {
|
if (!_mongocrypt_buffer_to_bson(&ectx->original_cmd, &original_cmd_bson)) {
|
||||||
return _mongocrypt_ctx_fail_w_msg(ctx, "malformed bson in original_cmd");
|
return _mongocrypt_ctx_fail_w_msg(ctx, "malformed bson in original_cmd");
|
||||||
|
|
@ -1303,7 +1300,7 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *
|
||||||
|
|
||||||
if (ctx->opts.rangeopts.set && ctx->opts.query_type.set) {
|
if (ctx->opts.rangeopts.set && ctx->opts.query_type.set) {
|
||||||
// RangeOpts with query type is a special case. The result contains two
|
// RangeOpts with query type is a special case. The result contains two
|
||||||
// ciphertext values.
|
// ciphertext values of FLE2RangeFindSpec.
|
||||||
return FLE2RangeFindDriverSpec_to_ciphertexts(ctx, out);
|
return FLE2RangeFindDriverSpec_to_ciphertexts(ctx, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1317,6 +1314,9 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *
|
||||||
_mongocrypt_ctx_fail_w_msg(ctx, "Cannot use rangePreview query type with Range V2");
|
_mongocrypt_ctx_fail_w_msg(ctx, "Cannot use rangePreview query type with Range V2");
|
||||||
goto fail;
|
goto fail;
|
||||||
// fallthrough
|
// fallthrough
|
||||||
|
case MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW:
|
||||||
|
case MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW:
|
||||||
|
case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW:
|
||||||
case MONGOCRYPT_QUERY_TYPE_RANGE:
|
case MONGOCRYPT_QUERY_TYPE_RANGE:
|
||||||
case MONGOCRYPT_QUERY_TYPE_EQUALITY: marking.u.fle2.type = MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND; break;
|
case MONGOCRYPT_QUERY_TYPE_EQUALITY: marking.u.fle2.type = MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND; break;
|
||||||
default: _mongocrypt_ctx_fail_w_msg(ctx, "Invalid value for EncryptOpts.queryType"); goto fail;
|
default: _mongocrypt_ctx_fail_w_msg(ctx, "Invalid value for EncryptOpts.queryType"); goto fail;
|
||||||
|
|
@ -1333,6 +1333,7 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *
|
||||||
goto fail;
|
goto fail;
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case MONGOCRYPT_INDEX_TYPE_RANGE: marking.u.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_RANGE; break;
|
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;
|
||||||
default:
|
default:
|
||||||
// This might be unreachable because of other validation. Better safe than
|
// This might be unreachable because of other validation. Better safe than
|
||||||
// sorry.
|
// sorry.
|
||||||
|
|
@ -1342,8 +1343,7 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *
|
||||||
|
|
||||||
if (ctx->opts.rangeopts.set) {
|
if (ctx->opts.rangeopts.set) {
|
||||||
// Process the RangeOpts and the input 'v' document into a new 'v'.
|
// Process the RangeOpts and the input 'v' document into a new 'v'.
|
||||||
// The new 'v' document will be a FLE2RangeFindSpec or
|
// The new 'v' document will be a FLE2RangeInsertSpec.
|
||||||
// FLE2RangeInsertSpec.
|
|
||||||
bson_t old_v;
|
bson_t old_v;
|
||||||
|
|
||||||
if (!_mongocrypt_buffer_to_bson(&ectx->original_cmd, &old_v)) {
|
if (!_mongocrypt_buffer_to_bson(&ectx->original_cmd, &old_v)) {
|
||||||
|
|
@ -1365,6 +1365,22 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *
|
||||||
|
|
||||||
marking.u.fle2.sparsity = ctx->opts.rangeopts.value.sparsity;
|
marking.u.fle2.sparsity = ctx->opts.rangeopts.value.sparsity;
|
||||||
|
|
||||||
|
} else if (ctx->opts.textopts.set) {
|
||||||
|
bson_t old_v;
|
||||||
|
|
||||||
|
if (!_mongocrypt_buffer_to_bson(&ectx->original_cmd, &old_v)) {
|
||||||
|
_mongocrypt_ctx_fail_w_msg(ctx, "unable to convert input to BSON");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (!mc_TextOpts_to_FLE2TextSearchInsertSpec(&ctx->opts.textopts.value, &old_v, &new_v, ctx->status)) {
|
||||||
|
_mongocrypt_ctx_fail(ctx);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bson_iter_init_find(&marking.u.fle2.v_iter, &new_v, "v")) {
|
||||||
|
_mongocrypt_ctx_fail_w_msg(ctx, "invalid input BSON, must contain 'v'");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
bson_t as_bson;
|
bson_t as_bson;
|
||||||
|
|
||||||
|
|
@ -1842,6 +1858,25 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms
|
||||||
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set query type with no index type");
|
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set query type with no index type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->opts.query_type.set) {
|
||||||
|
const mongocrypt_query_type_t qt = ctx->opts.query_type.value;
|
||||||
|
if (qt == MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW) {
|
||||||
|
if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW)) {
|
||||||
|
return _mongocrypt_ctx_fail_w_msg(ctx, "prefixPreview query type requires textPreview index type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (qt == MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW) {
|
||||||
|
if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW)) {
|
||||||
|
return _mongocrypt_ctx_fail_w_msg(ctx, "suffixPreview query type requires textPreview 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.rangeopts.set && ctx->opts.index_type.set) {
|
if (ctx->opts.rangeopts.set && ctx->opts.index_type.set) {
|
||||||
if (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_NONE) {
|
if (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_NONE) {
|
||||||
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set range opts with no index type");
|
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set range opts with no index type");
|
||||||
|
|
@ -1850,6 +1885,16 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms
|
||||||
if (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_EQUALITY) {
|
if (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_EQUALITY) {
|
||||||
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set range opts with equality index type");
|
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.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.contention_factor.set && !mc_validate_contention(ctx->opts.contention_factor.value, ctx->status)) {
|
if (ctx->opts.contention_factor.set && !mc_validate_contention(ctx->opts.contention_factor.value, ctx->status)) {
|
||||||
|
|
@ -1895,6 +1940,12 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms
|
||||||
case MONGOCRYPT_QUERY_TYPE_EQUALITY:
|
case MONGOCRYPT_QUERY_TYPE_EQUALITY:
|
||||||
matches = (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_EQUALITY);
|
matches = (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_EQUALITY);
|
||||||
break;
|
break;
|
||||||
|
// fallthrough
|
||||||
|
case MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW:
|
||||||
|
case MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW:
|
||||||
|
case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW:
|
||||||
|
matches = (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
CLIENT_ERR("unsupported value for query_type: %d", (int)ctx->opts.query_type.value);
|
CLIENT_ERR("unsupported value for query_type: %d", (int)ctx->opts.query_type.value);
|
||||||
return _mongocrypt_ctx_fail(ctx);
|
return _mongocrypt_ctx_fail(ctx);
|
||||||
|
|
@ -2172,7 +2223,8 @@ _check_cmd_for_auto_encrypt(mongocrypt_binary_t *cmd, bool *bypass, char **targe
|
||||||
eligible = true;
|
eligible = true;
|
||||||
} else if (0 == strcmp(cmd_name, "hello")) {
|
} else if (0 == strcmp(cmd_name, "hello")) {
|
||||||
*bypass = true;
|
*bypass = true;
|
||||||
} else if (0 == strcmp(cmd_name, "buildInfo")) {
|
} else if (0 == strcmp(cmd_name, "buildInfo") || 0 == strcmp(cmd_name, "buildinfo")) {
|
||||||
|
// Accept either case form to match server behavior.
|
||||||
*bypass = true;
|
*bypass = true;
|
||||||
} else if (0 == strcmp(cmd_name, "getCmdLineOpts")) {
|
} else if (0 == strcmp(cmd_name, "getCmdLineOpts")) {
|
||||||
*bypass = true;
|
*bypass = true;
|
||||||
|
|
@ -2186,6 +2238,8 @@ _check_cmd_for_auto_encrypt(mongocrypt_binary_t *cmd, bool *bypass, char **targe
|
||||||
*bypass = true;
|
*bypass = true;
|
||||||
} else if (0 == strcmp(cmd_name, "updateSearchIndex")) {
|
} else if (0 == strcmp(cmd_name, "updateSearchIndex")) {
|
||||||
*bypass = true;
|
*bypass = true;
|
||||||
|
} else if (0 == strcmp(cmd_name, "serverStatus")) {
|
||||||
|
*bypass = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* database/client commands are ineligible. */
|
/* database/client commands are ineligible. */
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include "mc-optional-private.h"
|
#include "mc-optional-private.h"
|
||||||
#include "mc-rangeopts-private.h"
|
#include "mc-rangeopts-private.h"
|
||||||
#include "mc-schema-broker-private.h"
|
#include "mc-schema-broker-private.h"
|
||||||
|
#include "mc-textopts-private.h"
|
||||||
#include "mongocrypt-buffer-private.h"
|
#include "mongocrypt-buffer-private.h"
|
||||||
#include "mongocrypt-endpoint-private.h"
|
#include "mongocrypt-endpoint-private.h"
|
||||||
#include "mongocrypt-key-broker-private.h"
|
#include "mongocrypt-key-broker-private.h"
|
||||||
|
|
@ -37,19 +38,15 @@ typedef enum {
|
||||||
_MONGOCRYPT_TYPE_COMPACT,
|
_MONGOCRYPT_TYPE_COMPACT,
|
||||||
} _mongocrypt_ctx_type_t;
|
} _mongocrypt_ctx_type_t;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
MONGOCRYPT_INDEX_TYPE_NONE = 1,
|
|
||||||
MONGOCRYPT_INDEX_TYPE_EQUALITY = 2,
|
|
||||||
MONGOCRYPT_INDEX_TYPE_RANGE = 3,
|
|
||||||
MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED = 4
|
|
||||||
} mongocrypt_index_type_t;
|
|
||||||
|
|
||||||
const char *_mongocrypt_index_type_to_string(mongocrypt_index_type_t val);
|
const char *_mongocrypt_index_type_to_string(mongocrypt_index_type_t val);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MONGOCRYPT_QUERY_TYPE_EQUALITY = 1,
|
MONGOCRYPT_QUERY_TYPE_EQUALITY = 1,
|
||||||
MONGOCRYPT_QUERY_TYPE_RANGE = 2,
|
MONGOCRYPT_QUERY_TYPE_RANGE = 2,
|
||||||
MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED = 3
|
MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED = 3,
|
||||||
|
MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW = 4,
|
||||||
|
MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW = 5,
|
||||||
|
MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW = 6,
|
||||||
} mongocrypt_query_type_t;
|
} mongocrypt_query_type_t;
|
||||||
|
|
||||||
const char *_mongocrypt_query_type_to_string(mongocrypt_query_type_t val);
|
const char *_mongocrypt_query_type_to_string(mongocrypt_query_type_t val);
|
||||||
|
|
@ -87,6 +84,11 @@ typedef struct __mongocrypt_ctx_opts_t {
|
||||||
mc_RangeOpts_t value;
|
mc_RangeOpts_t value;
|
||||||
bool set;
|
bool set;
|
||||||
} rangeopts;
|
} rangeopts;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
mc_TextOpts_t value;
|
||||||
|
bool set;
|
||||||
|
} textopts;
|
||||||
} _mongocrypt_ctx_opts_t;
|
} _mongocrypt_ctx_opts_t;
|
||||||
|
|
||||||
// `_mongocrypt_ctx_opts_t` inherits extended alignment from libbson. To dynamically allocate, use
|
// `_mongocrypt_ctx_opts_t` inherits extended alignment from libbson. To dynamically allocate, use
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,12 @@
|
||||||
|
|
||||||
#include <bson/bson.h>
|
#include <bson/bson.h>
|
||||||
|
|
||||||
|
#include "mc-textopts-private.h"
|
||||||
|
#include "mlib/str.h"
|
||||||
|
#include "mongocrypt-binary-private.h"
|
||||||
#include "mongocrypt-ctx-private.h"
|
#include "mongocrypt-ctx-private.h"
|
||||||
#include "mongocrypt-key-broker-private.h"
|
#include "mongocrypt-key-broker-private.h"
|
||||||
|
#include "mongocrypt-private.h"
|
||||||
|
|
||||||
bool _mongocrypt_ctx_fail_w_msg(mongocrypt_ctx_t *ctx, const char *msg) {
|
bool _mongocrypt_ctx_fail_w_msg(mongocrypt_ctx_t *ctx, const char *msg) {
|
||||||
BSON_ASSERT_PARAM(ctx);
|
BSON_ASSERT_PARAM(ctx);
|
||||||
|
|
@ -264,6 +268,9 @@ 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))) {
|
} 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'");
|
_mongocrypt_ctx_fail_w_msg(ctx, "Algorithm 'rangePreview' is deprecated, please use 'range'");
|
||||||
return false;
|
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;
|
||||||
|
ctx->opts.index_type.set = true;
|
||||||
} else {
|
} else {
|
||||||
char *error = bson_strdup_printf("unsupported algorithm string \"%.*s\"",
|
char *error = bson_strdup_printf("unsupported algorithm string \"%.*s\"",
|
||||||
algo_str.len <= (size_t)INT_MAX ? (int)algo_str.len : INT_MAX,
|
algo_str.len <= (size_t)INT_MAX ? (int)algo_str.len : INT_MAX,
|
||||||
|
|
@ -1066,6 +1073,15 @@ bool mongocrypt_ctx_setopt_query_type(mongocrypt_ctx_t *ctx, const char *query_t
|
||||||
} else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED_STR))) {
|
} else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED_STR))) {
|
||||||
_mongocrypt_ctx_fail_w_msg(ctx, "Query type 'rangePreview' is deprecated, please use 'range'");
|
_mongocrypt_ctx_fail_w_msg(ctx, "Query type 'rangePreview' is deprecated, please use 'range'");
|
||||||
return false;
|
return false;
|
||||||
|
} else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_STR))) {
|
||||||
|
ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW;
|
||||||
|
ctx->opts.query_type.set = true;
|
||||||
|
} else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_STR))) {
|
||||||
|
ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW;
|
||||||
|
ctx->opts.query_type.set = true;
|
||||||
|
} 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;
|
||||||
} else {
|
} else {
|
||||||
/* don't check if qt_str.len fits in int; we want the diagnostic output */
|
/* don't check if qt_str.len fits in int; we want the diagnostic output */
|
||||||
char *error = bson_strdup_printf("Unsupported query_type \"%.*s\"",
|
char *error = bson_strdup_printf("Unsupported query_type \"%.*s\"",
|
||||||
|
|
@ -1084,6 +1100,7 @@ const char *_mongocrypt_index_type_to_string(mongocrypt_index_type_t val) {
|
||||||
case MONGOCRYPT_INDEX_TYPE_EQUALITY: return "Equality";
|
case MONGOCRYPT_INDEX_TYPE_EQUALITY: return "Equality";
|
||||||
case MONGOCRYPT_INDEX_TYPE_RANGE: return "Range";
|
case MONGOCRYPT_INDEX_TYPE_RANGE: return "Range";
|
||||||
case MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED: return "RangePreview";
|
case MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED: return "RangePreview";
|
||||||
|
case MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW: return "TextPreview";
|
||||||
default: return "Unknown";
|
default: return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1093,6 +1110,9 @@ const char *_mongocrypt_query_type_to_string(mongocrypt_query_type_t val) {
|
||||||
case MONGOCRYPT_QUERY_TYPE_EQUALITY: return "Equality";
|
case MONGOCRYPT_QUERY_TYPE_EQUALITY: return "Equality";
|
||||||
case MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED: return "RangePreview";
|
case MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED: return "RangePreview";
|
||||||
case MONGOCRYPT_QUERY_TYPE_RANGE: return "Range";
|
case MONGOCRYPT_QUERY_TYPE_RANGE: return "Range";
|
||||||
|
case MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW: return "PrefixPreview";
|
||||||
|
case MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW: return "SuffixPreview";
|
||||||
|
case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW: return "SubstringPreview";
|
||||||
default: return "Unknown";
|
default: return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1127,3 +1147,32 @@ bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_bin
|
||||||
ctx->opts.rangeopts.set = true;
|
ctx->opts.rangeopts.set = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mongocrypt_ctx_setopt_algorithm_text(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *opts) {
|
||||||
|
bson_t as_bson;
|
||||||
|
if (!ctx) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->initialized) {
|
||||||
|
return _mongocrypt_ctx_fail_w_msg(ctx, "cannot set options after init");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->state == MONGOCRYPT_CTX_ERROR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->opts.textopts.set) {
|
||||||
|
return _mongocrypt_ctx_fail_w_msg(ctx, "TextOpts already set");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_mongocrypt_binary_to_bson(opts, &as_bson)) {
|
||||||
|
return _mongocrypt_ctx_fail_w_msg(ctx, "invalid BSON");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mc_TextOpts_parse(&ctx->opts.textopts.value, &as_bson, ctx->status)) {
|
||||||
|
return _mongocrypt_ctx_fail(ctx);
|
||||||
|
}
|
||||||
|
ctx->opts.textopts.set = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,14 @@ typedef enum {
|
||||||
MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH = 4
|
MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH = 4
|
||||||
} mongocrypt_fle2_encryption_algorithm_t;
|
} mongocrypt_fle2_encryption_algorithm_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MONGOCRYPT_INDEX_TYPE_NONE = 1,
|
||||||
|
MONGOCRYPT_INDEX_TYPE_EQUALITY = 2,
|
||||||
|
MONGOCRYPT_INDEX_TYPE_RANGE = 3,
|
||||||
|
MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED = 4,
|
||||||
|
MONGOCRYPT_INDEX_TYPE_TEXTPREVIEW = 5,
|
||||||
|
} mongocrypt_index_type_t;
|
||||||
|
|
||||||
bool _mongocrypt_validate_and_copy_string(const char *in, int32_t in_len, char **out) MONGOCRYPT_WARN_UNUSED_RESULT;
|
bool _mongocrypt_validate_and_copy_string(const char *in, int32_t in_len, char **out) MONGOCRYPT_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
char *_mongocrypt_new_string_from_bytes(const void *in, int len);
|
char *_mongocrypt_new_string_from_bytes(const void *in, int len);
|
||||||
|
|
|
||||||
|
|
@ -712,6 +712,8 @@ bool mongocrypt_ctx_setopt_algorithm(mongocrypt_ctx_t *ctx, const char *algorith
|
||||||
// DEPRECATED: support "RangePreview" has been removed in favor of "range".
|
// DEPRECATED: support "RangePreview" has been removed in favor of "range".
|
||||||
#define MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR "RangePreview"
|
#define MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR "RangePreview"
|
||||||
#define MONGOCRYPT_ALGORITHM_RANGE_STR "Range"
|
#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"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identify the AWS KMS master key to use for creating a data key.
|
* Identify the AWS KMS master key to use for creating a data key.
|
||||||
|
|
@ -1530,6 +1532,34 @@ bool mongocrypt_ctx_setopt_query_type(mongocrypt_ctx_t *ctx, const char *query_t
|
||||||
MONGOCRYPT_EXPORT
|
MONGOCRYPT_EXPORT
|
||||||
bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *opts);
|
bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *opts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set options for explicit encryption with the "textPreview" algorithm.
|
||||||
|
*
|
||||||
|
* NOTE: "textPreview" is experimental only and may be removed in a future non-major release.
|
||||||
|
* @p opts is a BSON document of the form:
|
||||||
|
* {
|
||||||
|
* "caseSensitive": bool,
|
||||||
|
* . "diacriticSensitive": bool,
|
||||||
|
* . "prefix": Optional{
|
||||||
|
* . "strMaxQueryLength": Int32,
|
||||||
|
* . "strMinQueryLength": Int32,
|
||||||
|
* . },
|
||||||
|
* . "suffix": Optional{
|
||||||
|
* . "strMaxQueryLength": Int32,
|
||||||
|
* . "strMinQueryLength": Int32,
|
||||||
|
* . },
|
||||||
|
* . "substring": Optional{
|
||||||
|
* . "strMaxLength": Int32,
|
||||||
|
* . "strMaxQueryLength": Int32,
|
||||||
|
* . "strMinQueryLength": Int32,
|
||||||
|
* . },
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* "prefix" and "suffix" can both be set.
|
||||||
|
*/
|
||||||
|
MONGOCRYPT_EXPORT
|
||||||
|
bool mongocrypt_ctx_setopt_algorithm_text(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *opts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the expiration time for the data encryption key cache. Defaults to 60 seconds if not set.
|
* Set the expiration time for the data encryption key cache. Defaults to 60 seconds if not set.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,7 @@ if grep -q Microsoft /proc/version; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
NAME=libmongocrypt
|
NAME=libmongocrypt
|
||||||
# TODO SERVER-106496 Update version number
|
VERSION=1.15.0
|
||||||
VERSION=1.14.0
|
|
||||||
|
|
||||||
if grep -q Microsoft /proc/version; then
|
if grep -q Microsoft /proc/version; then
|
||||||
SRC_ROOT=$(wslpath -u $(powershell.exe -Command "Get-ChildItem Env:TEMP | Get-Content | Write-Host"))
|
SRC_ROOT=$(wslpath -u $(powershell.exe -Command "Get-ChildItem Env:TEMP | Get-Content | Write-Host"))
|
||||||
|
|
@ -44,9 +43,7 @@ if [ ! -d $SRC ]; then
|
||||||
$GIT_EXE clone https://github.com/mongodb/libmongocrypt $CLONE_DEST
|
$GIT_EXE clone https://github.com/mongodb/libmongocrypt $CLONE_DEST
|
||||||
|
|
||||||
pushd $SRC
|
pushd $SRC
|
||||||
# TODO: SERVER-106496 Revert back to `$VERSION` upon new release of libmongocrypt
|
$GIT_EXE checkout $VERSION
|
||||||
# $GIT_EXE checkout $VERSION
|
|
||||||
$GIT_EXE checkout 0840a84aa78578b50ef586ebbb12e5318108db9b
|
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue