diff --git a/ext/libmongocrypt/libmongocrypt/.evergreen/config.yml b/ext/libmongocrypt/libmongocrypt/.evergreen/config.yml index d228ae9..faa9dca 100755 --- a/ext/libmongocrypt/libmongocrypt/.evergreen/config.yml +++ b/ext/libmongocrypt/libmongocrypt/.evergreen/config.yml @@ -306,7 +306,7 @@ functions: script: | set -ex cd ./libmongocrypt/bindings/python - PYTHON=${PYTHON} ./release.sh + PYTHON=${PYTHON} ./scripts/release.sh "upload python release": - command: archive.targz_pack @@ -383,10 +383,7 @@ functions: script: | # Authenticate to artifactory. echo "${artifactory_password}" | docker login --password-stdin --username "${artifactory_username}" artifactory.corp.mongodb.com - # TODO(MONGOCRYPT-747): remove `--persist-build=false`. - # Pass `--persist-build=false` to avoid using Docker Hub. - # Earthly hardcodes use of docker/dockerfile-copy:v0.1.9 for the CACHE command. - bash ${workdir}/libmongocrypt/.evergreen/earthly.sh ${args} --persist-build=false + bash ${workdir}/libmongocrypt/.evergreen/earthly.sh ${args} sbom: - command: ec2.assume_role @@ -967,8 +964,6 @@ tasks: shell: bash script: |- set -o errexit - # Authenticate to artifactory for signing image. - echo "${artifactory_password}" | docker login --password-stdin --username "${artifactory_username}" artifactory.corp.mongodb.com # Copy file to sign into `libmongocrypt` directory to be used by Earthly. cp libmongocrypt_upload.tar.gz libmongocrypt - func: "earthly" # Sign tarball. diff --git a/ext/libmongocrypt/libmongocrypt/.evergreen/earthly.sh b/ext/libmongocrypt/libmongocrypt/.evergreen/earthly.sh index a0189a3..3b66e25 100755 --- a/ext/libmongocrypt/libmongocrypt/.evergreen/earthly.sh +++ b/ext/libmongocrypt/libmongocrypt/.evergreen/earthly.sh @@ -48,4 +48,4 @@ fi chmod a+x "$exe_path" -"$exe_path" --buildkit-image "artifactory.corp.mongodb.com/dockerhub/earthly/buildkitd:v${EARTHLY_VERSION}" "$@" +"$exe_path" "$@" diff --git a/ext/libmongocrypt/libmongocrypt/.github/workflows/codeql-actions.yml b/ext/libmongocrypt/libmongocrypt/.github/workflows/codeql-actions.yml index fecb95d..0304c03 100644 --- a/ext/libmongocrypt/libmongocrypt/.github/workflows/codeql-actions.yml +++ b/ext/libmongocrypt/libmongocrypt/.github/workflows/codeql-actions.yml @@ -10,6 +10,11 @@ on: workflow_dispatch: schedule: - cron: '17 10 * * 2' + workflow_call: + inputs: + ref: + required: true + type: string jobs: analyze-python: @@ -27,11 +32,12 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + ref: ${{ inputs.ref }} persist-credentials: false # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@28deaeda66b76a05916b6923827895f2b14ab387 # v3 with: languages: actions build-mode: none @@ -39,6 +45,6 @@ jobs: queries: security-extended - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@28deaeda66b76a05916b6923827895f2b14ab387 # v3 with: category: "/language:actions" diff --git a/ext/libmongocrypt/libmongocrypt/.github/workflows/codeql-python.yml b/ext/libmongocrypt/libmongocrypt/.github/workflows/codeql-python.yml index b8964e2..3970a00 100644 --- a/ext/libmongocrypt/libmongocrypt/.github/workflows/codeql-python.yml +++ b/ext/libmongocrypt/libmongocrypt/.github/workflows/codeql-python.yml @@ -42,7 +42,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@28deaeda66b76a05916b6923827895f2b14ab387 # v3 with: languages: python build-mode: none @@ -55,12 +55,12 @@ jobs: - name: Install package run: | cd bindings/python - export LIBMONGOCRYPT_VERSION=$(cat ./libmongocrypt-version.txt) + export LIBMONGOCRYPT_VERSION=$(cat ./scripts/libmongocrypt-version.txt) git fetch origin $LIBMONGOCRYPT_VERSION - bash release.sh + bash ./scripts/release.sh pip install dist/*.whl - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@28deaeda66b76a05916b6923827895f2b14ab387 # v3 with: category: "/language:python" diff --git a/ext/libmongocrypt/libmongocrypt/.github/workflows/dist-python.yml b/ext/libmongocrypt/libmongocrypt/.github/workflows/dist-python.yml index dd278d4..b25b84c 100644 --- a/ext/libmongocrypt/libmongocrypt/.github/workflows/dist-python.yml +++ b/ext/libmongocrypt/libmongocrypt/.github/workflows/dist-python.yml @@ -54,9 +54,9 @@ jobs: - name: Build and test dist files run: | - export LIBMONGOCRYPT_VERSION=$(cat ./libmongocrypt-version.txt) + export LIBMONGOCRYPT_VERSION=$(cat ./scripts/libmongocrypt-version.txt) git fetch origin $LIBMONGOCRYPT_VERSION - bash ./release.sh + bash ./scripts/release.sh - uses: actions/upload-artifact@v4 with: diff --git a/ext/libmongocrypt/libmongocrypt/.github/workflows/release-python.yml b/ext/libmongocrypt/libmongocrypt/.github/workflows/release-python.yml index 730500d..f87c3cc 100644 --- a/ext/libmongocrypt/libmongocrypt/.github/workflows/release-python.yml +++ b/ext/libmongocrypt/libmongocrypt/.github/workflows/release-python.yml @@ -3,9 +3,6 @@ name: Python Release on: workflow_dispatch: inputs: - version: - description: "The new version to set" - required: true following_version: description: "The post (dev) version to set" dry_run: @@ -24,7 +21,6 @@ env: # to 'false' when the input is set to 'false'. DRY_RUN: ${{ ! contains(inputs.dry_run, 'false') }} FOLLOWING_VERSION: ${{ inputs.following_version || '' }} - VERSION: ${{ inputs.version || '10.10.10.10' }} defaults: run: @@ -54,7 +50,6 @@ jobs: - uses: mongodb-labs/drivers-github-tools/python/pre-publish@v2 id: pre-publish with: - version: ${{ env.VERSION }} working_directory: ./bindings/python dry_run: ${{ env.DRY_RUN }} tag_template: "pymongocrypt-${VERSION}" @@ -66,14 +61,20 @@ jobs: with: ref: ${{ needs.pre-publish.outputs.version }} - static-scan: + static-python: needs: [pre-publish] uses: ./.github/workflows/codeql-python.yml with: ref: ${{ needs.pre-publish.outputs.version }} + static-actions: + needs: [pre-publish] + uses: ./.github/workflows/codeql-actions.yml + with: + ref: ${{ needs.pre-publish.outputs.version }} + publish: - needs: [build-dist, static-scan] + needs: [build-dist, static-python, static-actions] name: Upload release to PyPI runs-on: ubuntu-latest environment: release-python @@ -86,14 +87,14 @@ jobs: name: all-dist-${{ github.run_id }} path: dist/ - name: Publish package distributions to TestPyPI - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1 with: repository-url: https://test.pypi.org/legacy/ skip-existing: true attestations: ${{ env.DRY_RUN }} - name: Publish package distributions to PyPI if: startsWith(env.DRY_RUN, 'false') - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1 post-publish: needs: [publish] @@ -117,7 +118,6 @@ jobs: artifactory_username: ${{ vars.ARTIFACTORY_USERNAME }} - uses: mongodb-labs/drivers-github-tools/python/post-publish@v2 with: - version: ${{ env.VERSION }} following_version: ${{ env.FOLLOWING_VERSION }} working_directory: ./bindings/python product_name: ${{ env.PRODUCT_NAME }} diff --git a/ext/libmongocrypt/libmongocrypt/.github/workflows/test-python.yml b/ext/libmongocrypt/libmongocrypt/.github/workflows/test-python.yml index 9611273..b818692 100644 --- a/ext/libmongocrypt/libmongocrypt/.github/workflows/test-python.yml +++ b/ext/libmongocrypt/libmongocrypt/.github/workflows/test-python.yml @@ -40,6 +40,7 @@ jobs: if: github.repository_owner == 'mongodb' runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] python-version: ["3.8", "3.13"] @@ -59,6 +60,6 @@ jobs: if [ "${{ matrix.python-version }}" == "3.13" ]; then export PIP_PRE=1 fi - export LIBMONGOCRYPT_VERSION=$(cat ./libmongocrypt-version.txt) + export LIBMONGOCRYPT_VERSION=$(cat ./scripts/libmongocrypt-version.txt) git fetch origin $LIBMONGOCRYPT_VERSION - bash ./release.sh + bash ./scripts/release.sh diff --git a/ext/libmongocrypt/libmongocrypt/.github/workflows/zizmor.yml b/ext/libmongocrypt/libmongocrypt/.github/workflows/zizmor.yml index 36c084a..84a6484 100644 --- a/ext/libmongocrypt/libmongocrypt/.github/workflows/zizmor.yml +++ b/ext/libmongocrypt/libmongocrypt/.github/workflows/zizmor.yml @@ -19,7 +19,7 @@ jobs: with: persist-credentials: false - name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@v1 + uses: actions-rust-lang/setup-rust-toolchain@9d7e65c320fdb52dcd45ffaa68deb6c02c8754d9 # v1 - name: Get zizmor run: cargo install zizmor - name: Run zizmor @@ -27,7 +27,7 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@28deaeda66b76a05916b6923827895f2b14ab387 # v3 with: sarif_file: results.sarif category: zizmor diff --git a/ext/libmongocrypt/libmongocrypt/.pre-commit-config.yaml b/ext/libmongocrypt/libmongocrypt/.pre-commit-config.yaml index bbd2bbb..9d3a41a 100644 --- a/ext/libmongocrypt/libmongocrypt/.pre-commit-config.yaml +++ b/ext/libmongocrypt/libmongocrypt/.pre-commit-config.yaml @@ -53,6 +53,18 @@ repos: language: system types: [shell] +- repo: local + hooks: + - id: synchro + name: synchro + entry: bash ./bindings/python/scripts/synchro.sh + language: python + require_serial: true + fail_fast: true + additional_dependencies: + - ruff==0.1.3 + - unasync + - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. rev: v0.1.3 diff --git a/ext/libmongocrypt/libmongocrypt/CHANGELOG.md b/ext/libmongocrypt/libmongocrypt/CHANGELOG.md index 587a431..ade8096 100644 --- a/ext/libmongocrypt/libmongocrypt/CHANGELOG.md +++ b/ext/libmongocrypt/libmongocrypt/CHANGELOG.md @@ -1,4 +1,12 @@ # ChangeLog +## 1.14.0 +### Fixed +- Fix building against libbson with extra alignment enabled (`ENABLE_EXTRA_ALIGNMENT=ON`). +- Retry KMS encrypt request for context created by `mongocrypt_ctx_rewrap_many_datakey_init`. +### Improvements +- Improve performance of OpenSSL crypto operations. +- Improve error for incorrect path to crypt_shared library. + ## 1.13.2 ### Notes - Bump downloaded libbson version from 1.28.1 to 1.30.3. Fixes a CMake configure error on macOS with CMake 4. diff --git a/ext/libmongocrypt/libmongocrypt/CMakeLists.txt b/ext/libmongocrypt/libmongocrypt/CMakeLists.txt index 9b35079..1b03572 100644 --- a/ext/libmongocrypt/libmongocrypt/CMakeLists.txt +++ b/ext/libmongocrypt/libmongocrypt/CMakeLists.txt @@ -108,6 +108,7 @@ set (MONGOCRYPT_SOURCES src/mc-fle2-encryption-placeholder.c src/mc-fle2-find-equality-payload.c src/mc-fle2-find-equality-payload-v2.c + src/mc-fle2-find-text-payload.c src/mc-fle2-payload-iev.c src/mc-fle2-payload-iev-v2.c src/mc-fle2-payload-uev.c @@ -115,6 +116,7 @@ set (MONGOCRYPT_SOURCES src/mc-fle2-payload-uev-v2.c src/mc-fle2-rfds.c src/mc-fle2-tag-and-encrypted-metadata-block.c + src/mc-parse-utils.c src/mc-range-edge-generation.c src/mc-range-mincover.c src/mc-range-encoding.c @@ -469,6 +471,7 @@ set (TEST_MONGOCRYPT_SOURCES test/test-mc-fle2-encryption-placeholder.c test/test-mc-fle2-find-equality-payload-v2.c test/test-mc-fle2-find-range-payload-v2.c + test/test-mc-fle2-find-text-payload.c test/test-mc-fle2-payload-iev.c test/test-mc-fle2-payload-iev-v2.c test/test-mc-fle2-payload-iup.c @@ -533,6 +536,8 @@ target_compile_definitions (test-mongocrypt PRIVATE "TEST_MONGOCRYPT_OUTPUT_PATH=\"$\"" # Tell test-mongocrypt whether we have a real csfle library for testing TEST_MONGOCRYPT_HAVE_REAL_CRYPT_SHARED_LIB=$ + # Tell test-mongocrypt the path of the libmongocrypt shared library for testing. + "TEST_MONGOCRYPT_MONGOCRYPT_SHARED_PATH=\"$\"" ) add_test ( @@ -712,4 +717,3 @@ install ( COMPONENT Devel ) - diff --git a/ext/libmongocrypt/libmongocrypt/CODEOWNERS b/ext/libmongocrypt/libmongocrypt/CODEOWNERS index 9ffca16..81b647d 100644 --- a/ext/libmongocrypt/libmongocrypt/CODEOWNERS +++ b/ext/libmongocrypt/libmongocrypt/CODEOWNERS @@ -1,4 +1,7 @@ # Code Owners will automatically be added as reviewers on PRs +# Listing code owners is required by DRIVERS-3098 +* @mongodb/dbx-c-cxx + # Python Bindings -bindings/python @mongodb/dbx-python \ No newline at end of file +bindings/python @mongodb/dbx-python diff --git a/ext/libmongocrypt/libmongocrypt/Earthfile b/ext/libmongocrypt/libmongocrypt/Earthfile index 5c4707e..6885d8c 100644 --- a/ext/libmongocrypt/libmongocrypt/Earthfile +++ b/ext/libmongocrypt/libmongocrypt/Earthfile @@ -50,15 +50,16 @@ # • sles15 - OpenSUSE Leap 15.0 # • alpine - Alpine Linux 3.18 # - # When adding new environments, always pull from a fully-qualified image ID: + # When adding new environments, prefer an unqualified image ID with a version: # • DO NOT: "ubuntu" # • DO NOT: "ubuntu:latest" - # • DO NOT: "ubuntu:22.10" - # • DO: "artifactory.corp.mongodb.com/dockerhub/library/ubuntu:22.10" + # • DO NOT: "docker.io/library/ubuntu:22.10" + # • DO: "ubuntu:22.10" + # Use of an unqualified image ID may enable separate registry in CI and local development. # ### VERSION --use-cache-command 0.6 -FROM artifactory.corp.mongodb.com/dockerhub/library/alpine:3.16 +FROM alpine:3.16 WORKDIR /s init: @@ -125,24 +126,24 @@ ALPINE_SETUP: env.c6: # A CentOS 6 environment. - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/library/centos:6 + FROM +init --base=centos:6 DO +CENTOS6_SETUP env.c7: # A CentOS 7 environment. - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/library/centos:7 + FROM +init --base=centos:7 DO +REDHAT_SETUP env.rl8: # CentOS 8 is cancelled. Use RockyLinux 8 for our RHEL 8 environment. - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/library/rockylinux:8 + FROM +init --base=rockylinux:8 DO +REDHAT_SETUP # Utility command for Ubuntu environments ENV_UBUNTU: COMMAND ARG --required version - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/library/ubuntu:$version + FROM +init --base=ubuntu:$version DO +DEBIAN_SETUP env.u14: @@ -167,19 +168,19 @@ env.u22: env.amzn1: # An Amazon "1" environment. (AmazonLinux 2018) - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/library/amazonlinux:2018.03 + FROM +init --base=amazonlinux:2018.03 DO +AMZ_SETUP env.amzn2: # An AmazonLinux 2 environment - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/library/amazonlinux:2 + FROM +init --base=amazonlinux:2 DO +AMZ_SETUP # Utility command for Debian setup ENV_DEBIAN: COMMAND ARG --required version - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/library/debian:$version + FROM +init --base=debian:$version IF [ $version = "9.2" ] # Update source list for archived Debian stretch packages. # Refer: https://unix.stackexchange.com/a/743865/260858 @@ -208,11 +209,11 @@ env.deb12: env.sles15: # An OpenSUSE Leap 15.0 environment. - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/opensuse/leap:15.0 + FROM +init --base=opensuse/leap:15.0 DO +SLES_SETUP env.alpine: - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/library/alpine:3.18 + FROM +init --base=alpine:3.18 DO +ALPINE_SETUP # Utility: Warm-up obtaining CMake and Ninja for the build. This is usually @@ -259,7 +260,7 @@ BUILD_EXAMPLE_STATE_MACHINE: RUN cd /s && /s/example-state-machine rpm-build: - FROM +init --base artifactory.corp.mongodb.com/dockerhub/fedora:38 + FROM +init --base fedora:38 GIT CLONE https://src.fedoraproject.org/rpms/libmongocrypt.git /R # Install the packages listed by "BuildRequires" and rpm-build: RUN __install $(awk '/^BuildRequires:/ { print $2 }' /R/libmongocrypt.spec) \ @@ -275,7 +276,7 @@ rpm-build: rpm-install-runtime: # Install the runtime RPM - FROM +init --base artifactory.corp.mongodb.com/dockerhub/fedora:38 + FROM +init --base fedora:38 COPY +rpm-build/RPMS /tmp/libmongocrypt-rpm/ RUN dnf makecache RUN __install $(find /tmp/libmongocrypt-rpm/ -name 'libmongocrypt-1.*.rpm') @@ -325,7 +326,7 @@ deb-build: deb-install-runtime: # Install the runtime deb package - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/library/debian:unstable + FROM +init --base=debian:unstable COPY +deb-build/debs/libmongocrypt0*.deb /tmp/lmc.deb RUN __install /tmp/lmc.deb @@ -354,7 +355,7 @@ packaging-full-test: BUILD +rpm-runtime-test check-format: - FROM +init --base=artifactory.corp.mongodb.com/dockerhub/python:3.11.2-slim-buster + FROM +init --base=python:3.11.2-slim-buster RUN __install build-essential # To install `make` to install clang-format. RUN pip install pipx COPY etc/format* /X/etc/ diff --git a/ext/libmongocrypt/libmongocrypt/README.md b/ext/libmongocrypt/libmongocrypt/README.md index 4361f5c..6d38e1c 100644 --- a/ext/libmongocrypt/libmongocrypt/README.md +++ b/ext/libmongocrypt/libmongocrypt/README.md @@ -103,7 +103,7 @@ See [releasing](./doc/releasing.md). Distribution packages (i.e., .deb/.rpm) are built and published for several Linux distributions. The installation of these packages for supported platforms is documented here. ### Unstable Development Distribution Packages ### -To install the latest unstable development package, change `1.13` to `development` in the package URLs listed in the subsequent instructions. For example, `https://libmongocrypt.s3.amazonaws.com/apt/ubuntu /libmongocrypt/1.13` in the instructions would become `https://libmongocrypt.s3.amazonaws.com/apt/ubuntu /libmongocrypt/development`. Do not use the unstable version of libmongocrypt in a production environment. +To install the latest unstable development package, change `1.14` to `development` in the package URLs listed in the subsequent instructions. For example, `https://libmongocrypt.s3.amazonaws.com/apt/ubuntu /libmongocrypt/1.14` in the instructions would become `https://libmongocrypt.s3.amazonaws.com/apt/ubuntu /libmongocrypt/development`. Do not use the unstable version of libmongocrypt in a production environment. ### .deb Packages (Debian and Ubuntu) ### @@ -144,13 +144,13 @@ sudo sh -c 'curl -s --location https://pgp.mongodb.com/libmongocrypt.asc | gpg - Second, create a list entry for the repository. For Ubuntu systems (be sure to change `` to `xenial`, `bionic`, `focal`, or `jammy`, as appropriate to your system): ``` -echo "deb https://libmongocrypt.s3.amazonaws.com/apt/ubuntu /libmongocrypt/1.13 universe" | sudo tee /etc/apt/sources.list.d/libmongocrypt.list +echo "deb https://libmongocrypt.s3.amazonaws.com/apt/ubuntu /libmongocrypt/1.14 universe" | sudo tee /etc/apt/sources.list.d/libmongocrypt.list ``` For Debian systems (be sure to change `` to `stretch`, `buster`, `bullseye`, or `bookworm` as appropriate to your system): ``` -echo "deb https://libmongocrypt.s3.amazonaws.com/apt/debian /libmongocrypt/1.13 main" | sudo tee /etc/apt/sources.list.d/libmongocrypt.list +echo "deb https://libmongocrypt.s3.amazonaws.com/apt/debian /libmongocrypt/1.14 main" | sudo tee /etc/apt/sources.list.d/libmongocrypt.list ``` #### Package installation #### @@ -172,7 +172,7 @@ Create the file `/etc/yum.repos.d/libmongocrypt.repo` with contents: ``` [libmongocrypt] name=libmongocrypt repository -baseurl=https://libmongocrypt.s3.amazonaws.com/yum/redhat/$releasever/libmongocrypt/1.13/x86_64 +baseurl=https://libmongocrypt.s3.amazonaws.com/yum/redhat/$releasever/libmongocrypt/1.14/x86_64 gpgcheck=1 enabled=1 gpgkey=https://pgp.mongodb.com/libmongocrypt.asc @@ -191,7 +191,7 @@ Create the file `/etc/yum.repos.d/libmongocrypt.repo` with contents: ``` [libmongocrypt] name=libmongocrypt repository -baseurl=https://libmongocrypt.s3.amazonaws.com/yum/amazon/2023/libmongocrypt/1.13/x86_64 +baseurl=https://libmongocrypt.s3.amazonaws.com/yum/amazon/2023/libmongocrypt/1.14/x86_64 gpgcheck=1 enabled=1 gpgkey=https://pgp.mongodb.com/libmongocrypt.asc @@ -210,7 +210,7 @@ Create the file `/etc/yum.repos.d/libmongocrypt.repo` with contents: ``` [libmongocrypt] name=libmongocrypt repository -baseurl=https://libmongocrypt.s3.amazonaws.com/yum/amazon/2/libmongocrypt/1.13/x86_64 +baseurl=https://libmongocrypt.s3.amazonaws.com/yum/amazon/2/libmongocrypt/1.14/x86_64 gpgcheck=1 enabled=1 gpgkey=https://pgp.mongodb.com/libmongocrypt.asc @@ -229,7 +229,7 @@ Create the file `/etc/yum.repos.d/libmongocrypt.repo` with contents: ``` [libmongocrypt] name=libmongocrypt repository -baseurl=https://libmongocrypt.s3.amazonaws.com/yum/amazon/2013.03/libmongocrypt/1.13/x86_64 +baseurl=https://libmongocrypt.s3.amazonaws.com/yum/amazon/2013.03/libmongocrypt/1.14/x86_64 gpgcheck=1 enabled=1 gpgkey=https://pgp.mongodb.com/libmongocrypt.asc @@ -252,7 +252,7 @@ sudo rpm --import https://pgp.mongodb.com/libmongocrypt.asc Second, add the repository (be sure to change `` to `12` or `15`, as appropriate to your system): ``` -sudo zypper addrepo --gpgcheck "https://libmongocrypt.s3.amazonaws.com/zypper/suse//libmongocrypt/1.13/x86_64" libmongocrypt +sudo zypper addrepo --gpgcheck "https://libmongocrypt.s3.amazonaws.com/zypper/suse//libmongocrypt/1.14/x86_64" libmongocrypt ``` Finally, install the libmongocrypt packages: diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/.evergreen/integ-test.sh b/ext/libmongocrypt/libmongocrypt/bindings/python/.evergreen/integ-test.sh index cbf4e1f..52ee5ee 100755 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/.evergreen/integ-test.sh +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/.evergreen/integ-test.sh @@ -44,6 +44,11 @@ export PATH=$CRYPT_SHARED_DIR:$MONGODB_BINARIES:$PATH export TEST_CRYPT_SHARED="1" pytest --maxfail=10 -v -m encryption +# Now test with stable pymongo. +pip uninstall -y pymongo +pip install pymongo +pytest --maxfail=10 -v -m encryption + popd deactivate rm -rf .venv diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/.evergreen/test.sh b/ext/libmongocrypt/libmongocrypt/bindings/python/.evergreen/test.sh index 0e5b682..e49577c 100755 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/.evergreen/test.sh +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/.evergreen/test.sh @@ -86,7 +86,7 @@ for PYTHON_BINARY in "${PYTHONS[@]}"; do done # Verify the sbom file -LIBMONGOCRYPT_VERSION=$(cat ./libmongocrypt-version.txt) +LIBMONGOCRYPT_VERSION=$(cat ./scripts/libmongocrypt-version.txt) EXPECTED="pkg:github/mongodb/libmongocrypt@$LIBMONGOCRYPT_VERSION" if grep -q $EXPECTED sbom.json; then echo "SBOM is up to date!" diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/CHANGELOG.rst b/ext/libmongocrypt/libmongocrypt/bindings/python/CHANGELOG.rst index 146279f..7438166 100644 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/CHANGELOG.rst +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/CHANGELOG.rst @@ -1,6 +1,13 @@ Changelog ========= +Changes in Version 1.13.0 +------------------------- + +- Bundle libmongocrypt 1.13.1 in release wheels. +- Add support for the ``key_expiration_ms`` option to ``MongoCryptOptions``. +- Add support for ``$lookup`` in CSFLE and QE. + Changes in Version 1.12.0 ------------------------- diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/CONTRIBUTING.md b/ext/libmongocrypt/libmongocrypt/bindings/python/CONTRIBUTING.md new file mode 100644 index 0000000..a1a5983 --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/CONTRIBUTING.md @@ -0,0 +1,34 @@ +# Contributing to PyMongoCrypt + +## Asyncio considerations +PyMongoCrypt adds asyncio capability by modifying the source files in */asynchronous to */synchronous using [unasync](https://github.com/python-trio/unasync/) and some custom transforms. + +Where possible, edit the code in `*/asynchronous/*.py` and not the synchronous files. You can run `pre-commit run --all-files synchro` before running tests if you are testing synchronous code. + +To prevent the synchro hook from accidentally overwriting code, it first checks to see whether a sync version of a file is changing and not its async counterpart, and will fail. In the unlikely scenario that you want to override this behavior, first export `OVERRIDE_SYNCHRO_CHECK=1`. + +Sometimes, the synchro hook will fail and introduce changes many previously unmodified files. This is due to static Python errors, such as missing imports, incorrect syntax, or other fatal typos. To resolve these issues, run `pre-commit run --all-files --hook-stage manual ruff` and fix all reported errors before running the synchro hook again. + +## Updating the libmongocrypt bindings + +To update the libmongocrypt bindings in `pymongocrypt/binding.py`, run the following script: + +```bash +python scripts/update_binding.py +``` + +## Update the bundled version of libmongocrypt + +To update the bundled version of libmongocrypt, run the following script: + +```bash +bash script/update-version.sh +``` + +This will set the version in `scripts/libmongocrypt-version.sh` and update `sbom.json` to reflect +the new vendored version of `libmongocrypt`. + +## Building wheels + +To build wheels, run `scripts/release.sh`. It will build the appropriate wheel for the current system +on Windows and MacOS. If docker is available on Linux or MacOS, it will build the manylinux wheels. diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/libmongocrypt-version.txt b/ext/libmongocrypt/libmongocrypt/bindings/python/libmongocrypt-version.txt deleted file mode 100644 index 0eed1a2..0000000 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/libmongocrypt-version.txt +++ /dev/null @@ -1 +0,0 @@ -1.12.0 diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/state_machine.py b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/state_machine.py index 4468c7c..579093b 100644 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/state_machine.py +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/state_machine.py @@ -46,7 +46,7 @@ async def collection_info(self, database, filter): - `filter`: The filter to pass to listCollections. :Returns: - The first document from the listCollections command response as BSON. + The all or first document from the listCollections command response as BSON. """ @abstractmethod @@ -125,7 +125,11 @@ async def run_state_machine(ctx, callback): list_colls_filter = ctx.mongo_operation() coll_info = await callback.collection_info(ctx.database, list_colls_filter) if coll_info: - ctx.add_mongo_operation_result(coll_info) + if isinstance(coll_info, list): + for i in coll_info: + ctx.add_mongo_operation_result(i) + else: + ctx.add_mongo_operation_result(coll_info) ctx.complete_mongo_operation() elif state == lib.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS: mongocryptd_cmd = ctx.mongo_operation() diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binding.py b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binding.py index fe371a5..3d60dc8 100644 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binding.py +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binding.py @@ -29,9 +29,10 @@ def _parse_version(version): ffi = cffi.FFI() -# Generated with strip_header.py +# Start embedding from update_binding.py ffi.cdef( - """/* + """ +/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -323,6 +324,16 @@ def _parse_version(version): */ bool mongocrypt_setopt_retry_kms(mongocrypt_t *crypt, bool enable); +/** + * Enable support for multiple collection schemas. Required to support $lookup. + * + * @param[in] crypt The @ref mongocrypt_t object. + * @pre @ref mongocrypt_init has not been called on @p crypt. + * @returns A boolean indicating success. If false, an error status is set. + * Retrieve it with @ref mongocrypt_ctx_status + */ +bool mongocrypt_setopt_enable_multiple_collinfo(mongocrypt_t *crypt); + /** * Configure an AWS KMS provider on the @ref mongocrypt_t object. * @@ -1466,8 +1477,13 @@ def _parse_version(version): /// String constants for setopt_query_type // DEPRECATED: Support "rangePreview" has been removed in favor of "range". +/// NOTE: "substringPreview" is experimental and may be removed in a future non-major release. +/// NOTE: "suffixPreview" is experimental and may be removed in a future non-major release. +/// NOTE: "prefixPreview" is experimental and may be removed in a future non-major release. + """ ) +# End embedding from update_binding.py def _to_string(cdata): diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/mongocrypt.py b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/mongocrypt.py index edd6c2c..608d39e 100644 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/mongocrypt.py +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/mongocrypt.py @@ -96,6 +96,9 @@ def __init(self): if self.__opts.bypass_query_analysis: lib.mongocrypt_setopt_bypass_query_analysis(self.__crypt) + if self.__opts.enable_multiple_collinfo: + lib.mongocrypt_setopt_enable_multiple_collinfo(self.__crypt) + # Prefer using the native crypto binding when we know it's available. try: crypto_available = lib.mongocrypt_is_crypto_available() @@ -149,10 +152,15 @@ def __init(self): if any([on_demand_aws, on_demand_gcp, on_demand_azure]): lib.mongocrypt_setopt_use_need_kms_credentials_state(self.__crypt) - # Enable KMS retry when available, libmongocrypt >= 1.12.0, + # Enable KMS retry and key_expiration_ms when available, libmongocrypt >= 1.12.0, try: if not lib.mongocrypt_setopt_retry_kms(self.__crypt, True): self.__raise_from_status() + if self.__opts.key_expiration_ms is not None: + if not lib.mongocrypt_setopt_key_expiration( + self.__crypt, self.__opts.key_expiration_ms + ): + self.__raise_from_status() except AttributeError: # libmongocrypt < 1.12 pass diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/options.py b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/options.py index 6b905d4..c1e27b1 100644 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/options.py +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/options.py @@ -11,6 +11,8 @@ def __init__( crypt_shared_lib_path=None, crypt_shared_lib_required=False, bypass_encryption=False, + key_expiration_ms=None, + enable_multiple_collinfo=False, ): """Options for :class:`MongoCrypt`. @@ -53,6 +55,11 @@ def __init__( - `crypt_shared_lib_required`: Whether to require a crypt_shared library. - `bypass_encryption`: Whether to bypass encryption. + - `key_expiration_ms` (int): The cache expiration time for data + encryption keys. Defaults to 60000. 0 means keys never expire. + + .. versionadded:: 1.13 + Added the ``key_expiration_ms`` parameter. .. versionremoved:: 1.11 Removed the ``enable_range_v2`` parameter. @@ -136,6 +143,11 @@ def __init__( encrypted_fields_map, bytes ): raise TypeError("encrypted_fields_map must be bytes or None") + if key_expiration_ms is not None: + if not isinstance(key_expiration_ms, int): + raise TypeError("key_expiration_ms must be int or None") + if key_expiration_ms < 0: + raise ValueError("key_expiration_ms must be >=0 or None") self.kms_providers = kms_providers self.schema_map = schema_map @@ -144,6 +156,8 @@ def __init__( self.crypt_shared_lib_path = crypt_shared_lib_path self.crypt_shared_lib_required = crypt_shared_lib_required self.bypass_encryption = bypass_encryption + self.key_expiration_ms = key_expiration_ms + self.enable_multiple_collinfo = enable_multiple_collinfo class ExplicitEncryptOpts: diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/state_machine.py b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/state_machine.py index 76fb4cd..c65369b 100644 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/state_machine.py +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/state_machine.py @@ -46,7 +46,7 @@ def collection_info(self, database, filter): - `filter`: The filter to pass to listCollections. :Returns: - The first document from the listCollections command response as BSON. + The all or first document from the listCollections command response as BSON. """ @abstractmethod @@ -125,7 +125,11 @@ def run_state_machine(ctx, callback): list_colls_filter = ctx.mongo_operation() coll_info = callback.collection_info(ctx.database, list_colls_filter) if coll_info: - ctx.add_mongo_operation_result(coll_info) + if isinstance(coll_info, list): + for i in coll_info: + ctx.add_mongo_operation_result(i) + else: + ctx.add_mongo_operation_result(coll_info) ctx.complete_mongo_operation() elif state == lib.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS: mongocryptd_cmd = ctx.mongo_operation() diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/version.py b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/version.py index 8d6c325..ece884f 100644 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/version.py +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/version.py @@ -12,6 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "1.13.0.dev0" +__version__ = "1.14.0.dev0" _MIN_LIBMONGOCRYPT_VERSION = "1.8.0" diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/sbom.json b/ext/libmongocrypt/libmongocrypt/bindings/python/sbom.json index 5d59e54..7c2bb90 100644 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/sbom.json +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/sbom.json @@ -1,31 +1,31 @@ { "components": [ { - "bom-ref": "pkg:github/mongodb/libmongocrypt@1.12.0", + "bom-ref": "pkg:github/mongodb/libmongocrypt@1.13.1", "externalReferences": [ { "type": "distribution", - "url": "https://github.com/mongodb/libmongocrypt/archive/refs/tags/1.12.0.tar.gz" + "url": "https://github.com/mongodb/libmongocrypt/archive/refs/tags/1.13.1.tar.gz" }, { "type": "website", - "url": "https://github.com/mongodb/libmongocrypt/tree/1.12.0" + "url": "https://github.com/mongodb/libmongocrypt/tree/1.13.1" } ], "group": "mongodb", "name": "libmongocrypt", - "purl": "pkg:github/mongodb/libmongocrypt@1.12.0", + "purl": "pkg:github/mongodb/libmongocrypt@1.13.1", "type": "library", - "version": "1.12.0" + "version": "1.13.1" } ], "dependencies": [ { - "ref": "pkg:github/mongodb/libmongocrypt@1.12.0" + "ref": "pkg:github/mongodb/libmongocrypt@1.13.1" } ], "metadata": { - "timestamp": "2024-12-30T18:25:06.574241+00:00", + "timestamp": "2025-04-01T19:53:54.393395+00:00", "tools": [ { "externalReferences": [ @@ -68,7 +68,7 @@ } ] }, - "serialNumber": "urn:uuid:5e81b4d2-1313-43dd-9ec0-b958d0d71bca", + "serialNumber": "urn:uuid:a5e0a753-031f-43e3-ac20-f39b878c46e1", "version": 1, "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", "bomFormat": "CycloneDX", diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/build-manylinux-wheel.sh b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/build-manylinux-wheel.sh similarity index 100% rename from ext/libmongocrypt/libmongocrypt/bindings/python/build-manylinux-wheel.sh rename to ext/libmongocrypt/libmongocrypt/bindings/python/scripts/build-manylinux-wheel.sh diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/libmongocrypt-version.txt b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/libmongocrypt-version.txt new file mode 100644 index 0000000..b50dd27 --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/libmongocrypt-version.txt @@ -0,0 +1 @@ +1.13.1 diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/release.sh b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/release.sh similarity index 93% rename from ext/libmongocrypt/libmongocrypt/bindings/python/release.sh rename to ext/libmongocrypt/libmongocrypt/bindings/python/scripts/release.sh index 684b172..37bdced 100755 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/release.sh +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/release.sh @@ -15,14 +15,19 @@ set -o xtrace # Write all commands first to stderr set -o errexit # Exit the script with error if any of the commands fail +SCRIPT_DIR=$(dirname ${BASH_SOURCE:-$0}) + # The libmongocrypt git revision release to embed in our wheels. -LIBMONGOCRYPT_VERSION=$(cat ./libmongocrypt-version.txt) +LIBMONGOCRYPT_VERSION=$(cat $SCRIPT_DIR/libmongocrypt-version.txt) REVISION=$(git rev-list -n 1 $LIBMONGOCRYPT_VERSION) # The libmongocrypt release branch. -BRANCH="r1.12" +MINOR_VERSION=$(echo $LIBMONGOCRYPT_VERSION | cut -d. -f1,2) +BRANCH="r${MINOR_VERSION}" # The python executable to use. PYTHON=${PYTHON:-python} +pushd $SCRIPT_DIR/.. + # Clean slate. rm -rf dist .venv build libmongocrypt pymongocrypt/*.so pymongocrypt/*.dll pymongocrypt/*.dylib @@ -48,7 +53,7 @@ function build_wheel() { function build_manylinux_wheel() { python -m pip install unasync docker pull $1 - docker run --rm -v `pwd`:/python $1 /python/build-manylinux-wheel.sh + docker run --rm -v `pwd`:/python $1 /python/scripts/build-manylinux-wheel.sh # Sudo is needed to remove the files created by docker. sudo rm -rf build libmongocrypt pymongocrypt/*.so pymongocrypt/*.dll pymongocrypt/*.dylib } @@ -126,3 +131,4 @@ if [ $(command -v docker) ]; then fi ls -ltr dist +popd diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/synchro.py b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/synchro.py similarity index 69% rename from ext/libmongocrypt/libmongocrypt/bindings/python/synchro.py rename to ext/libmongocrypt/libmongocrypt/bindings/python/scripts/synchro.py index a9a6ba6..26737cc 100644 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/synchro.py +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/synchro.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os +import sys from os import listdir from pathlib import Path @@ -27,12 +29,14 @@ "aclose": "close", } -_base = "pymongocrypt" +ROOT = Path(__file__).absolute().parent.parent + +_base = ROOT / "pymongocrypt" async_files = [ - f"./{_base}/asynchronous/{f}" - for f in listdir("pymongocrypt/asynchronous") - if (Path(_base) / "asynchronous" / f).is_file() + f"{_base}/asynchronous/{f}" + for f in listdir(f"{_base}/asynchronous") + if (_base / "asynchronous" / f).is_file() ] @@ -40,20 +44,23 @@ async_files, [ Rule( - fromdir="/pymongocrypt/asynchronous/", - todir="/pymongocrypt/synchronous/", + fromdir=f"{_base}/asynchronous/", + todir=f"{_base}/synchronous/", additional_replacements=replacements, ) ], ) sync_files = [ - f"./{_base}/synchronous/{f}" - for f in listdir("pymongocrypt/synchronous") - if (Path(_base) / "synchronous" / f).is_file() + f"{_base}/synchronous/{f}" + for f in listdir(f"{_base}/synchronous") + if (_base / "synchronous" / f).is_file() ] +modified_files = [f"./{f}" for f in sys.argv[1:]] for file in sync_files: + if file in modified_files and "OVERRIDE_SYNCHRO_CHECK" not in os.environ: + raise ValueError(f"Refusing to overwrite {file}") with open(file, "r+") as f: lines = f.readlines() for i in range(len(lines)): diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/synchro.sh b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/synchro.sh new file mode 100755 index 0000000..70efcad --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/synchro.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -eu + +SCRIPT_DIR=$(dirname ${BASH_SOURCE:-$0}) + +python $SCRIPT_DIR/synchro.py "$@" +python -m ruff check $SCRIPT_DIR/../pymongocrypt/synchronous --fix --silent diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/update-version.sh b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/update-version.sh new file mode 100755 index 0000000..7bb6654 --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/update-version.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set -eu + +SCRIPT_DIR=$(dirname ${BASH_SOURCE:-$0}) + +if [ -z "${1:-}" ]; then + echo "Provide the new version of libmongocrypt!" + exit 1 +fi + +LIBMONGOCRYPT_VERSION=$1 + +echo $LIBMONGOCRYPT_VERSION > $SCRIPT_DIR/libmongocrypt-version.txt + +pushd $SCRIPT_DIR/.. +if [ $(command -v podman) ]; then + DOCKER=podman +else + DOCKER=docker +fi + +echo "pkg:github/mongodb/libmongocrypt@$LIBMONGOCRYPT_VERSION" > purls.txt +$DOCKER run --platform="linux/amd64" -it --rm -v $(pwd):$(pwd) artifactory.corp.mongodb.com/release-tools-container-registry-public-local/silkbomb:2.0 update --purls=$(pwd)/purls.txt -o $(pwd)/sbom.json +rm purls.txt + +popd diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/update_binding.py b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/update_binding.py new file mode 100644 index 0000000..6f13a76 --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/scripts/update_binding.py @@ -0,0 +1,78 @@ +# Copyright 2019-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. + +"""Update pymongocrypt/bindings.py using mongocrypt.h. +""" + +import re +from pathlib import Path + +DROP_RE = re.compile(r"^\s*(#|MONGOCRYPT_EXPORT)") +HERE = Path(__file__).absolute().parent + + +# itertools.pairwise backport for Python 3.9 support. +def pairwise(iterable): + # pairwise('ABCDEFG') → AB BC CD DE EF FG + + iterator = iter(iterable) + a = next(iterator, None) + + for b in iterator: + yield a, b + a = b + + +def strip_file(content): + fold = content.replace("\\\n", " ") + all_lines = [*fold.split("\n"), ""] + keep_lines = (line for line in all_lines if not DROP_RE.match(line)) + fin = "" + for line, peek in pairwise(keep_lines): + if peek == "" and line == "": + # Drop adjacent empty lines + continue + yield line + fin = peek + yield fin + + +def update_bindings(): + header_file = HERE.parent.parent.parent / "src/mongocrypt.h" + with header_file.open(encoding="utf-8") as fp: + header_lines = strip_file(fp.read()) + + target = HERE.parent / "pymongocrypt/binding.py" + source_lines = target.read_text().splitlines() + new_lines = [] + skip = False + for line in source_lines: + if not skip: + new_lines.append(line) + if line.strip() == "# Start embedding from update_binding.py": + skip = True + new_lines.append("ffi.cdef(") + new_lines.append('"""') + new_lines.extend(header_lines) + if line.strip() == "# End embedding from update_binding.py": + new_lines.append('"""') + new_lines.append(")") + new_lines.append(line) + skip = False + with target.open("w") as f: + f.write("\n".join(new_lines)) + + +if __name__ == "__main__": + update_bindings() diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/strip_header.py b/ext/libmongocrypt/libmongocrypt/bindings/python/strip_header.py deleted file mode 100644 index fcc5426..0000000 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/strip_header.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2019-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. - -"""Generate a CFFI.cdef() string from a C header file - -Usage (on macOS):: python strip_header.py ../../src/mongocrypt.h | pbcopy -""" - -import itertools -import re -import sys - -DROP_RE = re.compile(r"^\s*(#|MONGOCRYPT_EXPORT)") - - -def strip_file(content): - fold = content.replace("\\\n", " ") - all_lines = [*fold.split("\n"), ""] - keep_lines = (line for line in all_lines if not DROP_RE.match(line)) - fin = "" - for line, peek in itertools.pairwise(keep_lines): - if peek == "" and line == "": - # Drop adjacent empty lines - continue - yield line - fin = peek - yield fin - - -def strip(hdr): - with open(hdr) as fp: - out = strip_file(fp.read()) - print("\n".join(out)) # noqa: T201 - - -if __name__ == "__main__": - if len(sys.argv) != 2: - raise Exception("Usage: strip_header.py header.h") - strip(sys.argv[1]) diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_mongocrypt.py b/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_mongocrypt.py index 1160c73..f554123 100644 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_mongocrypt.py +++ b/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_mongocrypt.py @@ -143,6 +143,11 @@ def test_mongocrypt_options(self): ) self.assertEqual(opts.encrypted_fields_map, encrypted_fields_map) self.assertTrue(opts.bypass_query_analysis) + for expiration in [0, 1, 1000000]: + opts = MongoCryptOptions( + valid[0][0], schema_map, key_expiration_ms=expiration + ) + self.assertEqual(opts.key_expiration_ms, expiration) def test_mongocrypt_options_validation(self): with self.assertRaisesRegex( @@ -192,6 +197,12 @@ def test_mongocrypt_options_validation(self): TypeError, "encrypted_fields_map must be bytes or None" ): MongoCryptOptions(valid_kms, encrypted_fields_map={}) + with self.assertRaisesRegex(TypeError, "key_expiration_ms must be int or None"): + MongoCryptOptions(valid_kms, key_expiration_ms="123") + with self.assertRaisesRegex( + ValueError, "key_expiration_ms must be >=0 or None" + ): + MongoCryptOptions(valid_kms, key_expiration_ms=-1) class TestMongoCrypt(unittest.TestCase): @@ -507,6 +518,8 @@ def mongo_crypt_opts(): os.getenv("TEST_CRYPT_SHARED"), "this test requires TEST_CRYPT_SHARED=1" ) def test_crypt_shared(self): + if sys.platform == "darwin": + raise unittest.SkipTest("Skipping due to SERVER-101020") kms_providers = { "aws": {"accessKeyId": "example", "secretAccessKey": "example"}, "local": {"key": b"\x00" * 96}, @@ -638,6 +651,8 @@ def mongo_crypt_opts(): os.getenv("TEST_CRYPT_SHARED"), "this test requires TEST_CRYPT_SHARED=1" ) async def test_crypt_shared(self): + if sys.platform == "darwin": + raise unittest.SkipTest("Skipping due to SERVER-101020") kms_providers = { "aws": {"accessKeyId": "example", "secretAccessKey": "example"}, "local": {"key": b"\x00" * 96}, diff --git a/ext/libmongocrypt/libmongocrypt/bindings/python/update-sbom.sh b/ext/libmongocrypt/libmongocrypt/bindings/python/update-sbom.sh deleted file mode 100755 index e0c9031..0000000 --- a/ext/libmongocrypt/libmongocrypt/bindings/python/update-sbom.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -eux - -LIBMONGOCRYPT_VERSION=$(cat ./libmongocrypt-version.txt) -if [ $(command -v podman) ]; then - DOCKER=podman -else - DOCKER=docker -fi - -echo "pkg:github/mongodb/libmongocrypt@$LIBMONGOCRYPT_VERSION" > purls.txt -$DOCKER run --platform="linux/amd64" -it --rm -v $(pwd):$(pwd) artifactory.corp.mongodb.com/release-tools-container-registry-public-local/silkbomb:1.0 update --purls=$(pwd)/purls.txt -o $(pwd)/sbom.json -rm purls.txt diff --git a/ext/libmongocrypt/libmongocrypt/doc/releasing.md b/ext/libmongocrypt/libmongocrypt/doc/releasing.md index 4df019c..72e9097 100644 --- a/ext/libmongocrypt/libmongocrypt/doc/releasing.md +++ b/ext/libmongocrypt/libmongocrypt/doc/releasing.md @@ -19,7 +19,7 @@ Go to [Snyk](https://app.snyk.io/) and select the `dev-prod` organization. If ac ##### Update Snyk -Update the Snyk reference target tracking the to-be-released branch. For a patch release (e.g. x.y.z), check-out the `rx.y` branch and update the `rx.y` reference target. For a minor release (e.g. x.y.0), check out the `master` branch update the `master` reference target. +Update the Snyk reference target tracking the to-be-released branch. For a patch release (e.g. x.y.z), check-out the `rx.y` branch and update the `rx.y` reference target. For a non-patch release (e.g. x.y.0), check out the `master` branch and update the `master` reference target. Run `cmake` to ensure generated source files are present: ```bash @@ -61,14 +61,14 @@ Check the contents of the "vulnerabilities" field (if present) in the Augmented Do the following when releasing: - If this is a feature release (e.g. `x.y.0` or `x.0.0`), follow these steps: [Creating SSDLC static analysis reports](https://docs.google.com/document/d/1rkFL8ymbkc0k8Apky9w5pTPbvKRm68wj17mPJt2_0yo/edit). -- Check out the release branch. For a release `x.y.z`, the release branch is `rx.y`. If this is a new minor release (`x.y.0`), create the release branch. +- Check out the release branch. For a release `x.y.z`, the release branch is `rx.y`. If this is a new non-patch release (`x.y.0`), create the release branch. - Update CHANGELOG.md with the version being released. - Ensure `etc/purls.txt` is up-to-date. - Update `etc/third_party_vulnerabilities.md` with any updates to new or known vulnerabilities for third party dependencies that must be reported. -- If this is a new minor release (e.g. `x.y.0`): +- If this is a new non-patch release (e.g. `x.y.0`): - Update the Linux distribution package installation instructions in [README.md](../README.md) to refer to the new version `x.y`. - Update the [libmongocrypt-release](https://spruce.mongodb.com/project/libmongocrypt-release/settings/general) Evergreen project (requires auth) to set `Branch Name` to `rx.y`. -- Commit the changes on the `rx.y` branch with a message like "Update CHANGELOG.md for x.y.z". +- Commit the changes on the `rx.y` branch with a message like "Release x.y.z". - Tag the commit with `git tag -a `. - Push both the branch ref and tag ref in the same command: `git push origin master 1.8.0-alpha0` or `git push origin r1.8 1.8.4` - Pushing the branch ref and the tag ref in the same command eliminates the possibility of a race condition in Evergreen (for building resources based on the presence of a release tag) @@ -77,20 +77,20 @@ Do the following when releasing: - `upload-all` - `windows-upload-release` - All `publish-packages` tasks. - - If the `publish-packages` tasks fail with an error like `[curator] 2024/01/02 13:56:17 [p=emergency]: problem submitting repobuilder job: 404 (Not Found)`, this suggests the published path does not yet exist. Barque (the Linux package publishing service) has protection to avoid unintentional publishes. File a DEVPROD ticket ([example](https://jira.mongodb.org/browse/DEVPROD-4053)) and assign to the team called Release Infrastructure to request the path be created. Then re-run the failing `publish-packages` task. Ask in the slack channel `#devprod-release-tools` for further help with `Barque` or `curator`. + - If the `publish-packages` tasks fail with an error like `[curator] 2024/01/02 13:56:17 [p=emergency]: problem submitting repobuilder job: 404 (Not Found)`, this suggests the published path does not yet exist. Barque (the Linux package publishing service) has protection to avoid unintentional publishes. File a DEVPROD ticket ([example](https://jira.mongodb.org/browse/DEVPROD-15320)) and assign to the team called Release Infrastructure to request the path be created. Then re-run the failing `publish-packages` task. Ask in the slack channel `#ask-devprod-release-tools` for further help with `Barque` or `curator`. - Create the release from the GitHub releases page from the new tag. - - Attach the tarball and signature file from the Files tab of the `windows-upload-release` task. [Example](https://github.com/mongodb/libmongocrypt/releases/tag/1.10.0). + - Attach the tarball and signature file from the Files tab of the `windows-upload-release` task. [Example](https://github.com/mongodb/libmongocrypt/releases/tag/1.13.0). - Attach the Augmented SBOM file to the release as `cyclonedx.augmented.sbom.json`. Download the Augmented SBOM from a recent execution of the `sbom` task in an Evergreen patch or commit build. - Attach `etc/third_party_vulnerabilities.md` to the release. - Attach `etc/ssdlc_compliance_report.md` to the release. - -- If this is a new minor release (e.g. `x.y.0`): - - File a DOCSP ticket to update the installation instructions on [Install libmongocrypt](https://www.mongodb.com/docs/manual/core/csfle/reference/libmongocrypt/). ([Example](https://jira.mongodb.org/browse/DOCSP-36863)) - - Generate a new unique SBOM serial number for the next release: - ```bash - ./.evergreen/earthly.sh +sbom-generate-new-serial-number - ``` +- Check out the release branch (`rx.y`). Generate a new unique SBOM serial number for the next upcoming patch release (e.g. for `1.13.1` following the release of `1.13.0`): + ```bash + ./.evergreen/earthly.sh +sbom-generate-new-serial-number + ``` + Commit resulting `etc/cyclonedx.sbom.json` and push to `rx.y`. +- If this is a new non-patch release (e.g. `x.y.0`): + - File a DOCSP ticket to update the installation instructions on [Install libmongocrypt](https://www.mongodb.com/docs/manual/core/csfle/reference/libmongocrypt/). ([Example](https://jira.mongodb.org/browse/DOCSP-47954)) - Create a new Snyk reference target. The following instructions use the example branch `rx.y`: Run `cmake` to ensure generated source files are present: @@ -118,20 +118,27 @@ Do the following when releasing: - Navigate to the [Webhook Settings](https://github.com/mongodb/libmongocrypt/settings/hooks). - Click `Edit` on the hook for `https://githook.mongodb.com/`. - Add the new release branch to the `Payload URL`. Remove unmaintained release branches. -- Make a PR to apply the "Update CHANGELOG.md for x.y.z" commit to the `master` branch. +- Make a PR to to the `master` branch: + - Apply changes from the "Release x.y.z" commit. + - If this was a non-patch release (e.g. `x.y.0`), generate a new unique SBOM serial number for the next upcoming non-patch release (e.g. for `1.14.0` following the release of `1.13.0`): + ```bash + ./.evergreen/earthly.sh +sbom-generate-new-serial-number + ``` + Commit resulting `etc/cyclonedx.sbom.json`. - Update the release on the [Jira releases page](https://jira.mongodb.org/projects/MONGOCRYPT/versions). - Record the release on [C/C++ Release Info](https://docs.google.com/spreadsheets/d/1yHfGmDnbA5-Qt8FX4tKWC5xk9AhzYZx1SKF4AD36ecY/edit?usp=sharing). This is done to meet SSDLC reporting requirements. - Add a link to the Evergreen waterfall for the tagged commit to [libmongocrypt Security Testing Summary](https://docs.google.com/document/d/1dc7uvBzu3okAIsA8LSW5sVQGkYIvwpBVdg5v4wb4c4s/edit#heading=h.5t79jwe4p0ss). ## Homebrew steps ## -Submit a PR to update the Homebrew package https://github.com/mongodb/homebrew-brew/blob/master/Formula/libmongocrypt.rb. ([Example](https://github.com/mongodb/homebrew-brew/pull/208)). If not on macOS, request a team member to do this step. +Submit a PR to update the Homebrew package https://github.com/mongodb/homebrew-brew/blob/master/Formula/libmongocrypt.rb. ([Example](https://github.com/mongodb/homebrew-brew/pull/234)). If not on macOS, request a team member to do this step. +Request review by posting in #ask-devprod-build. ## Debian steps ## If you are not a Debian maintainer on the team, request a team member to do the steps in this section. Refer to the [Debian](https://github.com/mongodb/mongo-c-driver/blob/master/docs/dev/debian.rst) steps. -For a minor release (e.g. x.y.0), submit a merge request to the [extrepo-data](https://salsa.debian.org/extrepo-team/extrepo-data) project in Debian to update the PPA. The change would look something like this: +For a non-patch release (e.g. x.y.0), submit a merge request to the [extrepo-data](https://salsa.debian.org/extrepo-team/extrepo-data) project in Debian to update the PPA. The change would look something like this: ``` diff --git a/repos/debian/libmongocrypt.yaml b/repos/debian/libmongocrypt.yaml @@ -142,8 +149,8 @@ index 609dc0b..f7530a9 100644 source: Types: deb URIs: https://libmongocrypt.s3.amazonaws.com/apt/debian -- Suites: /libmongocrypt/1.11 -+ Suites: /libmongocrypt/1.12 +- Suites: /libmongocrypt/1.12 ++ Suites: /libmongocrypt/1.13 Components: main Architectures: amd64 arm64 suites: diff --git a/ext/libmongocrypt/libmongocrypt/etc/calc_release_version.py b/ext/libmongocrypt/libmongocrypt/etc/calc_release_version.py index 26bf164..eeb807f 100644 --- a/ext/libmongocrypt/libmongocrypt/etc/calc_release_version.py +++ b/ext/libmongocrypt/libmongocrypt/etc/calc_release_version.py @@ -38,19 +38,45 @@ import re import subprocess import sys -try: - # Prefer newer `packaging` over deprecated packages. - from packaging.version import Version as Version - from packaging.version import parse as parse_version -except ImportError: - # Fallback to deprecated pkg_resources. - try: - from pkg_resources.extern.packaging.version import Version - from pkg_resources import parse_version - except ImportError: - # Fallback to deprecated distutils. - from distutils.version import LooseVersion as Version - from distutils.version import LooseVersion as parse_version + +class Version: + def __init__(self, s): + pat = r'(\d+)\.(\d+)\.(\d+)(\-\S+)?' + match = re.match(pat, s) + assert match, "Unrecognized version string %s" % s + self.major, self.minor, self.micro = ( + map(int, (match.group(1), match.group(2), match.group(3)))) + + if match.group(4): + self.prerelease = match.group(4)[1:] + else: + self.prerelease = '' + + def __lt__(self, other): + if self.major != other.major: + return self.major < other.major + if self.minor != other.minor: + return self.minor < other.minor + if self.micro != other.micro: + return self.micro < other.micro + if self.prerelease != other.prerelease: + if self.prerelease != '' and other.prerelease == '': + # Consider a prerelease less than non-prerelease. + return True + # For simplicity, compare prerelease versions lexicographically. + return self.prerelease < other.prerelease + + # Versions are equal. + return False + + def __eq__(self, other): + self_tuple = self.major, self.minor, self.micro, self.prerelease + other_tuple = other.major, other.minor, other.micro, other.prerelease + return self_tuple == other_tuple + + +def parse_version(ver): + return Version(ver) DEBUG = len(sys.argv) > 1 and '-d' in sys.argv if DEBUG: diff --git a/ext/libmongocrypt/libmongocrypt/etc/calc_release_version_selftest.sh b/ext/libmongocrypt/libmongocrypt/etc/calc_release_version_selftest.sh index 7fd9787..1dbbe03 100755 --- a/ext/libmongocrypt/libmongocrypt/etc/calc_release_version_selftest.sh +++ b/ext/libmongocrypt/libmongocrypt/etc/calc_release_version_selftest.sh @@ -66,7 +66,7 @@ echo "Test next minor version ... begin" # failed, then it is probably because a new major/minor release was made. # Update the expected output to represent the correct next version. # XXX NOTE XXX NOTE XXX - assert_eq "$got" "1.9.0-$DATE+git$CURRENT_SHORTREF" + assert_eq "$got" "1.14.0-$DATE+git$CURRENT_SHORTREF" } echo "Test next minor version ... end" diff --git a/ext/libmongocrypt/libmongocrypt/etc/cyclonedx.sbom.json b/ext/libmongocrypt/libmongocrypt/etc/cyclonedx.sbom.json index f03a732..623c291 100644 --- a/ext/libmongocrypt/libmongocrypt/etc/cyclonedx.sbom.json +++ b/ext/libmongocrypt/libmongocrypt/etc/cyclonedx.sbom.json @@ -57,7 +57,7 @@ } ], "metadata": { - "timestamp": "2025-04-08T13:06:37.750496+00:00", + "timestamp": "2025-04-08T15:21:23.237097+00:00", "tools": [ { "externalReferences": [ @@ -100,7 +100,7 @@ } ] }, - "serialNumber": "urn:uuid:1eeadd7e-be33-4e55-960c-02bac1da4cf7", + "serialNumber": "urn:uuid:9e8a6b86-64aa-4438-bd54-80fd66afce96", "version": 1, "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", "bomFormat": "CycloneDX", diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/CMakeLists.txt b/ext/libmongocrypt/libmongocrypt/kms-message/CMakeLists.txt index f6e3324..6848e61 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/CMakeLists.txt +++ b/ext/libmongocrypt/libmongocrypt/kms-message/CMakeLists.txt @@ -4,7 +4,7 @@ project (kms_message LANGUAGES C ) -set (CMAKE_C_STANDARD 90) +set (CMAKE_C_STANDARD 99) include (CheckCCompilerFlag) # All targets obey visibility, not just library targets. diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/hexlify.c b/ext/libmongocrypt/libmongocrypt/kms-message/src/hexlify.c index 2d70927..2ef7d1b 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/hexlify.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/hexlify.c @@ -14,7 +14,12 @@ * limitations under the License. */ +#include "hexlify.h" + +// + #include "kms_message_private.h" + #include #include #include diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/hexlify.h b/ext/libmongocrypt/libmongocrypt/kms-message/src/hexlify.h index 60bc93e..cab27e8 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/hexlify.h +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/hexlify.h @@ -21,4 +21,4 @@ char * hexlify (const uint8_t *buf, size_t len); int -unhexlify (const char *in, size_t len); \ No newline at end of file +unhexlify (const char *in, size_t len); diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_azure_request.c b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_azure_request.c index 5ce7488..88acb5b 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_azure_request.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_azure_request.c @@ -216,4 +216,4 @@ kms_azure_request_unwrapkey_new (const char *host, ciphertext, ciphertext_len, opt); -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_gcp_request.c b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_gcp_request.c index 960141b..d14d492 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_gcp_request.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_gcp_request.c @@ -283,4 +283,4 @@ kms_gcp_request_decrypt_new (const char *host, ciphertext, ciphertext_len, opt); -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c index 56ca01f..6ba23a6 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c @@ -279,7 +279,8 @@ kmip_reader_has_data (kmip_reader_t *reader) #define CHECK_REMAINING_BUFFER_AND_RET(read_size) \ if ((reader->pos + (read_size)) > reader->len) { \ return false; \ - } + } else \ + ((void)0) bool kmip_reader_read_u8 (kmip_reader_t *reader, uint8_t *value) @@ -346,7 +347,8 @@ kmip_reader_read_bytes (kmip_reader_t *reader, uint8_t **ptr, size_t length) #define CHECK_AND_RET(x) \ if (!(x)) { \ return false; \ - } + } else \ + ((void)0) bool kmip_reader_read_tag (kmip_reader_t *reader, kmip_tag_type_t *tag) diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_request.c b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_request.c index 3b95410..2c2c7dc 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_request.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_request.c @@ -83,7 +83,7 @@ kms_kmip_request_register_secretdata_new (void *reserved, if (len != KMS_KMIP_REQUEST_SECRETDATA_LENGTH) { KMS_ERROR (req, - "expected SecretData length of %d, got %" PRIu32, + "expected SecretData length of %d, got %zu", KMS_KMIP_REQUEST_SECRETDATA_LENGTH, len); return req; @@ -463,4 +463,3 @@ kms_kmip_request_decrypt_new (void *reserved, const char* unique_identifer, cons */ return kmip_encrypt_decrypt(unique_identifer, ciphertext, len, iv_data, iv_len, false); } - diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message_private.h b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message_private.h index b0effba..2fb7018 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message_private.h +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message_private.h @@ -124,6 +124,9 @@ struct _kms_response_parser_t { } \ } while (0) +#ifdef __GNUC__ +__attribute__((format(__printf__, 3, 4))) +#endif void kms_set_error (char *error, size_t size, const char *fmt, ...); @@ -137,6 +140,7 @@ kms_set_error (char *error, size_t size, const char *fmt, ...); if (!(stmt)) { \ fprintf (stderr, "%s failed\n", #stmt); \ abort (); \ - } + } else \ + ((void)0) #endif /* KMS_MESSAGE_PRIVATE_H */ diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request.c b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request.c index b95c451..a00ff90 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request.c @@ -744,7 +744,7 @@ kms_request_get_signature (kms_request_t *request) return kms_request_str_detach (sig); } -void +static void kms_request_validate (kms_request_t *request) { if (!check_and_prohibit_kmip (request)) { diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_opt.c b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_opt.c index c9e1b00..b1e5af3 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_opt.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_opt.c @@ -85,4 +85,4 @@ kms_request_opt_set_crypto_hook_sign_rsaes_pkcs1_v1_5 ( { opt->crypto.sign_rsaes_pkcs1_v1_5 = sign_rsaes_pkcs1_v1_5; opt->crypto.sign_ctx = sign_ctx; -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.c b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.c index 57b2e4f..f830f95 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.c @@ -27,8 +27,8 @@ #include #include /* CHAR_BIT */ -bool rfc_3986_tab[256] = {0}; -bool kms_initialized = false; +static bool rfc_3986_tab[256] = {0}; +static bool kms_initialized = false; static void tables_init (void) @@ -126,12 +126,6 @@ kms_request_str_detach (kms_request_str_t *str) return r; } -const char * -kms_request_str_get (kms_request_str_t *str) -{ - return str->str; -} - bool kms_request_str_reserve (kms_request_str_t *str, size_t size) { diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.h b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.h index 4e33faa..6d22837 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.h +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.h @@ -64,10 +64,19 @@ kms_request_str_append_newline (kms_request_str_t *str); KMS_MSG_EXPORT (void) kms_request_str_append_lowercase (kms_request_str_t *str, kms_request_str_t *appended); + +#ifdef __GNUC__ +__attribute__((format(__printf__, 2, 3))) +#endif KMS_MSG_EXPORT (void) kms_request_str_appendf (kms_request_str_t *str, const char *format, ...); + +#ifdef __GNUC__ +__attribute__((format(__printf__, 2, 3))) +#endif KMS_MSG_EXPORT (void) kms_request_strdupf (kms_request_str_t *str, const char *format, ...); + KMS_MSG_EXPORT (void) kms_request_str_append_escaped (kms_request_str_t *str, kms_request_str_t *appended, diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_response_parser.c b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_response_parser.c index 67336d7..0f51f1a 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_response_parser.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_response_parser.c @@ -81,7 +81,6 @@ kms_response_parser_wants_bytes (kms_response_parser_t *parser, int32_t max) default: KMS_ASSERT (false && "Invalid kms_response_parser HTTP state"); } - return -1; } static bool diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/sort.c b/ext/libmongocrypt/libmongocrypt/kms-message/src/sort.c index 91aa3f3..97a0b7a 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/sort.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/sort.c @@ -37,6 +37,10 @@ * https://github.com/freebsd/freebsd/blob/e7c6cef9514d3bb1f14a30a5ee871231523e43db/lib/libc/stdlib/merge.c */ +#include "sort.h" + +// + #include /* @@ -44,10 +48,9 @@ * last 4 elements. */ -typedef int (*cmp_t) (const void *, const void *); #define CMP(x, y) cmp (x, y) #define swap(a, b) \ - { \ + if (1) { \ s = b; \ i = size; \ do { \ @@ -56,7 +59,8 @@ typedef int (*cmp_t) (const void *, const void *); *s++ = tmp; \ } while (--i); \ a -= size; \ - } + } else \ + ((void)0) void insertionsort (unsigned char *a, size_t n, size_t size, cmp_t cmp) diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/src/sort.h b/ext/libmongocrypt/libmongocrypt/kms-message/src/sort.h index 42c1b21..31558bf 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/src/sort.h +++ b/ext/libmongocrypt/libmongocrypt/kms-message/src/sort.h @@ -15,6 +15,8 @@ * limitations under the License. */ +#include + typedef int (*cmp_t) (const void *, const void *); void diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kmip_reader_writer.c b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kmip_reader_writer.c index 1e266bb..fa164a3 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kmip_reader_writer.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kmip_reader_writer.c @@ -6,7 +6,7 @@ * 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. @@ -54,6 +54,7 @@ kms_kmip_writer_test_evaluate (kmip_writer_t *writer, free (expected_hex); } +void kms_kmip_writer_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_writer_test (void) { @@ -140,6 +141,7 @@ kms_kmip_writer_test (void) kmip_writer_destroy (writer); } +void kms_kmip_reader_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_reader_test (void) { @@ -312,6 +314,7 @@ kms_kmip_reader_test (void) free (data); } +void kms_kmip_reader_negative_int_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_reader_negative_int_test (void) { @@ -356,6 +359,7 @@ kms_kmip_reader_negative_int_test (void) free (data); } +void kms_kmip_reader_find_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_reader_find_test (void) { @@ -404,6 +408,7 @@ kms_kmip_reader_find_test (void) free (data); } +void kms_kmip_reader_find_and_recurse_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_reader_find_and_recurse_test (void) { @@ -438,6 +443,7 @@ kms_kmip_reader_find_and_recurse_test (void) free (data); } +void kms_kmip_reader_find_and_read_enum_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_reader_find_and_read_enum_test (void) { @@ -470,6 +476,7 @@ kms_kmip_reader_find_and_read_enum_test (void) free (data); } +void kms_kmip_reader_find_and_read_bytes_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_reader_find_and_read_bytes_test (void) { diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_assert.h b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_assert.h index a13b852..f574ca6 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_assert.h +++ b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_assert.h @@ -44,7 +44,7 @@ #define TEST_ERROR(...) \ do { \ TEST_STDERR_PRINTF ( \ - "test error %s:%d %s(): ", __FILE__, __LINE__, __FUNCTION__); \ + "test error %s:%d %s(): ", __FILE__, __LINE__, __func__); \ TEST_STDERR_PRINTF (__VA_ARGS__); \ TEST_STDERR_PRINTF ("\n"); \ abort (); \ @@ -53,7 +53,8 @@ #define ASSERT(stmt) \ if (!(stmt)) { \ TEST_ERROR ("statement failed %s", #stmt); \ - } + } else \ + ((void)0) #define ASSERT_CMPSTR_WITH_LEN(_expect, _expect_len, _actual, _actual_len) \ do { \ @@ -98,7 +99,7 @@ TEST_ERROR ( \ "comparison failed: %d %s %d", _a_int, #_operator, _b_int); \ } \ - } while (0); + } while (0) #define ASSERT_CMPBYTES( \ expected_bytes, expected_len, actual_bytes, actual_len) \ @@ -161,4 +162,4 @@ ASSERT_CONTAINS (_error_str, expect_substring); \ } while (0) -#endif /* TEST_KMS_ASSERT_H */ \ No newline at end of file +#endif /* TEST_KMS_ASSERT_H */ diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_azure_online.c b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_azure_online.c index 76a3b36..795aaf2 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_azure_online.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_azure_online.c @@ -257,4 +257,4 @@ main (int argc, char **argv) kms_message_init (); test_azure_wrapkey (); return 0; -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_gcp_online.c b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_gcp_online.c index 1578e51..d7b5c6b 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_gcp_online.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_gcp_online.c @@ -247,4 +247,4 @@ main (int argc, char **argv) kms_message_init (); test_gcp (); return 0; -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_request.c b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_request.c index 05b1fdb..198c940 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_request.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_request.c @@ -76,6 +76,7 @@ value="ffa8cc79e8c3763b0121fcd06bb3488c8bf42c0774604640279b16b264194030eeb083962 0x36, 0xa9, 0x06, 0x6b, 0x4e, 0x10, 0xae, 0xb5, 0x6a, 0x5c, 0xcf, 0x6a, \ 0xa4, 0x69, 0x01, 0xe6, 0x25, 0xe3, 0x40, 0x0c, 0x78, 0x11, 0xd2, 0xec +void kms_kmip_request_register_secretdata_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_request_register_secretdata_test (void) { @@ -98,6 +99,7 @@ kms_kmip_request_register_secretdata_test (void) kms_request_destroy (req); } +void kms_kmip_request_register_secretdata_invalid_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_request_register_secretdata_invalid_test (void) { @@ -144,6 +146,7 @@ value="7FJYvnV6XkaUCWuY96bCSc6AuhvkPpqI"/> 0x58, 0x6b, 0x61, 0x55, 0x43, 0x57, 0x75, 0x59, 0x39, 0x36, 0x62, 0x43, \ 0x53, 0x63, 0x36, 0x41, 0x75, 0x68, 0x76, 0x6b, 0x50, 0x70, 0x71, 0x49 +void kms_kmip_request_get_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_request_get_test (void) { @@ -200,6 +203,7 @@ value="7FJYvnV6XkaUCWuY96bCSc6AuhvkPpqI"/> 0x58, 0x6b, 0x61, 0x55, 0x43, 0x57, 0x75, 0x59, 0x39, 0x36, 0x62, 0x43, \ 0x53, 0x63, 0x36, 0x41, 0x75, 0x68, 0x76, 0x6b, 0x50, 0x70, 0x71, 0x49 +void kms_kmip_request_activate_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_request_activate_test (void) { diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_response.c b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_response.c index f25fa30..97c7b81 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_response.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_response.c @@ -56,6 +56,7 @@ static const uint8_t SUCCESS_REGISTER_RESPONSE[] = { static const char *const SUCCESS_REGISTER_RESPONSE_UNIQUE_IDENTIFIER = "39"; +void kms_kmip_response_get_unique_identifier_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_response_get_unique_identifier_test (void) { @@ -141,6 +142,7 @@ static const uint8_t SUCCESS_GET_RESPONSE_SECRETDATA[] = { 0x36, 0xa9, 0x06, 0x6b, 0x4e, 0x10, 0xae, 0xb5, 0x6a, 0x5c, 0xcf, 0x6a, 0xa4, 0x69, 0x01, 0xe6, 0x25, 0xe3, 0x40, 0x0c, 0x78, 0x11, 0xd2, 0xec}; +void kms_kmip_response_get_secretdata_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_response_get_secretdata_test (void) { @@ -197,6 +199,7 @@ static const uint8_t ERROR_GET_RESPOSE_NOTFOUND[] = { 0x6c, 0x74, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64}; +void kms_kmip_response_get_secretdata_notfound_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_response_get_secretdata_notfound_test (void) { diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_response_parser.c b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_response_parser.c index 0d1c773..91bf114 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_response_parser.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_kmip_response_parser.c @@ -36,6 +36,7 @@ static const int SAMPLE_KMIP_FIRST_LENGTH = 32; /* SAMPLE_KMIP_LARGE_LENGTH is a byte size larger than the message. */ static const int SAMPLE_KMIP_LARGE_LENGTH = 1024; +void kms_kmip_response_parser_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_response_parser_test (void) { @@ -118,6 +119,7 @@ feed_full_response (kms_response_parser_t *parser, uint8_t *data) } } +void kms_kmip_response_parser_reuse_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_response_parser_reuse_test (void) { @@ -150,6 +152,7 @@ kms_kmip_response_parser_reuse_test (void) free (data); } +void kms_kmip_response_parser_excess_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_response_parser_excess_test (void) { @@ -171,6 +174,7 @@ kms_kmip_response_parser_excess_test (void) free (data); } +void kms_kmip_response_parser_notenough_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_response_parser_notenough_test (void) { diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_online_util.c b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_online_util.c index 8160111..08f3fe9 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_online_util.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_online_util.c @@ -117,4 +117,4 @@ send_kms_request (kms_request_t *req, const char *host) kms_response_parser_destroy (response_parser); mongoc_stream_destroy (tls_stream); return response; -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_online_util.h b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_online_util.h index c3ccccd..d371601 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_online_util.h +++ b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_online_util.h @@ -32,4 +32,4 @@ connect_with_tls (const char *host, kms_response_t * send_kms_request (kms_request_t *req, const char *host); -#endif /* TEST_KMS_ONLINE_UTIL_H */ \ No newline at end of file +#endif /* TEST_KMS_ONLINE_UTIL_H */ diff --git a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_request.c b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_request.c index 42312a8..c520da4 100644 --- a/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_request.c +++ b/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_request.c @@ -43,15 +43,15 @@ #include "test_kms_assert.h" -const char *aws_test_suite_dir = "aws-sig-v4-test-suite"; +static const char *aws_test_suite_dir = "aws-sig-v4-test-suite"; -const char *skipped_aws_tests[] = { +static const char *skipped_aws_tests[] = { /* we don't yet support temporary security credentials provided by the AWS * Security Token Service (AWS STS). see post-sts-token/readme.txt */ "post-sts-token", }; -bool +static bool skip_aws_test (const char *test_name) { size_t i; @@ -65,7 +65,7 @@ skip_aws_test (const char *test_name) return false; } -bool +static bool ends_with (const char *str, const char *suffix) { size_t str_len = strlen (str); @@ -79,7 +79,7 @@ ends_with (const char *str, const char *suffix) } -char * +static char * last_segment (const char *str) { const char *p = str + strlen (str); @@ -93,7 +93,7 @@ last_segment (const char *str) return strdup (str); } -char * +static char * test_file_path (const char *path, const char *suffix) { char *r; @@ -105,7 +105,7 @@ test_file_path (const char *path, const char *suffix) return r; } -void +static void realloc_buffer (char **buffer, size_t *n, size_t len) { if (*buffer == NULL) { @@ -119,12 +119,12 @@ realloc_buffer (char **buffer, size_t *n, size_t len) *n = len; } -ssize_t +static ssize_t test_getline (char **lineptr, size_t *n, FILE *stream) { if (*lineptr == NULL && *n == 0) { realloc_buffer (lineptr, n, 128); - }; + } // Sanity check if ((*lineptr == NULL && *n != 0) || (*lineptr != NULL && *n == 0)) { @@ -164,7 +164,7 @@ test_getline (char **lineptr, size_t *n, FILE *stream) } } -char * +static char * read_test (const char *path, const char *suffix) { char *file_path = test_file_path (path, suffix); @@ -210,7 +210,7 @@ read_test (const char *path, const char *suffix) return str; } -void +static void set_test_date (kms_request_t *request) { struct tm tm; @@ -230,7 +230,7 @@ set_test_date (kms_request_t *request) KMS_ASSERT (kms_request_set_date (request, &tm)); } -kms_request_t * +static kms_request_t * read_req (const char *path) { kms_request_t *request; @@ -305,7 +305,7 @@ read_req (const char *path) return request; } -void +static void test_compare (kms_request_t *request, char *(*func) (kms_request_t *), const char *dir_path, @@ -330,31 +330,31 @@ test_compare (kms_request_t *request, free (test_name); } -void +static void test_compare_creq (kms_request_t *request, const char *dir_path) { test_compare (request, kms_request_get_canonical, dir_path, "creq"); } -void +static void test_compare_sts (kms_request_t *request, const char *dir_path) { test_compare (request, kms_request_get_string_to_sign, dir_path, "sts"); } -void +static void test_compare_authz (kms_request_t *request, const char *dir_path) { test_compare (request, kms_request_get_signature, dir_path, "authz"); } -void +static void test_compare_sreq (kms_request_t *request, const char *dir_path) { test_compare (request, kms_request_get_signed, dir_path, "sreq"); } -void +static void aws_sig_v4_test (const char *dir_path) { kms_request_t *request; @@ -367,7 +367,7 @@ aws_sig_v4_test (const char *dir_path) kms_request_destroy (request); } -bool +static bool all_aws_sig_v4_tests (const char *path, const char *selected) { /* Amazon supplies tests, one per directory, 5 files per test, see @@ -422,7 +422,7 @@ all_aws_sig_v4_tests (const char *path, const char *selected) } /* docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html */ -void +static void example_signature_test (void) { const char *expect = @@ -446,7 +446,7 @@ example_signature_test (void) kms_request_destroy (request); } -void +static void path_normalization_test (void) { const char *tests[][2] = { @@ -501,7 +501,7 @@ path_normalization_test (void) } } -kms_request_t * +static kms_request_t * make_test_request (void) { kms_request_t *request = kms_request_new ("POST", "/", NULL); @@ -515,7 +515,7 @@ make_test_request (void) return request; } -void +static void host_test (void) { kms_request_t *request = make_test_request (); @@ -523,7 +523,7 @@ host_test (void) kms_request_destroy (request); } -void +static void content_length_test (void) { const char *payload = "foo-payload"; @@ -533,7 +533,7 @@ content_length_test (void) kms_request_destroy (request); } -void +static void bad_query_test (void) { kms_request_t *request = kms_request_new ("GET", "/?asdf", NULL); @@ -541,7 +541,7 @@ bad_query_test (void) kms_request_destroy (request); } -void +static void append_header_field_value_test (void) { kms_request_t *request = kms_request_new ("GET", "/", NULL); @@ -552,7 +552,7 @@ append_header_field_value_test (void) kms_request_destroy (request); } -void +static void set_date_test (void) { // Windows CRT asserts on this negative test because it is a negative test @@ -568,7 +568,7 @@ set_date_test (void) #endif } -void +static void multibyte_test (void) { /* euro currency symbol */ @@ -597,7 +597,7 @@ multibyte_test (void) #undef EU } -void +static void connection_close_test (void) { kms_request_opt_t *opt; @@ -619,7 +619,7 @@ connection_close_test (void) } /* the ciphertext blob from a response to an "Encrypt" API call */ -const char ciphertext_blob[] = +static const char ciphertext_blob[] = "\x01\x02\x02\x00\x78\xf3\x8e\xd8\xd4\xc6\xba\xfb\xa1\xcf\xc1\x1e\x68\xf2" "\xa1\x91\x9e\x36\x4d\x74\xa2\xc4\x9e\x30\x67\x08\x53\x33\x0d\xcd\xe0\xc9" "\x1b\x01\x60\x30\xd4\x73\x9e\x90\x1f\xa7\x43\x55\x84\x26\xf9\xd5\xf0\xb1" @@ -630,7 +630,7 @@ const char ciphertext_blob[] = "\x03\xcd\xcb\xe2\xac\x36\x4f\x73\xdb\x1b\x73\x2e\x33\xda\x45\x51\xf4\xcd" "\xc0\xff\xd2\xe1\xb9\xc4\xc2\x0e\xbf\x53\x90\x46\x18\x42"; -void +static void decrypt_request_test (void) { kms_request_t *request = kms_decrypt_request_new ( @@ -649,7 +649,7 @@ decrypt_request_test (void) kms_request_destroy (request); } -void +static void encrypt_request_test (void) { char *plaintext = "foobar"; @@ -669,7 +669,7 @@ encrypt_request_test (void) kms_request_destroy (request); } -void +static void kv_list_del_test (void) { kms_kv_list_t *lst = kms_kv_list_new (); @@ -696,7 +696,7 @@ kv_list_del_test (void) kms_kv_list_destroy (lst); } -void +static void b64_test (void) { uint8_t *expected = (uint8_t *) "\x01\x02\x03\x04"; @@ -712,7 +712,7 @@ b64_test (void) KMS_ASSERT (0 == memcmp (expected, data, 4)); } -void +static void b64_b64url_test (void) { char base64_data[64]; @@ -744,7 +744,7 @@ b64_b64url_test (void) ASSERT_CMPSTR (base64_data, "PDw_Pz8-Pg=="); } -void +static void kms_response_parser_test (void) { kms_response_parser_t *parser = kms_response_parser_new (); @@ -760,7 +760,7 @@ kms_response_parser_test (void) kms_response_parser_feed (parser, (uint8_t *) "This is a test.", 15)); ASSERT (0 == kms_response_parser_wants_bytes (parser, 123)); response = kms_response_parser_get_response (parser); - ASSERT (response->status == 200) + ASSERT (response->status == 200); ASSERT_CMPSTR (response->body->str, "This is a test."); kms_response_destroy (response); @@ -958,7 +958,7 @@ kms_response_parser_files (void) _field = kms_request_str_new (); \ } while (0) -void +static void kms_request_validate_test (void) { kms_request_t *request = NULL; @@ -1242,7 +1242,7 @@ main (int argc, char *argv[]) int ret = kms_message_init (); if (ret != 0) { - TEST_PRINTF ("kms_message_init failed: 0x%x\n", ret); + TEST_PRINTF ("kms_message_init failed: 0x%d\n", ret); abort (); } diff --git a/ext/libmongocrypt/libmongocrypt/src/crypto/libcrypto.c b/ext/libmongocrypt/libmongocrypt/src/crypto/libcrypto.c index 2fee384..92c1e78 100644 --- a/ext/libmongocrypt/libmongocrypt/src/crypto/libcrypto.c +++ b/ext/libmongocrypt/libmongocrypt/src/crypto/libcrypto.c @@ -33,47 +33,41 @@ #include #include -#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) - -static HMAC_CTX *HMAC_CTX_new(void) { - return bson_malloc0(sizeof(HMAC_CTX)); -} - -static void HMAC_CTX_free(HMAC_CTX *ctx) { - HMAC_CTX_cleanup(ctx); - bson_free(ctx); -} +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#include #endif bool _native_crypto_initialized = false; -void _native_crypto_init(void) { - _native_crypto_initialized = true; -} - -/* _encrypt_with_cipher encrypts @in with the OpenSSL cipher specified by - * @cipher. +/* _encrypt_with_cipher encrypts @in with the specified OpenSSL cipher. + * @cipher is a usable EVP_CIPHER, or NULL if early initialization failed. + * @cipher_description is a human-readable description used when reporting deferred errors from initialization, required + * if @cipher might be NULL. * @key is the input key. @iv is the input IV. * @out is the output ciphertext. @out must be allocated by the caller with * enough room for the ciphertext. * @bytes_written is the number of bytes that were written to @out. * Returns false and sets @status on error. @status is required. */ -static bool _encrypt_with_cipher(const EVP_CIPHER *cipher, aes_256_args_t args) { - EVP_CIPHER_CTX *ctx; - bool ret = false; - int intermediate_bytes_written = 0; - mongocrypt_status_t *status = args.status; - - ctx = EVP_CIPHER_CTX_new(); - +static bool _encrypt_with_cipher(const EVP_CIPHER *cipher, const char *cipher_description, aes_256_args_t args) { BSON_ASSERT(args.key); BSON_ASSERT(args.in); BSON_ASSERT(args.out); - BSON_ASSERT(ctx); - BSON_ASSERT(cipher); + BSON_ASSERT(args.in->len <= INT_MAX); + + mongocrypt_status_t *status = args.status; + if (!cipher) { + BSON_ASSERT(cipher_description); + CLIENT_ERR("failed to initialize cipher %s", cipher_description); + return false; + } + BSON_ASSERT(NULL == args.iv || (uint32_t)EVP_CIPHER_iv_length(cipher) == args.iv->len); BSON_ASSERT((uint32_t)EVP_CIPHER_key_length(cipher) == args.key->len); - BSON_ASSERT(args.in->len <= INT_MAX); + + bool ret = false; + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + BSON_ASSERT(ctx); if (!EVP_EncryptInit_ex(ctx, cipher, NULL /* engine */, args.key->data, NULL == args.iv ? NULL : args.iv->data)) { CLIENT_ERR("error in EVP_EncryptInit_ex: %s", ERR_error_string(ERR_get_error(), NULL)); @@ -84,6 +78,8 @@ static bool _encrypt_with_cipher(const EVP_CIPHER *cipher, aes_256_args_t args) EVP_CIPHER_CTX_set_padding(ctx, 0); *args.bytes_written = 0; + + int intermediate_bytes_written = 0; if (!EVP_EncryptUpdate(ctx, args.out->data, &intermediate_bytes_written, args.in->data, (int)args.in->len)) { CLIENT_ERR("error in EVP_EncryptUpdate: %s", ERR_error_string(ERR_get_error(), NULL)); goto done; @@ -107,30 +103,35 @@ static bool _encrypt_with_cipher(const EVP_CIPHER *cipher, aes_256_args_t args) return ret; } -/* _decrypt_with_cipher decrypts @in with the OpenSSL cipher specified by - * @cipher. +/* _decrypt_with_cipher decrypts @in with the specified OpenSSL cipher. + * @cipher is a usable EVP_CIPHER, or NULL if early initialization failed. + * @cipher_description is a human-readable description used when reporting deferred errors from initialization, required + * if @cipher might be NULL. * @key is the input key. @iv is the input IV. * @out is the output plaintext. @out must be allocated by the caller with * enough room for the plaintext. * @bytes_written is the number of bytes that were written to @out. * Returns false and sets @status on error. @status is required. */ -static bool _decrypt_with_cipher(const EVP_CIPHER *cipher, aes_256_args_t args) { - EVP_CIPHER_CTX *ctx; - bool ret = false; - int intermediate_bytes_written = 0; - mongocrypt_status_t *status = args.status; - - ctx = EVP_CIPHER_CTX_new(); - BSON_ASSERT(ctx); - - BSON_ASSERT_PARAM(cipher); +static bool _decrypt_with_cipher(const EVP_CIPHER *cipher, const char *cipher_description, aes_256_args_t args) { BSON_ASSERT(args.iv); BSON_ASSERT(args.key); BSON_ASSERT(args.in); BSON_ASSERT(args.out); + BSON_ASSERT(args.in->len <= INT_MAX); + + mongocrypt_status_t *status = args.status; + if (!cipher) { + BSON_ASSERT_PARAM(cipher_description); + CLIENT_ERR("failed to initialize cipher %s", cipher_description); + return false; + } + BSON_ASSERT((uint32_t)EVP_CIPHER_iv_length(cipher) == args.iv->len); BSON_ASSERT((uint32_t)EVP_CIPHER_key_length(cipher) == args.key->len); - BSON_ASSERT(args.in->len <= INT_MAX); + + bool ret = false; + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + BSON_ASSERT(ctx); if (!EVP_DecryptInit_ex(ctx, cipher, NULL /* engine */, args.key->data, args.iv->data)) { CLIENT_ERR("error in EVP_DecryptInit_ex: %s", ERR_error_string(ERR_get_error(), NULL)); @@ -142,6 +143,7 @@ static bool _decrypt_with_cipher(const EVP_CIPHER *cipher, aes_256_args_t args) *args.bytes_written = 0; + int intermediate_bytes_written = 0; if (!EVP_DecryptUpdate(ctx, args.out->data, &intermediate_bytes_written, args.in->data, (int)args.in->len)) { CLIENT_ERR("error in EVP_DecryptUpdate: %s", ERR_error_string(ERR_get_error(), NULL)); goto done; @@ -165,16 +167,186 @@ static bool _decrypt_with_cipher(const EVP_CIPHER *cipher, aes_256_args_t args) return ret; } +bool _native_crypto_random(_mongocrypt_buffer_t *out, uint32_t count, mongocrypt_status_t *status) { + BSON_ASSERT_PARAM(out); + BSON_ASSERT(count <= INT_MAX); + + int ret = RAND_bytes(out->data, (int)count); + /* From man page: "RAND_bytes() and RAND_priv_bytes() return 1 on success, -1 + * if not supported by the current RAND method, or 0 on other failure. The + * error code can be obtained by ERR_get_error(3)" */ + if (ret == -1) { + CLIENT_ERR("secure random IV not supported: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } else if (ret == 0) { + CLIENT_ERR("failed to generate random IV: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; + } + return true; +} + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +// Newest libcrypto support: requires EVP_MAC_CTX_dup and EVP_CIPHER_fetch added in OpenSSL 3.0.0 + +static struct { + EVP_MAC_CTX *hmac_sha2_256; + EVP_MAC_CTX *hmac_sha2_512; + EVP_CIPHER *aes_256_cbc; + EVP_CIPHER *aes_256_ctr; + EVP_CIPHER *aes_256_ecb; // For testing only +} _mongocrypt_libcrypto; + +EVP_MAC_CTX *_build_hmac_ctx_prototype(const char *digest_name) { + EVP_MAC *hmac = EVP_MAC_fetch(NULL, OSSL_MAC_NAME_HMAC, NULL); + if (!hmac) { + return NULL; + } + + EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(hmac); + EVP_MAC_free(hmac); + if (!ctx) { + return NULL; + } + + OSSL_PARAM params[] = {OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, (char *)digest_name, 0), + OSSL_PARAM_construct_end()}; + + if (EVP_MAC_CTX_set_params(ctx, params)) { + return ctx; + } else { + EVP_MAC_CTX_free(ctx); + return NULL; + } +} + +/* _hmac_with_ctx_prototype computes an HMAC of @in using an OpenSSL context duplicated from @ctx_prototype. + * @ctx_description is a human-readable description used when reporting deferred errors from initialization, required + * if @ctx_prototype might be NULL. + * @key is the input key. + * @out is the output. @out must be allocated by the caller with + * the exact length for the output. E.g. for HMAC 256, @out->len must be 32. + * Returns false and sets @status on error. @status is required. */ +static bool _hmac_with_ctx_prototype(const EVP_MAC_CTX *ctx_prototype, + const char *ctx_description, + const _mongocrypt_buffer_t *key, + const _mongocrypt_buffer_t *in, + _mongocrypt_buffer_t *out, + mongocrypt_status_t *status) { + BSON_ASSERT_PARAM(key); + BSON_ASSERT_PARAM(in); + BSON_ASSERT_PARAM(out); + BSON_ASSERT(key->len <= INT_MAX); + + if (!ctx_prototype) { + BSON_ASSERT_PARAM(ctx_description); + CLIENT_ERR("failed to initialize algorithm %s", ctx_description); + return false; + } + + EVP_MAC_CTX *ctx = EVP_MAC_CTX_dup(ctx_prototype); + if (ctx) { + bool ok = EVP_MAC_init(ctx, key->data, key->len, NULL) && EVP_MAC_update(ctx, in->data, in->len) + && EVP_MAC_final(ctx, out->data, NULL, out->len); + EVP_MAC_CTX_free(ctx); + if (ok) { + return true; + } + } + CLIENT_ERR("HMAC error: %s", ERR_error_string(ERR_get_error(), NULL)); + return false; +} + +void _native_crypto_init(void) { + // Early lookup of digest and cipher algorithms avoids both the lookup overhead itself and the overhead of lock + // contention in the default OSSL_LIB_CTX. + // + // Failures now will store NULL, reporting a client error later. + // + // On HMAC fetching: + // + // Note that libcrypto sets an additional trap for us regarding MAC algorithms. An early fetch of the HMAC itself + // won't actually pre-fetch the subalgorithm. The name of the inner digest gets stored as a string, and re-fetched + // when setting up MAC context parameters. To fetch both the outer and inner algorithms ahead of time, we construct + // a prototype EVP_MAC_CTX that can be duplicated before each use. + // + // On thread safety: + // + // This creates objects that are intended to be immutable shared data after initialization. To understand whether + // this is safe we could consult the OpenSSL documentation but currently it's lacking in specifics about the + // individual API functions and types. It offers some general guidelines: "Objects are thread-safe as long as the + // API's being invoked don't modify the object; in this case the parameter is usually marked in the API as C. + // Not all parameters are marked this way." By inspection, we can see that pre-fetched ciphers and MACs are designed + // with atomic reference counting support and appear to be intended for safe immutable use. Contexts are normally + // not safe to share, but these used only as a source for EVP_MAC_CTX_dup() can be treated as immutable. + // + // TODO: This could be refactored to live in mongocrypt_t rather than in global data. Currently there's no way to + // avoid leaking this set of one-time allocations. + // + // TODO: Higher performance yet could be achieved by re-using thread local EVP_MAC_CTX, but this requires careful + // lifecycle management to avoid leaking data. Alternatively, the libmongocrypt API could be modified to include + // some non-shared but long-lived context suitable for keeping these crypto objects. Alternatively still, it may be + // worth using a self contained SHA2 HMAC with favorable performance and portability characteristics. + + _mongocrypt_libcrypto.aes_256_cbc = EVP_CIPHER_fetch(NULL, "AES-256-CBC", NULL); + _mongocrypt_libcrypto.aes_256_ctr = EVP_CIPHER_fetch(NULL, "AES-256-CTR", NULL); + _mongocrypt_libcrypto.aes_256_ecb = EVP_CIPHER_fetch(NULL, "AES-256-ECB", NULL); + _mongocrypt_libcrypto.hmac_sha2_256 = _build_hmac_ctx_prototype(OSSL_DIGEST_NAME_SHA2_256); + _mongocrypt_libcrypto.hmac_sha2_512 = _build_hmac_ctx_prototype(OSSL_DIGEST_NAME_SHA2_512); + _native_crypto_initialized = true; +} + bool _native_crypto_aes_256_cbc_encrypt(aes_256_args_t args) { - return _encrypt_with_cipher(EVP_aes_256_cbc(), args); + return _encrypt_with_cipher(_mongocrypt_libcrypto.aes_256_cbc, "AES-256-CBC", args); } bool _native_crypto_aes_256_cbc_decrypt(aes_256_args_t args) { - return _decrypt_with_cipher(EVP_aes_256_cbc(), args); + return _decrypt_with_cipher(_mongocrypt_libcrypto.aes_256_cbc, "AES-256-CBC", args); } +bool _native_crypto_aes_256_ecb_encrypt(aes_256_args_t args); // -Wmissing-prototypes: for testing only. + bool _native_crypto_aes_256_ecb_encrypt(aes_256_args_t args) { - return _encrypt_with_cipher(EVP_aes_256_ecb(), args); + return _encrypt_with_cipher(_mongocrypt_libcrypto.aes_256_ecb, "AES-256-ECB", args); +} + +bool _native_crypto_aes_256_ctr_encrypt(aes_256_args_t args) { + return _encrypt_with_cipher(_mongocrypt_libcrypto.aes_256_ctr, "AES-256-CTR", args); +} + +bool _native_crypto_aes_256_ctr_decrypt(aes_256_args_t args) { + return _decrypt_with_cipher(_mongocrypt_libcrypto.aes_256_ctr, "AES-256-CTR", args); +} + +bool _native_crypto_hmac_sha_256(const _mongocrypt_buffer_t *key, + const _mongocrypt_buffer_t *in, + _mongocrypt_buffer_t *out, + mongocrypt_status_t *status) { + return _hmac_with_ctx_prototype(_mongocrypt_libcrypto.hmac_sha2_256, "HMAC-SHA2-256", key, in, out, status); +} + +bool _native_crypto_hmac_sha_512(const _mongocrypt_buffer_t *key, + const _mongocrypt_buffer_t *in, + _mongocrypt_buffer_t *out, + mongocrypt_status_t *status) { + return _hmac_with_ctx_prototype(_mongocrypt_libcrypto.hmac_sha2_512, "HMAC-SHA2-512", key, in, out, status); +} + +#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ +// Support for previous libcrypto versions, without early fetch optimization. + +#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) +static HMAC_CTX *HMAC_CTX_new(void) { + return bson_malloc0(sizeof(HMAC_CTX)); +} + +static void HMAC_CTX_free(HMAC_CTX *ctx) { + HMAC_CTX_cleanup(ctx); + bson_free(ctx); +} +#endif + +void _native_crypto_init(void) { + _native_crypto_initialized = true; } /* _hmac_with_hash computes an HMAC of @in with the OpenSSL hash specified by @@ -233,37 +405,26 @@ static bool _hmac_with_hash(const EVP_MD *hash, #endif } -bool _native_crypto_hmac_sha_512(const _mongocrypt_buffer_t *key, - const _mongocrypt_buffer_t *in, - _mongocrypt_buffer_t *out, - mongocrypt_status_t *status) { - return _hmac_with_hash(EVP_sha512(), key, in, out, status); +bool _native_crypto_aes_256_cbc_encrypt(aes_256_args_t args) { + return _encrypt_with_cipher(EVP_aes_256_cbc(), NULL, args); } -bool _native_crypto_random(_mongocrypt_buffer_t *out, uint32_t count, mongocrypt_status_t *status) { - BSON_ASSERT_PARAM(out); - BSON_ASSERT(count <= INT_MAX); +bool _native_crypto_aes_256_cbc_decrypt(aes_256_args_t args) { + return _decrypt_with_cipher(EVP_aes_256_cbc(), NULL, args); +} - int ret = RAND_bytes(out->data, (int)count); - /* From man page: "RAND_bytes() and RAND_priv_bytes() return 1 on success, -1 - * if not supported by the current RAND method, or 0 on other failure. The - * error code can be obtained by ERR_get_error(3)" */ - if (ret == -1) { - CLIENT_ERR("secure random IV not supported: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } else if (ret == 0) { - CLIENT_ERR("failed to generate random IV: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - return true; +bool _native_crypto_aes_256_ecb_encrypt(aes_256_args_t args); // -Wmissing-prototypes: for testing only. + +bool _native_crypto_aes_256_ecb_encrypt(aes_256_args_t args) { + return _encrypt_with_cipher(EVP_aes_256_ecb(), NULL, args); } bool _native_crypto_aes_256_ctr_encrypt(aes_256_args_t args) { - return _encrypt_with_cipher(EVP_aes_256_ctr(), args); + return _encrypt_with_cipher(EVP_aes_256_ctr(), NULL, args); } bool _native_crypto_aes_256_ctr_decrypt(aes_256_args_t args) { - return _decrypt_with_cipher(EVP_aes_256_ctr(), args); + return _decrypt_with_cipher(EVP_aes_256_ctr(), NULL, args); } bool _native_crypto_hmac_sha_256(const _mongocrypt_buffer_t *key, @@ -273,4 +434,13 @@ bool _native_crypto_hmac_sha_256(const _mongocrypt_buffer_t *key, return _hmac_with_hash(EVP_sha256(), key, in, out, status); } +bool _native_crypto_hmac_sha_512(const _mongocrypt_buffer_t *key, + const _mongocrypt_buffer_t *in, + _mongocrypt_buffer_t *out, + mongocrypt_status_t *status) { + return _hmac_with_hash(EVP_sha512(), key, in, out, status); +} + +#endif /* OPENSSL_VERSION_NUMBER */ + #endif /* MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO */ diff --git a/ext/libmongocrypt/libmongocrypt/src/crypto/none.c b/ext/libmongocrypt/libmongocrypt/src/crypto/none.c index afc6547..db4cbb1 100644 --- a/ext/libmongocrypt/libmongocrypt/src/crypto/none.c +++ b/ext/libmongocrypt/libmongocrypt/src/crypto/none.c @@ -72,4 +72,4 @@ bool _native_crypto_hmac_sha_256(const _mongocrypt_buffer_t *key, return false; } -#endif /* MONGOCRYPT_ENABLE_CRYPTO */ \ No newline at end of file +#endif /* MONGOCRYPT_ENABLE_CRYPTO */ diff --git a/ext/libmongocrypt/libmongocrypt/src/csfle-markup.cpp b/ext/libmongocrypt/libmongocrypt/src/csfle-markup.cpp index b73b7d3..0306053 100644 --- a/ext/libmongocrypt/libmongocrypt/src/csfle-markup.cpp +++ b/ext/libmongocrypt/libmongocrypt/src/csfle-markup.cpp @@ -102,13 +102,15 @@ int do_main(int argc, const char *const *argv) { mcr_dll csfle = mcr_dll_open(argv[1]); auto close_csfle = DEFER({ mcr_dll_close(csfle); }); - if (csfle.error_string.data) { - std::cerr << "Failed to open [" << argv[1] << "] as a dynamic library: " << csfle.error_string.data << '\n'; + if (csfle.error_string.raw.data) { + std::cerr << "Failed to open [" << argv[1] << "] as a dynamic library: " << csfle.error_string.raw.data << '\n'; return 3; } #define LOAD_SYM(Name) \ + MC_BEGIN_CAST_FUNCTION_TYPE_STRICT_IGNORE \ auto Name = reinterpret_cast(mcr_dll_sym(csfle, #Name)); \ + MC_END_CAST_FUNCTION_TYPE_STRICT_IGNORE \ if (!Name) { \ fprintf(stderr, "Failed to load required symbol [%s] from the given csfle library", #Name); \ return 4; \ diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-dec128.h b/ext/libmongocrypt/libmongocrypt/src/mc-dec128.h index fd99487..0a6e7a2 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-dec128.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-dec128.h @@ -11,11 +11,11 @@ // the ImportDFP.cmake script: #ifndef MONGOCRYPT_INTELDFP // Notify includers that Decimal128 is not available: -#define MONGOCRYPT_HAVE_DECIMAL128_SUPPORT 0 +#define MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() false #else // With IntelDFP: // Tell includers that Decimal128 is okay: -#define MONGOCRYPT_HAVE_DECIMAL128_SUPPORT 1 +#define MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() true // Include the header that declares the DFP functions, which may be macros that // expand to renamed symbols: diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-dec128.test.cpp b/ext/libmongocrypt/libmongocrypt/src/mc-dec128.test.cpp index 9f7ac74..fa1d11c 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-dec128.test.cpp +++ b/ext/libmongocrypt/libmongocrypt/src/mc-dec128.test.cpp @@ -2,7 +2,7 @@ #include -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() #include @@ -76,4 +76,4 @@ int main() { std::puts("@@ctest-skip@@\n Decimal128 support is not enabled\n"); } -#endif \ No newline at end of file +#endif diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-efc-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-efc-private.h index bcf90f1..79b8676 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-efc-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-efc-private.h @@ -53,10 +53,7 @@ typedef struct { * into @efc. Fields are copied from @efc_bson. It is OK to free efc_bson after * this call. Fields are appended in reverse order to @efc->fields. Extra * unrecognized fields are not considered an error for forward compatibility. */ -bool mc_EncryptedFieldConfig_parse(mc_EncryptedFieldConfig_t *efc, - const bson_t *efc_bson, - mongocrypt_status_t *status, - bool use_range_v2); +bool mc_EncryptedFieldConfig_parse(mc_EncryptedFieldConfig_t *efc, const bson_t *efc_bson, mongocrypt_status_t *status); void mc_EncryptedFieldConfig_cleanup(mc_EncryptedFieldConfig_t *efc); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-efc.c b/ext/libmongocrypt/libmongocrypt/src/mc-efc.c index 205cd52..28f25ff 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-efc.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-efc.c @@ -51,7 +51,7 @@ _parse_supported_query_types(bson_iter_t *iter, supported_query_type_flags *out, BSON_ASSERT_PARAM(iter); BSON_ASSERT_PARAM(out); if (!BSON_ITER_HOLDS_DOCUMENT(iter)) { - CLIENT_ERR("When parsing supported query types: Expected type document, got: %d", bson_iter_type(iter)); + CLIENT_ERR("When parsing supported query types: Expected type document, got: %d", (int)bson_iter_type(iter)); return false; } @@ -66,7 +66,7 @@ _parse_supported_query_types(bson_iter_t *iter, supported_query_type_flags *out, } if (!BSON_ITER_HOLDS_UTF8(&query_type_iter)) { CLIENT_ERR("When parsing supported query types: Expected 'queryType' to be type UTF-8, got: %d", - bson_iter_type(&query_type_iter)); + (int)bson_iter_type(&query_type_iter)); return false; } const char *queryType = bson_iter_utf8(&query_type_iter, NULL /* length */); @@ -78,8 +78,7 @@ _parse_supported_query_types(bson_iter_t *iter, supported_query_type_flags *out, } /* _parse_field parses and prepends one field document to efc->fields. */ -static bool -_parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocrypt_status_t *status, bool use_range_v2) { +static bool _parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocrypt_status_t *status) { supported_query_type_flags query_types = SUPPORTS_NO_QUERIES; bson_iter_t field_iter; @@ -91,7 +90,7 @@ _parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocrypt_status_t return false; } if (!BSON_ITER_HOLDS_BINARY(&field_iter)) { - CLIENT_ERR("expected 'fields.keyId' to be type binary, got: %d", bson_iter_type(&field_iter)); + CLIENT_ERR("expected 'fields.keyId' to be type binary, got: %d", (int)bson_iter_type(&field_iter)); return false; } _mongocrypt_buffer_t field_keyid; @@ -106,7 +105,7 @@ _parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocrypt_status_t return false; } if (!BSON_ITER_HOLDS_UTF8(&field_iter)) { - CLIENT_ERR("expected 'fields.path' to be type UTF-8, got: %d", bson_iter_type(&field_iter)); + CLIENT_ERR("expected 'fields.path' to be type UTF-8, got: %d", (int)bson_iter_type(&field_iter)); return false; } field_path = bson_iter_utf8(&field_iter, NULL /* length */); @@ -141,8 +140,8 @@ _parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocrypt_status_t } } - if (query_types & SUPPORTS_RANGE_PREVIEW_DEPRECATED_QUERIES && use_range_v2) { - // When rangev2 is enabled ("range") error if "rangePreview" is included. + if (query_types & SUPPORTS_RANGE_PREVIEW_DEPRECATED_QUERIES) { + // Error if the removed "rangePreview" is included. // This check is intended to give an easier-to-understand earlier error. CLIENT_ERR("Cannot use field '%s' with 'rangePreview' queries. 'rangePreview' is unsupported. Use 'range' " "instead. 'range' is not compatible with 'rangePreview' and requires recreating the collection.", @@ -163,8 +162,7 @@ _parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocrypt_status_t bool mc_EncryptedFieldConfig_parse(mc_EncryptedFieldConfig_t *efc, const bson_t *efc_bson, - mongocrypt_status_t *status, - bool use_range_v2) { + mongocrypt_status_t *status) { bson_iter_t iter; BSON_ASSERT_PARAM(efc); @@ -189,7 +187,7 @@ bool mc_EncryptedFieldConfig_parse(mc_EncryptedFieldConfig_t *efc, if (!mc_iter_document_as_bson(&iter, &field, status)) { return false; } - if (!_parse_field(efc, &field, status, use_range_v2)) { + if (!_parse_field(efc, &field, status)) { return false; } // The first element of efc->fields contains the newly parsed field. diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle-blob-subtype-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-fle-blob-subtype-private.h index 4989034..c65b714 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle-blob-subtype-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle-blob-subtype-private.h @@ -46,6 +46,7 @@ typedef enum { /* Text Search Subtypes */ MC_SUBTYPE_FLE2IndexedTextEncryptedValue = 17, + MC_SUBTYPE_FLE2FindTextPayload = 18, } mc_fle_blob_subtype_t; #endif /* MC_FLE_BLOB_SUBTYPE_PRIVATE_H */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h index 5674d82..457f8dd 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h @@ -86,10 +86,7 @@ typedef struct { BSON_STATIC_ASSERT2(alignof_mc_FLE2RangeFindSpec_t, BSON_ALIGNOF(mc_FLE2RangeFindSpec_t) >= BSON_ALIGNOF(mc_FLE2RangeFindSpecEdgesInfo_t)); -bool mc_FLE2RangeFindSpec_parse(mc_FLE2RangeFindSpec_t *out, - const bson_iter_t *in, - bool use_range_v2, - mongocrypt_status_t *status); +bool mc_FLE2RangeFindSpec_parse(mc_FLE2RangeFindSpec_t *out, const bson_iter_t *in, mongocrypt_status_t *status); /** mc_FLE2RangeInsertSpec_t represents the range insert specification that is * encoded inside of a FLE2EncryptionPlaceholder. See @@ -114,10 +111,7 @@ typedef struct { BSON_STATIC_ASSERT2(alignof_mc_FLE2RangeInsertSpec_t, BSON_ALIGNOF(mc_FLE2RangeInsertSpec_t) >= BSON_ALIGNOF(bson_iter_t)); -bool mc_FLE2RangeInsertSpec_parse(mc_FLE2RangeInsertSpec_t *out, - const bson_iter_t *in, - bool use_range_v2, - mongocrypt_status_t *status); +bool mc_FLE2RangeInsertSpec_parse(mc_FLE2RangeInsertSpec_t *out, const bson_iter_t *in, mongocrypt_status_t *status); // Note: For the substring/suffix/prefix insert specs, all lengths are in terms of number of UTF-8 codepoints, not // number of bytes. @@ -131,6 +125,10 @@ typedef struct { uint32_t ub; } mc_FLE2SubstringInsertSpec_t; +bool mc_FLE2SubstringInsertSpec_parse(mc_FLE2SubstringInsertSpec_t *out, + const bson_iter_t *in, + mongocrypt_status_t *status); + /* mc_FLE2SuffixInsertSpec_t holds the parameters used to encode for suffix search. */ typedef struct { // lb is the lower bound on the length of suffixes to be indexed. @@ -139,6 +137,8 @@ typedef struct { uint32_t ub; } mc_FLE2SuffixInsertSpec_t; +bool mc_FLE2SuffixInsertSpec_parse(mc_FLE2SuffixInsertSpec_t *out, const bson_iter_t *in, mongocrypt_status_t *status); + /* mc_FLE2PrefixInsertSpec_t holds the parameters used to encode for prefix search. */ typedef struct { // lb is the lower bound on the length of prefixes to be indexed. @@ -147,6 +147,8 @@ typedef struct { uint32_t ub; } mc_FLE2PrefixInsertSpec_t; +bool mc_FLE2PrefixInsertSpec_parse(mc_FLE2PrefixInsertSpec_t *out, const bson_iter_t *in, mongocrypt_status_t *status); + /** mc_FLE2TextSearchInsertSpec_t represents the text search insert specification that is * encoded inside of a FLE2EncryptionPlaceholder. See * https://github.com/mongodb/mongo/blob/master/src/mongo/crypto/fle_field_schema.idl diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder.c index 7f67537..dcbe1d7 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder.c @@ -24,38 +24,38 @@ #include "mongocrypt-util-private.h" // mc_bson_type_to_string #include "mongocrypt.h" -#define CLIENT_ERR_PREFIXED_HELPER(Prefix, ErrorString, ...) CLIENT_ERR(Prefix ": " ErrorString, ##__VA_ARGS__) -#define CLIENT_ERR_PREFIXED(ErrorString, ...) CLIENT_ERR_PREFIXED_HELPER(ERROR_PREFIX, ErrorString, ##__VA_ARGS__) - // Common logic for testing field name, tracking duplication, and presence. #define IF_FIELD(Name) \ if (0 == strcmp(field, #Name)) { \ if (has_##Name) { \ - CLIENT_ERR_PREFIXED("Duplicate field '" #Name "' in placeholder bson"); \ + CLIENT_ERR(ERROR_PREFIX "Duplicate field '" #Name "' in placeholder bson"); \ goto fail; \ } \ - has_##Name = true; + has_##Name = true; \ + ((void)0) #define END_IF_FIELD \ continue; \ - } + } \ + else((void)0) #define CHECK_HAS(Name) \ if (!has_##Name) { \ - CLIENT_ERR_PREFIXED("Missing field '" #Name "' in placeholder"); \ + CLIENT_ERR(ERROR_PREFIX "Missing field '" #Name "' in placeholder"); \ goto fail; \ } // Common logic for parsing int32 greater than zero #define IF_FIELD_INT32_GT0_PARSE(Name, Dest, Iter) \ - IF_FIELD(Name) { \ + IF_FIELD(Name); \ + { \ if (!BSON_ITER_HOLDS_INT32(&Iter)) { \ - CLIENT_ERR_PREFIXED("'" #Name "' must be an int32"); \ + CLIENT_ERR(ERROR_PREFIX "'" #Name "' must be an int32"); \ goto fail; \ } \ int32_t val = bson_iter_int32(&Iter); \ if (val <= 0) { \ - CLIENT_ERR_PREFIXED("'" #Name "' must be greater than zero"); \ + CLIENT_ERR(ERROR_PREFIX "'" #Name "' must be greater than zero"); \ goto fail; \ } \ Dest = (uint32_t)val; \ @@ -66,7 +66,7 @@ void mc_FLE2EncryptionPlaceholder_init(mc_FLE2EncryptionPlaceholder_t *placehold memset(placeholder, 0, sizeof(mc_FLE2EncryptionPlaceholder_t)); } -#define ERROR_PREFIX "Error parsing FLE2EncryptionPlaceholder" +#define ERROR_PREFIX "Error parsing FLE2EncryptionPlaceholder: " bool mc_FLE2EncryptionPlaceholder_parse(mc_FLE2EncryptionPlaceholder_t *out, const bson_t *in, @@ -81,7 +81,7 @@ bool mc_FLE2EncryptionPlaceholder_parse(mc_FLE2EncryptionPlaceholder_t *out, mc_FLE2EncryptionPlaceholder_init(out); if (!bson_validate(in, BSON_VALIDATE_NONE, NULL) || !bson_iter_init(&iter, in)) { - CLIENT_ERR_PREFIXED("invalid BSON"); + CLIENT_ERR(ERROR_PREFIX "invalid BSON"); return false; } @@ -89,61 +89,65 @@ bool mc_FLE2EncryptionPlaceholder_parse(mc_FLE2EncryptionPlaceholder_t *out, const char *field = bson_iter_key(&iter); BSON_ASSERT(field); - IF_FIELD(t) { + IF_FIELD(t); + { int32_t type; if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("invalid marking, 't' must be an int32"); + CLIENT_ERR(ERROR_PREFIX "invalid marking, 't' must be an int32"); goto fail; } type = bson_iter_int32(&iter); if ((type != MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT) && (type != MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND)) { - CLIENT_ERR_PREFIXED("invalid placeholder type value: %d", type); + CLIENT_ERR(ERROR_PREFIX "invalid placeholder type value: %d", type); goto fail; } out->type = (mongocrypt_fle2_placeholder_type_t)type; } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(a) { + IF_FIELD(a); + { int32_t algorithm; if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("invalid marking, 'a' must be an int32"); + CLIENT_ERR(ERROR_PREFIX "invalid marking, 'a' must be an int32"); goto fail; } algorithm = bson_iter_int32(&iter); if (algorithm != MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED && algorithm != MONGOCRYPT_FLE2_ALGORITHM_EQUALITY && algorithm != MONGOCRYPT_FLE2_ALGORITHM_RANGE && algorithm != MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH) { - CLIENT_ERR_PREFIXED("invalid algorithm value: %d", algorithm); + CLIENT_ERR(ERROR_PREFIX "invalid algorithm value: %d", algorithm); goto fail; } out->algorithm = (mongocrypt_fle2_encryption_algorithm_t)algorithm; } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(ki) { + IF_FIELD(ki); + { if (!_mongocrypt_buffer_from_uuid_iter(&out->index_key_id, &iter)) { - CLIENT_ERR_PREFIXED("index key id must be a UUID"); + CLIENT_ERR(ERROR_PREFIX "index key id must be a UUID"); goto fail; } } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(ku) { + IF_FIELD(ku); + { if (!_mongocrypt_buffer_from_uuid_iter(&out->user_key_id, &iter)) { - CLIENT_ERR_PREFIXED("user key id must be a UUID"); + CLIENT_ERR(ERROR_PREFIX "user key id must be a UUID"); goto fail; } } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(v) { - memcpy(&out->v_iter, &iter, sizeof(bson_iter_t)); - } - END_IF_FIELD + IF_FIELD(v); + memcpy(&out->v_iter, &iter, sizeof(bson_iter_t)); + END_IF_FIELD; - IF_FIELD(cm) { + IF_FIELD(cm); + { if (!BSON_ITER_HOLDS_INT64(&iter)) { - CLIENT_ERR_PREFIXED("invalid marking, 'cm' must be an int64"); + CLIENT_ERR(ERROR_PREFIX "invalid marking, 'cm' must be an int64"); goto fail; } out->maxContentionFactor = bson_iter_int64(&iter); @@ -151,11 +155,12 @@ bool mc_FLE2EncryptionPlaceholder_parse(mc_FLE2EncryptionPlaceholder_t *out, goto fail; } } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(s) { + IF_FIELD(s); + { if (!BSON_ITER_HOLDS_INT64(&iter)) { - CLIENT_ERR_PREFIXED("invalid marking, 's' must be an int64"); + CLIENT_ERR(ERROR_PREFIX "invalid marking, 's' must be an int64"); goto fail; } out->sparsity = bson_iter_int64(&iter); @@ -163,7 +168,7 @@ bool mc_FLE2EncryptionPlaceholder_parse(mc_FLE2EncryptionPlaceholder_t *out, goto fail; } } - END_IF_FIELD + END_IF_FIELD; } CHECK_HAS(t) @@ -191,42 +196,41 @@ void mc_FLE2EncryptionPlaceholder_cleanup(mc_FLE2EncryptionPlaceholder_t *placeh } #undef ERROR_PREFIX -#define ERROR_PREFIX "Error validating contention" +#define ERROR_PREFIX "Error validating contention: " bool mc_validate_contention(int64_t contention, mongocrypt_status_t *status) { if (contention < 0) { - CLIENT_ERR_PREFIXED("contention must be non-negative, got: %" PRId64, contention); + CLIENT_ERR(ERROR_PREFIX "contention must be non-negative, got: %" PRId64, contention); return false; } if (contention == INT64_MAX) { - CLIENT_ERR_PREFIXED("contention must be < INT64_MAX, got: %" PRId64, contention); + CLIENT_ERR(ERROR_PREFIX "contention must be < INT64_MAX, got: %" PRId64, contention); return false; } return true; } #undef ERROR_PREFIX -#define ERROR_PREFIX "Error validating sparsity" +#define ERROR_PREFIX "Error validating sparsity: " bool mc_validate_sparsity(int64_t sparsity, mongocrypt_status_t *status) { if (sparsity < 0) { - CLIENT_ERR_PREFIXED("sparsity must be non-negative, got: %" PRId64, sparsity); + CLIENT_ERR(ERROR_PREFIX "sparsity must be non-negative, got: %" PRId64, sparsity); return false; } // mc_getEdgesInt expects a size_t sparsity. if ((uint64_t)sparsity >= SIZE_MAX) { - CLIENT_ERR_PREFIXED("sparsity must be < %zu, got: %" PRId64, SIZE_MAX, sparsity); + CLIENT_ERR(ERROR_PREFIX "sparsity must be < %zu, got: %" PRId64, SIZE_MAX, sparsity); return false; } return true; } #undef ERROR_PREFIX -#define ERROR_PREFIX "Error parsing FLE2RangeFindSpecEdgesInfo" +#define ERROR_PREFIX "Error parsing FLE2RangeFindSpecEdgesInfo: " static bool mc_FLE2RangeFindSpecEdgesInfo_parse(mc_FLE2RangeFindSpecEdgesInfo_t *out, const bson_iter_t *in, - bool use_range_v2, mongocrypt_status_t *status) { bson_iter_t iter; bool has_lowerBound = false, has_lbIncluded = false, has_upperBound = false, has_ubIncluded = false, @@ -238,7 +242,7 @@ static bool mc_FLE2RangeFindSpecEdgesInfo_parse(mc_FLE2RangeFindSpecEdgesInfo_t iter = *in; if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { - CLIENT_ERR_PREFIXED("must be an iterator to a document"); + CLIENT_ERR(ERROR_PREFIX "must be an iterator to a document"); return false; } bson_iter_recurse(&iter, &iter); @@ -247,73 +251,73 @@ static bool mc_FLE2RangeFindSpecEdgesInfo_parse(mc_FLE2RangeFindSpecEdgesInfo_t const char *field = bson_iter_key(&iter); BSON_ASSERT(field); - IF_FIELD(lowerBound) { - out->lowerBound = iter; - } - END_IF_FIELD + IF_FIELD(lowerBound); + out->lowerBound = iter; + END_IF_FIELD; - IF_FIELD(lbIncluded) { + IF_FIELD(lbIncluded); + { if (!BSON_ITER_HOLDS_BOOL(&iter)) { - CLIENT_ERR_PREFIXED("'lbIncluded' must be a bool"); + CLIENT_ERR(ERROR_PREFIX "'lbIncluded' must be a bool"); goto fail; } out->lbIncluded = bson_iter_bool(&iter); } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(upperBound) { - out->upperBound = iter; - } - END_IF_FIELD + IF_FIELD(upperBound); + out->upperBound = iter; + END_IF_FIELD; - IF_FIELD(ubIncluded) { + IF_FIELD(ubIncluded); + { if (!BSON_ITER_HOLDS_BOOL(&iter)) { - CLIENT_ERR_PREFIXED("'ubIncluded' must be a bool"); + CLIENT_ERR(ERROR_PREFIX "'ubIncluded' must be a bool"); goto fail; } out->ubIncluded = bson_iter_bool(&iter); } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(indexMin) { - out->indexMin = iter; - } - END_IF_FIELD + IF_FIELD(indexMin); + out->indexMin = iter; + END_IF_FIELD; - IF_FIELD(indexMax) { - out->indexMax = iter; - } - END_IF_FIELD + IF_FIELD(indexMax); + out->indexMax = iter; + END_IF_FIELD; - IF_FIELD(precision) { + IF_FIELD(precision); + { if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("'precision' must be an int32"); + CLIENT_ERR(ERROR_PREFIX "'precision' must be an int32"); goto fail; } int32_t val = bson_iter_int32(&iter); if (val < 0) { - CLIENT_ERR_PREFIXED("'precision' must be non-negative"); + CLIENT_ERR(ERROR_PREFIX "'precision' must be non-negative"); goto fail; } out->precision = OPT_I32(val); } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(trimFactor) { + IF_FIELD(trimFactor); + { if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("'trimFactor' must be an int32"); + CLIENT_ERR(ERROR_PREFIX "'trimFactor' must be an int32"); goto fail; } int32_t val = bson_iter_int32(&iter); if (val < 0) { - CLIENT_ERR_PREFIXED("'trimFactor' must be non-negative"); + CLIENT_ERR(ERROR_PREFIX "'trimFactor' must be non-negative"); goto fail; } out->trimFactor = OPT_I32(val); } - END_IF_FIELD + END_IF_FIELD; } CHECK_HAS(lowerBound) @@ -325,11 +329,6 @@ static bool mc_FLE2RangeFindSpecEdgesInfo_parse(mc_FLE2RangeFindSpecEdgesInfo_t // Do not error if precision is not present. Precision optional and only // applies to double/decimal128. - if (!use_range_v2 && out->trimFactor.set) { - CLIENT_ERR_PREFIXED("'trimFactor' is not supported for QE range v1"); - return false; - } - return true; fail: @@ -337,12 +336,9 @@ static bool mc_FLE2RangeFindSpecEdgesInfo_parse(mc_FLE2RangeFindSpecEdgesInfo_t } #undef ERROR_PREFIX -#define ERROR_PREFIX "Error parsing FLE2RangeFindSpec" +#define ERROR_PREFIX "Error parsing FLE2RangeFindSpec: " -bool mc_FLE2RangeFindSpec_parse(mc_FLE2RangeFindSpec_t *out, - const bson_iter_t *in, - bool use_range_v2, - mongocrypt_status_t *status) { +bool mc_FLE2RangeFindSpec_parse(mc_FLE2RangeFindSpec_t *out, const bson_iter_t *in, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(out); BSON_ASSERT_PARAM(in); @@ -352,7 +348,7 @@ bool mc_FLE2RangeFindSpec_parse(mc_FLE2RangeFindSpec_t *out, *out = (mc_FLE2RangeFindSpec_t){{{{0}}}}; if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { - CLIENT_ERR_PREFIXED("must be an iterator to a document"); + CLIENT_ERR(ERROR_PREFIX "must be an iterator to a document"); return false; } bson_iter_recurse(&iter, &iter); @@ -361,54 +357,58 @@ bool mc_FLE2RangeFindSpec_parse(mc_FLE2RangeFindSpec_t *out, const char *field = bson_iter_key(&iter); BSON_ASSERT(field); - IF_FIELD(edgesInfo) { - if (!mc_FLE2RangeFindSpecEdgesInfo_parse(&out->edgesInfo.value, &iter, use_range_v2, status)) { + IF_FIELD(edgesInfo); + { + if (!mc_FLE2RangeFindSpecEdgesInfo_parse(&out->edgesInfo.value, &iter, status)) { goto fail; } out->edgesInfo.set = true; } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(payloadId) { + IF_FIELD(payloadId); + { if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("'payloadId' must be an int32"); + CLIENT_ERR(ERROR_PREFIX "'payloadId' must be an int32"); goto fail; } out->payloadId = bson_iter_int32(&iter); } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(firstOperator) { + IF_FIELD(firstOperator); + { if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("'firstOperator' must be an int32"); + CLIENT_ERR(ERROR_PREFIX "'firstOperator' must be an int32"); goto fail; } const int32_t first_op = bson_iter_int32(&iter); if (first_op < FLE2RangeOperator_min_val || first_op > FLE2RangeOperator_max_val) { - CLIENT_ERR_PREFIXED("'firstOperator' must be between %d and %d", - FLE2RangeOperator_min_val, - FLE2RangeOperator_max_val); + CLIENT_ERR(ERROR_PREFIX "'firstOperator' must be between %d and %d", + FLE2RangeOperator_min_val, + FLE2RangeOperator_max_val); goto fail; } out->firstOperator = (mc_FLE2RangeOperator_t)first_op; } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(secondOperator) { + IF_FIELD(secondOperator); + { if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("'secondOperator' must be an int32"); + CLIENT_ERR(ERROR_PREFIX "'secondOperator' must be an int32"); goto fail; } const int32_t second_op = bson_iter_int32(&iter); if (second_op < FLE2RangeOperator_min_val || second_op > FLE2RangeOperator_max_val) { - CLIENT_ERR_PREFIXED("'secondOperator' must be between %d and %d", - FLE2RangeOperator_min_val, - FLE2RangeOperator_max_val); + CLIENT_ERR(ERROR_PREFIX "'secondOperator' must be between %d and %d", + FLE2RangeOperator_min_val, + FLE2RangeOperator_max_val); goto fail; } out->secondOperator = (mc_FLE2RangeOperator_t)second_op; } - END_IF_FIELD + END_IF_FIELD; } // edgesInfo is optional. Do not require it. @@ -422,12 +422,9 @@ bool mc_FLE2RangeFindSpec_parse(mc_FLE2RangeFindSpec_t *out, } #undef ERROR_PREFIX -#define ERROR_PREFIX "Error parsing FLE2RangeInsertSpec" +#define ERROR_PREFIX "Error parsing FLE2RangeInsertSpec: " -bool mc_FLE2RangeInsertSpec_parse(mc_FLE2RangeInsertSpec_t *out, - const bson_iter_t *in, - bool use_range_v2, - mongocrypt_status_t *status) { +bool mc_FLE2RangeInsertSpec_parse(mc_FLE2RangeInsertSpec_t *out, const bson_iter_t *in, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(out); BSON_ASSERT_PARAM(in); @@ -437,7 +434,7 @@ bool mc_FLE2RangeInsertSpec_parse(mc_FLE2RangeInsertSpec_t *out, bool has_v = false, has_min = false, has_max = false, has_precision = false, has_trimFactor = false; if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { - CLIENT_ERR_PREFIXED("must be an iterator to a document"); + CLIENT_ERR(ERROR_PREFIX "must be an iterator to a document"); return false; } bson_iter_recurse(&iter, &iter); @@ -446,48 +443,47 @@ bool mc_FLE2RangeInsertSpec_parse(mc_FLE2RangeInsertSpec_t *out, const char *field = bson_iter_key(&iter); BSON_ASSERT(field); - IF_FIELD(v) { - out->v = iter; - } - END_IF_FIELD + IF_FIELD(v); + out->v = iter; + END_IF_FIELD; - IF_FIELD(min) { - out->min = iter; - } - END_IF_FIELD + IF_FIELD(min); + out->min = iter; + END_IF_FIELD; - IF_FIELD(max) { - out->max = iter; - } - END_IF_FIELD + IF_FIELD(max); + out->max = iter; + END_IF_FIELD; - IF_FIELD(precision) { + IF_FIELD(precision); + { if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("'precision' must be an int32"); + CLIENT_ERR(ERROR_PREFIX "'precision' must be an int32"); goto fail; } int32_t val = bson_iter_int32(&iter); if (val < 0) { - CLIENT_ERR_PREFIXED("'precision' must be non-negative"); + CLIENT_ERR(ERROR_PREFIX "'precision' must be non-negative"); goto fail; } out->precision = OPT_I32(val); } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(trimFactor) { + IF_FIELD(trimFactor); + { if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("'trimFactor' must be an int32"); + CLIENT_ERR(ERROR_PREFIX "'trimFactor' must be an int32"); goto fail; } int32_t val = bson_iter_int32(&iter); if (val < 0) { - CLIENT_ERR_PREFIXED("'trimFactor' must be non-negative"); + CLIENT_ERR(ERROR_PREFIX "'trimFactor' must be non-negative"); goto fail; } out->trimFactor = OPT_I32(val); } - END_IF_FIELD + END_IF_FIELD; } CHECK_HAS(v) @@ -496,11 +492,6 @@ bool mc_FLE2RangeInsertSpec_parse(mc_FLE2RangeInsertSpec_t *out, // Do not error if precision is not present. Precision optional and only // applies to double/decimal128. - if (!use_range_v2 && out->trimFactor.set) { - CLIENT_ERR_PREFIXED("'trimFactor' is not supported for QE range v1"); - return false; - } - return true; fail: @@ -509,11 +500,11 @@ bool mc_FLE2RangeInsertSpec_parse(mc_FLE2RangeInsertSpec_t *out, #undef ERROR_PREFIX -#define ERROR_PREFIX "Error parsing FLE2SubstringInsertSpec" +#define ERROR_PREFIX "Error parsing FLE2SubstringInsertSpec: " -static bool mc_FLE2SubstringInsertSpec_parse(mc_FLE2SubstringInsertSpec_t *out, - const bson_iter_t *in, - mongocrypt_status_t *status) { +bool mc_FLE2SubstringInsertSpec_parse(mc_FLE2SubstringInsertSpec_t *out, + const bson_iter_t *in, + mongocrypt_status_t *status) { bson_iter_t iter; bool has_mlen = false, has_ub = false, has_lb = false; BSON_ASSERT_PARAM(out); @@ -522,7 +513,7 @@ static bool mc_FLE2SubstringInsertSpec_parse(mc_FLE2SubstringInsertSpec_t *out, iter = *in; if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { - CLIENT_ERR_PREFIXED("must be an iterator to a document"); + CLIENT_ERR(ERROR_PREFIX "must be an iterator to a document"); return false; } bson_iter_recurse(&iter, &iter); @@ -537,11 +528,11 @@ static bool mc_FLE2SubstringInsertSpec_parse(mc_FLE2SubstringInsertSpec_t *out, CHECK_HAS(ub) CHECK_HAS(lb) if (out->ub < out->lb) { - CLIENT_ERR_PREFIXED("upper bound cannot be less than the lower bound"); + CLIENT_ERR(ERROR_PREFIX "upper bound cannot be less than the lower bound"); goto fail; } if (out->mlen < out->ub) { - CLIENT_ERR_PREFIXED("maximum indexed length cannot be less than the upper bound"); + CLIENT_ERR(ERROR_PREFIX "maximum indexed length cannot be less than the upper bound"); goto fail; } return true; @@ -551,10 +542,9 @@ static bool mc_FLE2SubstringInsertSpec_parse(mc_FLE2SubstringInsertSpec_t *out, #undef ERROR_PREFIX -#define ERROR_PREFIX "Error parsing FLE2SuffixInsertSpec" +#define ERROR_PREFIX "Error parsing FLE2SuffixInsertSpec: " -static bool -mc_FLE2SuffixInsertSpec_parse(mc_FLE2SuffixInsertSpec_t *out, const bson_iter_t *in, mongocrypt_status_t *status) { +bool mc_FLE2SuffixInsertSpec_parse(mc_FLE2SuffixInsertSpec_t *out, const bson_iter_t *in, mongocrypt_status_t *status) { bson_iter_t iter; bool has_ub = false, has_lb = false; @@ -564,7 +554,7 @@ mc_FLE2SuffixInsertSpec_parse(mc_FLE2SuffixInsertSpec_t *out, const bson_iter_t iter = *in; if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { - CLIENT_ERR_PREFIXED("must be an iterator to a document"); + CLIENT_ERR(ERROR_PREFIX "must be an iterator to a document"); return false; } bson_iter_recurse(&iter, &iter); @@ -577,7 +567,7 @@ mc_FLE2SuffixInsertSpec_parse(mc_FLE2SuffixInsertSpec_t *out, const bson_iter_t CHECK_HAS(ub) CHECK_HAS(lb) if (out->ub < out->lb) { - CLIENT_ERR_PREFIXED("upper bound cannot be less than the lower bound"); + CLIENT_ERR(ERROR_PREFIX "upper bound cannot be less than the lower bound"); goto fail; } return true; @@ -587,10 +577,9 @@ mc_FLE2SuffixInsertSpec_parse(mc_FLE2SuffixInsertSpec_t *out, const bson_iter_t #undef ERROR_PREFIX -#define ERROR_PREFIX "Error parsing FLE2PrefixInsertSpec" +#define ERROR_PREFIX "Error parsing FLE2PrefixInsertSpec: " -static bool -mc_FLE2PrefixInsertSpec_parse(mc_FLE2PrefixInsertSpec_t *out, const bson_iter_t *in, mongocrypt_status_t *status) { +bool mc_FLE2PrefixInsertSpec_parse(mc_FLE2PrefixInsertSpec_t *out, const bson_iter_t *in, mongocrypt_status_t *status) { bson_iter_t iter; bool has_ub = false, has_lb = false; BSON_ASSERT_PARAM(out); @@ -599,7 +588,7 @@ mc_FLE2PrefixInsertSpec_parse(mc_FLE2PrefixInsertSpec_t *out, const bson_iter_t iter = *in; if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { - CLIENT_ERR_PREFIXED("must be an iterator to a document"); + CLIENT_ERR(ERROR_PREFIX "must be an iterator to a document"); return false; } bson_iter_recurse(&iter, &iter); @@ -612,7 +601,7 @@ mc_FLE2PrefixInsertSpec_parse(mc_FLE2PrefixInsertSpec_t *out, const bson_iter_t CHECK_HAS(ub) CHECK_HAS(lb) if (out->ub < out->lb) { - CLIENT_ERR_PREFIXED("upper bound cannot be less than the lower bound"); + CLIENT_ERR(ERROR_PREFIX "upper bound cannot be less than the lower bound"); goto fail; } return true; @@ -622,7 +611,7 @@ mc_FLE2PrefixInsertSpec_parse(mc_FLE2PrefixInsertSpec_t *out, const bson_iter_t #undef ERROR_PREFIX -#define ERROR_PREFIX "Error parsing FLE2TextSearchInsertSpec" +#define ERROR_PREFIX "Error parsing FLE2TextSearchInsertSpec: " bool mc_FLE2TextSearchInsertSpec_parse(mc_FLE2TextSearchInsertSpec_t *out, const bson_iter_t *in, @@ -637,7 +626,7 @@ bool mc_FLE2TextSearchInsertSpec_parse(mc_FLE2TextSearchInsertSpec_t *out, bool has_substr = false, has_suffix = false, has_prefix = false; if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { - CLIENT_ERR_PREFIXED("must be an iterator to a document"); + CLIENT_ERR(ERROR_PREFIX "must be an iterator to a document"); return false; } bson_iter_recurse(&iter, &iter); @@ -646,72 +635,74 @@ bool mc_FLE2TextSearchInsertSpec_parse(mc_FLE2TextSearchInsertSpec_t *out, const char *field = bson_iter_key(&iter); BSON_ASSERT(field); - IF_FIELD(v) { + IF_FIELD(v); + { out->v = bson_iter_utf8(&iter, &out->len); if (!out->v) { - CLIENT_ERR_PREFIXED("unsupported BSON type: %s for text search", - mc_bson_type_to_string(bson_iter_type(&iter))); + CLIENT_ERR(ERROR_PREFIX "unsupported BSON type: %s for text search", + mc_bson_type_to_string(bson_iter_type(&iter))); goto fail; } out->v_iter = iter; } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(casef) { + IF_FIELD(casef); + { if (!BSON_ITER_HOLDS_BOOL(&iter)) { - CLIENT_ERR_PREFIXED("'casef' must be a bool"); + CLIENT_ERR(ERROR_PREFIX "'casef' must be a bool"); goto fail; } out->casef = bson_iter_bool(&iter); } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(diacf) { + IF_FIELD(diacf); + { if (!BSON_ITER_HOLDS_BOOL(&iter)) { - CLIENT_ERR_PREFIXED("'diacf' must be a bool"); + CLIENT_ERR(ERROR_PREFIX "'diacf' must be a bool"); goto fail; } out->diacf = bson_iter_bool(&iter); } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(substr) { + IF_FIELD(substr); + { if (!mc_FLE2SubstringInsertSpec_parse(&out->substr.value, &iter, status)) { goto fail; } out->substr.set = true; } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(suffix) { + IF_FIELD(suffix); + { if (!mc_FLE2SuffixInsertSpec_parse(&out->suffix.value, &iter, status)) { goto fail; } out->suffix.set = true; } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(prefix) { + IF_FIELD(prefix); + { if (!mc_FLE2PrefixInsertSpec_parse(&out->prefix.value, &iter, status)) { goto fail; } out->prefix.set = true; } - END_IF_FIELD + END_IF_FIELD; } CHECK_HAS(v) CHECK_HAS(casef) CHECK_HAS(diacf) - // one of substr/suffix/prefix must be set - if (!(has_substr || has_suffix || has_prefix)) { - CLIENT_ERR_PREFIXED("Must have a substring, suffix, or prefix index specification"); - goto fail; - } + return true; fail: return false; } -#undef ERROR_PREFIX \ No newline at end of file +#undef ERROR_PREFIX diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-v2.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-v2.c index 1566f3c..4cf4955 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-v2.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-v2.c @@ -17,6 +17,7 @@ #include #include "mc-fle2-find-equality-payload-private-v2.h" +#include "mc-parse-utils-private.h" #include "mongocrypt-buffer-private.h" #include "mongocrypt.h" @@ -46,21 +47,7 @@ void mc_FLE2FindEqualityPayloadV2_cleanup(mc_FLE2FindEqualityPayloadV2_t *payloa #define PARSE_BINARY(Name, Dest) \ IF_FIELD(Name) { \ - bson_subtype_t subtype; \ - uint32_t len; \ - const uint8_t *data; \ - if (bson_iter_type(&iter) != BSON_TYPE_BINARY) { \ - CLIENT_ERR("Field '" #Name "' expected to be bindata, got: %d", bson_iter_type(&iter)); \ - goto fail; \ - } \ - bson_iter_binary(&iter, &subtype, &len, &data); \ - if (subtype != BSON_SUBTYPE_BINARY) { \ - CLIENT_ERR("Field '" #Name "' expected to be bindata subtype %d, got: %d", BSON_SUBTYPE_BINARY, subtype); \ - goto fail; \ - } \ - if (!_mongocrypt_buffer_copy_from_binary_iter(&out->Dest, &iter)) { \ - CLIENT_ERR("Unable to create mongocrypt buffer for BSON binary " \ - "field in '" #Name "'"); \ + if (!parse_bindata(BSON_SUBTYPE_BINARY, &iter, &out->Dest, status)) { \ goto fail; \ } \ } \ @@ -70,7 +57,8 @@ void mc_FLE2FindEqualityPayloadV2_cleanup(mc_FLE2FindEqualityPayloadV2_t *payloa if (!has_##Name) { \ CLIENT_ERR("Missing field '" #Name "' in payload"); \ goto fail; \ - } + } else \ + ((void)0) bool mc_FLE2FindEqualityPayloadV2_parse(mc_FLE2FindEqualityPayloadV2_t *out, const bson_t *in, @@ -117,7 +105,8 @@ bool mc_FLE2FindEqualityPayloadV2_parse(mc_FLE2FindEqualityPayloadV2_t *out, #define APPEND_BINDATA(name, value) \ if (!_mongocrypt_buffer_append(&(value), out, name, -1)) { \ return false; \ - } + } else \ + ((void)0) bool mc_FLE2FindEqualityPayloadV2_serialize(const mc_FLE2FindEqualityPayloadV2_t *payload, bson_t *out) { BSON_ASSERT_PARAM(payload); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload.c index d6d7a71..86a4733 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload.c @@ -17,6 +17,7 @@ #include #include "mc-fle2-find-equality-payload-private.h" +#include "mc-parse-utils-private.h" #include "mongocrypt-buffer-private.h" #include "mongocrypt.h" @@ -47,21 +48,7 @@ void mc_FLE2FindEqualityPayload_cleanup(mc_FLE2FindEqualityPayload_t *payload) { #define PARSE_BINARY(Name, Dest) \ IF_FIELD(Name) { \ - bson_subtype_t subtype; \ - uint32_t len; \ - const uint8_t *data; \ - if (bson_iter_type(&iter) != BSON_TYPE_BINARY) { \ - CLIENT_ERR("Field '" #Name "' expected to be bindata, got: %d", bson_iter_type(&iter)); \ - goto fail; \ - } \ - bson_iter_binary(&iter, &subtype, &len, &data); \ - if (subtype != BSON_SUBTYPE_BINARY) { \ - CLIENT_ERR("Field '" #Name "' expected to be bindata subtype %d, got: %d", BSON_SUBTYPE_BINARY, subtype); \ - goto fail; \ - } \ - if (!_mongocrypt_buffer_copy_from_binary_iter(&out->Dest, &iter)) { \ - CLIENT_ERR("Unable to create mongocrypt buffer for BSON binary " \ - "field in '" #Name "'"); \ + if (!parse_bindata(BSON_SUBTYPE_BINARY, &iter, &out->Dest, status)) { \ goto fail; \ } \ } \ @@ -71,7 +58,8 @@ void mc_FLE2FindEqualityPayload_cleanup(mc_FLE2FindEqualityPayload_t *payload) { if (!has_##Name) { \ CLIENT_ERR("Missing field '" #Name "' in payload"); \ goto fail; \ - } + } else \ + ((void)0) bool mc_FLE2FindEqualityPayload_parse(mc_FLE2FindEqualityPayload_t *out, const bson_t *in, @@ -120,7 +108,8 @@ bool mc_FLE2FindEqualityPayload_parse(mc_FLE2FindEqualityPayload_t *out, #define PAYLOAD_APPEND_BINDATA(name, value) \ if (!_mongocrypt_buffer_append(&(value), out, name, -1)) { \ return false; \ - } + } else \ + ((void)0) bool mc_FLE2FindEqualityPayload_serialize(const mc_FLE2FindEqualityPayload_t *payload, bson_t *out) { BSON_ASSERT_PARAM(payload); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-private-v2.h b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-private-v2.h index 79bbd8c..f09b72e 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-private-v2.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-private-v2.h @@ -101,7 +101,7 @@ typedef struct { void mc_FLE2FindRangePayloadV2_init(mc_FLE2FindRangePayloadV2_t *payload); -bool mc_FLE2FindRangePayloadV2_serialize(const mc_FLE2FindRangePayloadV2_t *payload, bson_t *out, bool use_range_v2); +bool mc_FLE2FindRangePayloadV2_serialize(const mc_FLE2FindRangePayloadV2_t *payload, bson_t *out); void mc_FLE2FindRangePayloadV2_cleanup(mc_FLE2FindRangePayloadV2_t *payload); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-v2.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-v2.c index e07cd76..afea2e8 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-v2.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-v2.c @@ -51,9 +51,10 @@ void mc_FLE2FindRangePayloadV2_cleanup(mc_FLE2FindRangePayloadV2_t *payload) { #define APPEND_BINDATA(out, name, value) \ if (!_mongocrypt_buffer_append(&(value), out, name, -1)) { \ return false; \ - } + } else \ + ((void)0) -bool mc_FLE2FindRangePayloadV2_serialize(const mc_FLE2FindRangePayloadV2_t *payload, bson_t *out, bool use_range_v2) { +bool mc_FLE2FindRangePayloadV2_serialize(const mc_FLE2FindRangePayloadV2_t *payload, bson_t *out) { BSON_ASSERT_PARAM(out); BSON_ASSERT_PARAM(payload); @@ -131,39 +132,37 @@ bool mc_FLE2FindRangePayloadV2_serialize(const mc_FLE2FindRangePayloadV2_t *payl return false; } - if (use_range_v2) { - // Encode parameters that were used to generate the mincover. - // The crypto parameters are all optionally set. Find payloads may come in pairs (a lower and upper bound). - // One of the pair includes the mincover. The other payload was not generated with crypto parameters. + // Encode parameters that were used to generate the mincover. + // The crypto parameters are all optionally set. Find payloads may come in pairs (a lower and upper bound). + // One of the pair includes the mincover. The other payload was not generated with crypto parameters. - if (payload->sparsity.set) { - if (!BSON_APPEND_INT64(out, "sp", payload->sparsity.value)) { - return false; - } + if (payload->sparsity.set) { + if (!BSON_APPEND_INT64(out, "sp", payload->sparsity.value)) { + return false; } + } - if (payload->precision.set) { - if (!BSON_APPEND_INT32(out, "pn", payload->precision.value)) { - return false; - } + if (payload->precision.set) { + if (!BSON_APPEND_INT32(out, "pn", payload->precision.value)) { + return false; } + } - if (payload->trimFactor.set) { - if (!BSON_APPEND_INT32(out, "tf", payload->trimFactor.value)) { - return false; - } + if (payload->trimFactor.set) { + if (!BSON_APPEND_INT32(out, "tf", payload->trimFactor.value)) { + return false; } + } - if (payload->indexMin.value_type != BSON_TYPE_EOD) { - if (!BSON_APPEND_VALUE(out, "mn", &payload->indexMin)) { - return false; - } + if (payload->indexMin.value_type != BSON_TYPE_EOD) { + if (!BSON_APPEND_VALUE(out, "mn", &payload->indexMin)) { + return false; } + } - if (payload->indexMax.value_type != BSON_TYPE_EOD) { - if (!BSON_APPEND_VALUE(out, "mx", &payload->indexMax)) { - return false; - } + if (payload->indexMax.value_type != BSON_TYPE_EOD) { + if (!BSON_APPEND_VALUE(out, "mx", &payload->indexMax)) { + return false; } } diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload.c index 1a3610e..cfec4ef 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload.c @@ -52,7 +52,8 @@ void mc_FLE2FindRangePayload_cleanup(mc_FLE2FindRangePayload_t *payload) { #define APPEND_BINDATA(out, name, value) \ if (!_mongocrypt_buffer_append(&(value), out, name, -1)) { \ return false; \ - } + } else \ + ((void)0) bool mc_FLE2FindRangePayload_serialize(const mc_FLE2FindRangePayload_t *payload, bson_t *out) { BSON_ASSERT_PARAM(out); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-text-payload-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-text-payload-private.h new file mode 100644 index 0000000..da6826a --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-text-payload-private.h @@ -0,0 +1,122 @@ +/* + * 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_FLE2_FIND_TEXT_PAYLOAD_PRIVATE_H +#define MC_FLE2_FIND_TEXT_PAYLOAD_PRIVATE_H + +#include "mc-fle2-encryption-placeholder-private.h" +#include "mongocrypt-buffer-private.h" +#include "mongocrypt-private.h" +#include "mongocrypt.h" + +#define DEF_TEXT_SEARCH_FIND_TOKEN_SET(Type) \ + typedef struct { \ + _mongocrypt_buffer_t edcDerivedToken; \ + _mongocrypt_buffer_t escDerivedToken; \ + _mongocrypt_buffer_t serverDerivedFromDataToken; \ + } mc_Text##Type##FindTokenSet_t; + +DEF_TEXT_SEARCH_FIND_TOKEN_SET(Exact); +DEF_TEXT_SEARCH_FIND_TOKEN_SET(Substring); +DEF_TEXT_SEARCH_FIND_TOKEN_SET(Suffix); +DEF_TEXT_SEARCH_FIND_TOKEN_SET(Prefix); + +typedef struct { + struct { + mc_TextExactFindTokenSet_t value; + bool set; + } exact; // e + + struct { + mc_TextSubstringFindTokenSet_t value; + bool set; + } substring; // s + + struct { + mc_TextSuffixFindTokenSet_t value; + bool set; + } suffix; // u + + struct { + mc_TextPrefixFindTokenSet_t value; + bool set; + } prefix; // p +} mc_TextSearchFindTokenSets_t; + +/** + * FLE2FindTextPayload represents an FLE2 payload of a substring/suffix/prefix indexed field to + * query. It is created client side. + * + * FLE2FindTextPayload has the following data layout: + * + * struct { + * uint8_t fle_blob_subtype = 18; + * uint8_t bson[]; + * } FLE2FindTextPayload; + * + * bson is a BSON document of this form: + * { + * ts: { + * e: optional // required tokens if doing full string match + * s: optional // required tokens if doing substring match + * u: optional // required tokens if doing suffix match + * p: optional // required tokens if doing prefix match + * } + * cm: // Queryable Encryption max contentionFactor + * cf: // case folding parameter + * df: // diacritic folding parameter + * ss: optional // substring-indexing parameters (if applicable) + * fs: optional // suffix-indexing parameters (if applicable) + * ps: optional // prefix-indexing parameters (if applicable) + * } + * where for each of T in [Exact, Substring, Suffix, Prefix], TextFindTokenSet is a document of form: + * { + * d: // EDCTextDerivedFromDataToken + * s: // ESCTextDerivedFromDataToken + * l: // ServerTextDerivedFromDataToken + * } + */ +typedef struct { + mc_TextSearchFindTokenSets_t tokenSets; // ts + int64_t maxContentionFactor; // cm + bool caseFold; // cf + bool diacriticFold; // df + + struct { + mc_FLE2SubstringInsertSpec_t value; + bool set; + } substringSpec; // ss + + struct { + mc_FLE2SuffixInsertSpec_t value; + bool set; + } suffixSpec; // fs + + struct { + mc_FLE2PrefixInsertSpec_t value; + bool set; + } prefixSpec; // ps +} mc_FLE2FindTextPayload_t; + +void mc_FLE2FindTextPayload_init(mc_FLE2FindTextPayload_t *payload); + +bool mc_FLE2FindTextPayload_parse(mc_FLE2FindTextPayload_t *out, const bson_t *in, mongocrypt_status_t *status); + +bool mc_FLE2FindTextPayload_serialize(const mc_FLE2FindTextPayload_t *payload, bson_t *out); + +void mc_FLE2FindTextPayload_cleanup(mc_FLE2FindTextPayload_t *payload); + +#endif /* MC_FLE2_FIND_TEXT_PAYLOAD_PRIVATE_H */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-text-payload.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-text-payload.c new file mode 100644 index 0000000..ecb339d --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-text-payload.c @@ -0,0 +1,477 @@ +/* + * 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 +#include + +#include "mc-fle2-find-text-payload-private.h" +#include "mc-parse-utils-private.h" +#include "mongocrypt-buffer-private.h" +#include "mongocrypt-util-private.h" +#include "mongocrypt.h" + +#define IF_FIELD(Name) \ + if (0 == strcmp(field, #Name)) { \ + if (has_##Name) { \ + CLIENT_ERR("Error parsing %s: Duplicate field '" #Name "'", class_name); \ + goto fail; \ + } \ + has_##Name = true; + +#define END_IF_FIELD \ + continue; \ + } + +#define CHECK_HAS(Name) \ + if (!has_##Name) { \ + CLIENT_ERR("Error parsing %s: Missing required field '" #Name "'", class_name); \ + goto fail; \ + } + +#define PARSE_BINARY(Name, Dest) \ + IF_FIELD(Name) { \ + if (!parse_bindata(BSON_SUBTYPE_BINARY, &iter, Dest, status)) { \ + goto fail; \ + } \ + } \ + END_IF_FIELD + +typedef struct { + _mongocrypt_buffer_t *edcDerivedToken; + _mongocrypt_buffer_t *escDerivedToken; + _mongocrypt_buffer_t *serverDerivedToken; +} mc_TextFindTokenSetIndirection_t; + +typedef struct { + const _mongocrypt_buffer_t *edcDerivedToken; + const _mongocrypt_buffer_t *escDerivedToken; + const _mongocrypt_buffer_t *serverDerivedToken; +} mc_TextFindTokenSetIndirectionConst_t; + +/* Cleanup code common to all mc_TextFindTokenSet_t types. + */ +static void mc_TextFindTokenSetIndirection_cleanup(mc_TextFindTokenSetIndirection_t ts) { + _mongocrypt_buffer_cleanup(ts.edcDerivedToken); + _mongocrypt_buffer_cleanup(ts.escDerivedToken); + _mongocrypt_buffer_cleanup(ts.serverDerivedToken); +} + +/* Serialization code common to all mc_TextFindTokenSet_t types. + */ +static bool mc_TextFindTokenSetIndirection_serialize(mc_TextFindTokenSetIndirectionConst_t ts, + bson_t *parent, + const char *field_name) { + BSON_ASSERT_PARAM(ts.edcDerivedToken); + BSON_ASSERT_PARAM(ts.escDerivedToken); + BSON_ASSERT_PARAM(ts.serverDerivedToken); + BSON_ASSERT_PARAM(parent); + BSON_ASSERT_PARAM(field_name); + bson_t child; + if (!BSON_APPEND_DOCUMENT_BEGIN(parent, field_name, &child)) { + return false; + } + if (!_mongocrypt_buffer_append(ts.edcDerivedToken, &child, "d", -1)) { + return false; + } + if (!_mongocrypt_buffer_append(ts.escDerivedToken, &child, "s", -1)) { + return false; + } + if (!_mongocrypt_buffer_append(ts.serverDerivedToken, &child, "l", -1)) { + return false; + } + if (!bson_append_document_end(parent, &child)) { + return false; + } + return true; +} + +/* Parsing code common to all mc_TextFindTokenSet_t types. + */ +static bool mc_TextFindTokenSetIndirection_parse(mc_TextFindTokenSetIndirection_t out, + const char *class_name, + const bson_iter_t *in, + mongocrypt_status_t *status) { + BSON_ASSERT_PARAM(out.edcDerivedToken); + BSON_ASSERT_PARAM(out.escDerivedToken); + BSON_ASSERT_PARAM(out.serverDerivedToken); + BSON_ASSERT_PARAM(in); + bson_iter_t iter; + bool has_d = false, has_s = false, has_l = false; + + iter = *in; + if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { + CLIENT_ERR("Error parsing %s: field expected to be a document, but got %s", + class_name, + mc_bson_type_to_string(bson_iter_type(&iter))); + return false; + } + bson_iter_recurse(&iter, &iter); + while (bson_iter_next(&iter)) { + const char *field = bson_iter_key(&iter); + BSON_ASSERT(field); + + PARSE_BINARY(d, out.edcDerivedToken); + PARSE_BINARY(s, out.escDerivedToken); + PARSE_BINARY(l, out.serverDerivedToken); + + CLIENT_ERR("Error parsing %s: Unrecognized field '%s'", class_name, field); + goto fail; + } + + CHECK_HAS(d); + CHECK_HAS(s); + CHECK_HAS(l); + + return true; +fail: + return false; +} + +#define INDIRECT(type, ts) \ + (type) { \ + .edcDerivedToken = &(ts).edcDerivedToken, .escDerivedToken = &(ts).escDerivedToken, \ + .serverDerivedToken = &(ts).serverDerivedFromDataToken \ + } +#define INDIRECT_TOKENSET(ts) INDIRECT(mc_TextFindTokenSetIndirection_t, ts) +#define INDIRECT_TOKENSET_CONST(ts) INDIRECT(mc_TextFindTokenSetIndirectionConst_t, ts) + +#define DEF_TEXT_SEARCH_FIND_TOKEN_SET_CLEANUP(Type) \ + static void mc_Text##Type##FindTokenSet_cleanup(mc_Text##Type##FindTokenSet_t *fts) { \ + if (fts) { \ + mc_TextFindTokenSetIndirection_cleanup(INDIRECT_TOKENSET(*fts)); \ + } \ + } +DEF_TEXT_SEARCH_FIND_TOKEN_SET_CLEANUP(Exact); +DEF_TEXT_SEARCH_FIND_TOKEN_SET_CLEANUP(Substring); +DEF_TEXT_SEARCH_FIND_TOKEN_SET_CLEANUP(Suffix); +DEF_TEXT_SEARCH_FIND_TOKEN_SET_CLEANUP(Prefix); + +#define DEF_TEXT_SEARCH_FIND_TOKEN_SET_SERIALIZE(Type) \ + static bool mc_Text##Type##FindTokenSet_serialize(bson_t *parent, \ + const char *field_name, \ + const mc_Text##Type##FindTokenSet_t *ts) { \ + BSON_ASSERT_PARAM(ts); \ + return mc_TextFindTokenSetIndirection_serialize(INDIRECT_TOKENSET_CONST(*ts), parent, field_name); \ + } +DEF_TEXT_SEARCH_FIND_TOKEN_SET_SERIALIZE(Exact) +DEF_TEXT_SEARCH_FIND_TOKEN_SET_SERIALIZE(Substring) +DEF_TEXT_SEARCH_FIND_TOKEN_SET_SERIALIZE(Suffix) +DEF_TEXT_SEARCH_FIND_TOKEN_SET_SERIALIZE(Prefix) + +#define DEF_TEXT_SEARCH_FIND_TOKEN_SET_PARSE(Type) \ + static bool mc_Text##Type##FindTokenSet_parse(mc_Text##Type##FindTokenSet_t *out, \ + bson_iter_t *in, \ + mongocrypt_status_t *status) { \ + BSON_ASSERT_PARAM(out); \ + return mc_TextFindTokenSetIndirection_parse(INDIRECT_TOKENSET(*out), "Text" #Type "FindTokenSet", in, status); \ + } +DEF_TEXT_SEARCH_FIND_TOKEN_SET_PARSE(Exact) +DEF_TEXT_SEARCH_FIND_TOKEN_SET_PARSE(Substring) +DEF_TEXT_SEARCH_FIND_TOKEN_SET_PARSE(Suffix) +DEF_TEXT_SEARCH_FIND_TOKEN_SET_PARSE(Prefix) + +#undef DEF_TEXT_SEARCH_FIND_TOKEN_SET_CLEANUP +#undef DEF_TEXT_SEARCH_FIND_TOKEN_SET_SERIALIZE +#undef DEF_TEXT_SEARCH_FIND_TOKEN_SET_PARSE +#undef INDIRECT_TOKENSET_CONST +#undef INDIRECT_TOKENSET +#undef INDIRECT + +void mc_FLE2FindTextPayload_init(mc_FLE2FindTextPayload_t *payload) { + BSON_ASSERT_PARAM(payload); + memset(payload, 0, sizeof(*payload)); +} + +void mc_FLE2FindTextPayload_cleanup(mc_FLE2FindTextPayload_t *payload) { + if (!payload) { + return; + } + mc_TextExactFindTokenSet_cleanup(&payload->tokenSets.exact.value); + mc_TextSubstringFindTokenSet_cleanup(&payload->tokenSets.substring.value); + mc_TextSuffixFindTokenSet_cleanup(&payload->tokenSets.suffix.value); + mc_TextPrefixFindTokenSet_cleanup(&payload->tokenSets.prefix.value); +} + +static bool mc_TextSearchFindTokenSets_parse(mc_TextSearchFindTokenSets_t *out, + const bson_iter_t *in, + mongocrypt_status_t *status) { + BSON_ASSERT_PARAM(out); + BSON_ASSERT_PARAM(in); + + bson_iter_t iter; + bool has_e = false, has_s = false, has_u = false, has_p = false; + uint8_t field_count = 0; + const char *class_name = "TextSearchFindTokenSets"; + + iter = *in; + if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { + CLIENT_ERR("Error parsing %s: field expected to be a document, but got %s", + class_name, + mc_bson_type_to_string(bson_iter_type(&iter))); + return false; + } + bson_iter_recurse(&iter, &iter); + while (bson_iter_next(&iter)) { + const char *field = bson_iter_key(&iter); + BSON_ASSERT(field); + + IF_FIELD(e) { + if (!mc_TextExactFindTokenSet_parse(&out->exact.value, &iter, status)) { + goto fail; + } + out->exact.set = true; + field_count++; + } + END_IF_FIELD + + IF_FIELD(s) { + if (!mc_TextSubstringFindTokenSet_parse(&out->substring.value, &iter, status)) { + goto fail; + } + out->substring.set = true; + field_count++; + } + END_IF_FIELD + + IF_FIELD(u) { + if (!mc_TextSuffixFindTokenSet_parse(&out->suffix.value, &iter, status)) { + goto fail; + } + out->suffix.set = true; + field_count++; + } + END_IF_FIELD + + IF_FIELD(p) { + if (!mc_TextPrefixFindTokenSet_parse(&out->prefix.value, &iter, status)) { + goto fail; + } + out->prefix.set = true; + field_count++; + } + END_IF_FIELD + + CLIENT_ERR("Error parsing %s: Unrecognized field '%s'", class_name, field); + goto fail; + } + + if (!field_count) { + CLIENT_ERR("Error parsing %s: exactly one optional field is required", class_name); + goto fail; + } else if (field_count > 1) { + CLIENT_ERR("Error parsing %s: cannot have multiple optional fields present", class_name); + goto fail; + } + + return true; +fail: + return false; +} + +bool mc_FLE2FindTextPayload_parse(mc_FLE2FindTextPayload_t *out, const bson_t *in, mongocrypt_status_t *status) { + bson_iter_t iter; + const char *class_name = "FLE2FindTextPayload"; + + bool has_ts = false, has_cm = false, has_cf = false, has_df = false; // required fields + bool has_ss = false, has_fs = false, has_ps = false; // optional fields + + BSON_ASSERT_PARAM(out); + BSON_ASSERT_PARAM(in); + + mc_FLE2FindTextPayload_init(out); + if (!bson_validate(in, BSON_VALIDATE_NONE, NULL) || !bson_iter_init(&iter, in)) { + CLIENT_ERR("invalid BSON"); + return false; + } + + while (bson_iter_next(&iter)) { + const char *field = bson_iter_key(&iter); + const char *typestr = mc_bson_type_to_string(bson_iter_type(&iter)); + BSON_ASSERT(field); + + IF_FIELD(ts) { + if (!mc_TextSearchFindTokenSets_parse(&out->tokenSets, &iter, status)) { + return false; + } + } + END_IF_FIELD + + IF_FIELD(cm) { + if (!BSON_ITER_HOLDS_INT64(&iter)) { + CLIENT_ERR("Error parsing %s: Field 'cm' expected to be int64, but got %s", class_name, typestr); + goto fail; + } + out->maxContentionFactor = bson_iter_int64(&iter); + } + END_IF_FIELD + + IF_FIELD(cf) { + if (!BSON_ITER_HOLDS_BOOL(&iter)) { + CLIENT_ERR("Error parsing %s: Field 'cf' expected to be boolean, but got %s", class_name, typestr); + goto fail; + } + out->caseFold = bson_iter_bool(&iter); + } + END_IF_FIELD + + IF_FIELD(df) { + if (!BSON_ITER_HOLDS_BOOL(&iter)) { + CLIENT_ERR("Error parsing %s: Field 'df' expected to be boolean, but got %s", class_name, typestr); + goto fail; + } + out->diacriticFold = bson_iter_bool(&iter); + } + END_IF_FIELD + + IF_FIELD(ss) { + if (!mc_FLE2SubstringInsertSpec_parse(&out->substringSpec.value, &iter, status)) { + goto fail; + } + out->substringSpec.set = true; + } + END_IF_FIELD + + IF_FIELD(fs) { + if (!mc_FLE2SuffixInsertSpec_parse(&out->suffixSpec.value, &iter, status)) { + goto fail; + } + out->suffixSpec.set = true; + } + END_IF_FIELD + + IF_FIELD(ps) { + if (!mc_FLE2PrefixInsertSpec_parse(&out->prefixSpec.value, &iter, status)) { + goto fail; + } + out->prefixSpec.set = true; + } + END_IF_FIELD + + CLIENT_ERR("Error parsing %s: Unrecognized field '%s'", class_name, field); + goto fail; + } + + CHECK_HAS(ts); + CHECK_HAS(cm); + CHECK_HAS(cf); + CHECK_HAS(df); + return true; +fail: + return false; +} + +bool mc_FLE2FindTextPayload_serialize(const mc_FLE2FindTextPayload_t *payload, bson_t *out) { + BSON_ASSERT_PARAM(out); + BSON_ASSERT_PARAM(payload); + + // Append token sets "ts" + { + bson_t child; + if (!BSON_APPEND_DOCUMENT_BEGIN(out, "ts", &child)) { + return false; + } + // Append "e" if present + if (payload->tokenSets.exact.set) { + mc_TextExactFindTokenSet_serialize(&child, "e", &payload->tokenSets.exact.value); + } + // Append "s" if present + if (payload->tokenSets.substring.set) { + mc_TextSubstringFindTokenSet_serialize(&child, "s", &payload->tokenSets.substring.value); + } + // Append "u" if present + if (payload->tokenSets.suffix.set) { + mc_TextSuffixFindTokenSet_serialize(&child, "u", &payload->tokenSets.suffix.value); + } + // Append "p" if present + if (payload->tokenSets.prefix.set) { + mc_TextPrefixFindTokenSet_serialize(&child, "p", &payload->tokenSets.prefix.value); + } + if (!bson_append_document_end(out, &child)) { + return false; + } + } + + // Append "cm". + if (!BSON_APPEND_INT64(out, "cm", payload->maxContentionFactor)) { + return false; + } + + // Append "cf". + if (!BSON_APPEND_BOOL(out, "cf", payload->caseFold)) { + return false; + } + + // Append "df". + if (!BSON_APPEND_BOOL(out, "df", payload->diacriticFold)) { + return false; + } + + // Append "ss" if present. + if (payload->substringSpec.set) { + bson_t child; + if (!BSON_APPEND_DOCUMENT_BEGIN(out, "ss", &child)) { + return false; + } + if (!BSON_APPEND_INT32(&child, "mlen", (int32_t)payload->substringSpec.value.mlen)) { + return false; + } + if (!BSON_APPEND_INT32(&child, "ub", (int32_t)payload->substringSpec.value.ub)) { + return false; + } + if (!BSON_APPEND_INT32(&child, "lb", (int32_t)payload->substringSpec.value.lb)) { + return false; + } + if (!bson_append_document_end(out, &child)) { + return false; + } + } + + // Append "fs" if present. + if (payload->suffixSpec.set) { + bson_t child; + if (!BSON_APPEND_DOCUMENT_BEGIN(out, "fs", &child)) { + return false; + } + if (!BSON_APPEND_INT32(&child, "ub", (int32_t)payload->suffixSpec.value.ub)) { + return false; + } + if (!BSON_APPEND_INT32(&child, "lb", (int32_t)payload->suffixSpec.value.lb)) { + return false; + } + if (!bson_append_document_end(out, &child)) { + return false; + } + } + + // Append "ps" if present. + if (payload->prefixSpec.set) { + bson_t child; + if (!BSON_APPEND_DOCUMENT_BEGIN(out, "ps", &child)) { + return false; + } + if (!BSON_APPEND_INT32(&child, "ub", (int32_t)payload->prefixSpec.value.ub)) { + return false; + } + if (!BSON_APPEND_INT32(&child, "lb", (int32_t)payload->prefixSpec.value.lb)) { + return false; + } + if (!bson_append_document_end(out, &child)) { + return false; + } + } + + return true; +} diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private-v2.h b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private-v2.h index fe1c747..2f317b9 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private-v2.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private-v2.h @@ -158,9 +158,7 @@ const _mongocrypt_buffer_t *mc_FLE2InsertUpdatePayloadV2_decrypt(_mongocrypt_cry bool mc_FLE2InsertUpdatePayloadV2_serialize(const mc_FLE2InsertUpdatePayloadV2_t *payload, bson_t *out); -bool mc_FLE2InsertUpdatePayloadV2_serializeForRange(const mc_FLE2InsertUpdatePayloadV2_t *payload, - bson_t *out, - bool use_range_v2); +bool mc_FLE2InsertUpdatePayloadV2_serializeForRange(const mc_FLE2InsertUpdatePayloadV2_t *payload, bson_t *out); bool mc_FLE2InsertUpdatePayloadV2_serializeForTextSearch(const mc_FLE2InsertUpdatePayloadV2_t *payload, bson_t *out); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-v2.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-v2.c index e6f72b5..09a3204 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-v2.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-v2.c @@ -17,6 +17,7 @@ #include #include "mc-fle2-insert-update-payload-private-v2.h" +#include "mc-parse-utils-private.h" #include "mongocrypt-buffer-private.h" #include "mongocrypt-util-private.h" // mc_bson_type_to_string #include "mongocrypt.h" @@ -133,21 +134,7 @@ void mc_FLE2InsertUpdatePayloadV2_cleanup(mc_FLE2InsertUpdatePayloadV2_t *payloa #define PARSE_BINDATA(Name, Type, Dest) \ IF_FIELD(Name) { \ - bson_subtype_t subtype; \ - uint32_t len; \ - const uint8_t *data; \ - if (bson_iter_type(&iter) != BSON_TYPE_BINARY) { \ - CLIENT_ERR("Field '" #Name "' expected to be bindata, got: %d", bson_iter_type(&iter)); \ - goto fail; \ - } \ - bson_iter_binary(&iter, &subtype, &len, &data); \ - if (subtype != Type) { \ - CLIENT_ERR("Field '" #Name "' expected to be bindata subtype %d, got: %d", Type, subtype); \ - goto fail; \ - } \ - if (!_mongocrypt_buffer_copy_from_binary_iter(&out->Dest, &iter)) { \ - CLIENT_ERR("Unable to create mongocrypt buffer for BSON binary " \ - "field in '" #Name "'"); \ + if (!parse_bindata(Type, &iter, &out->Dest, status)) { \ goto fail; \ } \ } \ @@ -159,7 +146,8 @@ void mc_FLE2InsertUpdatePayloadV2_cleanup(mc_FLE2InsertUpdatePayloadV2_t *payloa if (!has_##Name) { \ CLIENT_ERR("Missing field '" #Name "' in payload"); \ goto fail; \ - } + } else \ + ((void)0) bool mc_FLE2InsertUpdatePayloadV2_parse(mc_FLE2InsertUpdatePayloadV2_t *out, const _mongocrypt_buffer_t *in, @@ -306,7 +294,8 @@ bool mc_FLE2InsertUpdatePayloadV2_parse(mc_FLE2InsertUpdatePayloadV2_t *out, #define IUPS_APPEND_BINDATA(dst, name, subtype, value) \ if (!_mongocrypt_buffer_append(&(value), dst, name, -1)) { \ return false; \ - } + } else \ + ((void)0) bool mc_FLE2InsertUpdatePayloadV2_serialize(const mc_FLE2InsertUpdatePayloadV2_t *payload, bson_t *out) { BSON_ASSERT_PARAM(out); @@ -329,9 +318,7 @@ bool mc_FLE2InsertUpdatePayloadV2_serialize(const mc_FLE2InsertUpdatePayloadV2_t return true; } -bool mc_FLE2InsertUpdatePayloadV2_serializeForRange(const mc_FLE2InsertUpdatePayloadV2_t *payload, - bson_t *out, - bool use_range_v2) { +bool mc_FLE2InsertUpdatePayloadV2_serializeForRange(const mc_FLE2InsertUpdatePayloadV2_t *payload, bson_t *out) { BSON_ASSERT_PARAM(out); BSON_ASSERT_PARAM(payload); @@ -375,34 +362,32 @@ bool mc_FLE2InsertUpdatePayloadV2_serializeForRange(const mc_FLE2InsertUpdatePay return false; } - if (use_range_v2) { - // Encode parameters that were used to generate the payload. - BSON_ASSERT(payload->sparsity.set); - if (!BSON_APPEND_INT64(out, "sp", payload->sparsity.value)) { - return false; - } - - // Precision may be unset. - if (payload->precision.set) { - if (!BSON_APPEND_INT32(out, "pn", payload->precision.value)) { - return false; - } - } + // Encode parameters that were used to generate the payload. + BSON_ASSERT(payload->sparsity.set); + if (!BSON_APPEND_INT64(out, "sp", payload->sparsity.value)) { + return false; + } - BSON_ASSERT(payload->trimFactor.set); - if (!BSON_APPEND_INT32(out, "tf", payload->trimFactor.value)) { + // Precision may be unset. + if (payload->precision.set) { + if (!BSON_APPEND_INT32(out, "pn", payload->precision.value)) { return false; } + } - BSON_ASSERT(payload->indexMin.value_type != BSON_TYPE_EOD); - if (!BSON_APPEND_VALUE(out, "mn", &payload->indexMin)) { - return false; - } + BSON_ASSERT(payload->trimFactor.set); + if (!BSON_APPEND_INT32(out, "tf", payload->trimFactor.value)) { + return false; + } - BSON_ASSERT(payload->indexMax.value_type != BSON_TYPE_EOD); - if (!BSON_APPEND_VALUE(out, "mx", &payload->indexMax)) { - return false; - } + BSON_ASSERT(payload->indexMin.value_type != BSON_TYPE_EOD); + if (!BSON_APPEND_VALUE(out, "mn", &payload->indexMin)) { + return false; + } + + BSON_ASSERT(payload->indexMax.value_type != BSON_TYPE_EOD); + if (!BSON_APPEND_VALUE(out, "mx", &payload->indexMax)) { + return false; } return true; diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload.c index e36b83c..d191d8b 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload.c @@ -17,6 +17,7 @@ #include #include "mc-fle2-insert-update-payload-private.h" +#include "mc-parse-utils-private.h" #include "mongocrypt-buffer-private.h" #include "mongocrypt.h" @@ -69,21 +70,7 @@ void mc_FLE2InsertUpdatePayload_cleanup(mc_FLE2InsertUpdatePayload_t *payload) { #define PARSE_BINDATA(Name, Type, Dest) \ IF_FIELD(Name) { \ - bson_subtype_t subtype; \ - uint32_t len; \ - const uint8_t *data; \ - if (bson_iter_type(&iter) != BSON_TYPE_BINARY) { \ - CLIENT_ERR("Field '" #Name "' expected to be bindata, got: %d", bson_iter_type(&iter)); \ - goto fail; \ - } \ - bson_iter_binary(&iter, &subtype, &len, &data); \ - if (subtype != Type) { \ - CLIENT_ERR("Field '" #Name "' expected to be bindata subtype %d, got: %d", Type, subtype); \ - goto fail; \ - } \ - if (!_mongocrypt_buffer_copy_from_binary_iter(&out->Dest, &iter)) { \ - CLIENT_ERR("Unable to create mongocrypt buffer for BSON binary " \ - "field in '" #Name "'"); \ + if (!parse_bindata(Type, &iter, &out->Dest, status)) { \ goto fail; \ } \ } \ @@ -95,7 +82,8 @@ void mc_FLE2InsertUpdatePayload_cleanup(mc_FLE2InsertUpdatePayload_t *payload) { if (!has_##Name) { \ CLIENT_ERR("Missing field '" #Name "' in payload"); \ goto fail; \ - } + } else \ + ((void)0) bool mc_FLE2InsertUpdatePayload_parse(mc_FLE2InsertUpdatePayload_t *out, const _mongocrypt_buffer_t *in, @@ -173,7 +161,8 @@ bool mc_FLE2InsertUpdatePayload_parse(mc_FLE2InsertUpdatePayload_t *out, #define IUPS_APPEND_BINDATA(dst, name, subtype, value) \ if (!_mongocrypt_buffer_append(&(value), dst, name, -1)) { \ return false; \ - } + } else \ + ((void)0) bool mc_FLE2InsertUpdatePayload_serialize(const mc_FLE2InsertUpdatePayload_t *payload, bson_t *out) { BSON_ASSERT_PARAM(out); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-v2.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-v2.c index 4a9ec9b..f613afd 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-v2.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-v2.c @@ -17,6 +17,7 @@ #include "mongocrypt-buffer-private.h" #include "mongocrypt-private.h" +#include "mc-dec128.h" #include "mc-fle-blob-subtype-private.h" #include "mc-fle2-payload-iev-private-v2.h" #include "mc-fle2-tag-and-encrypted-metadata-block-private.h" @@ -27,12 +28,12 @@ #include #define kMinServerEncryptedValueLen 17U // IV(16) + EncryptCTR(1byte) -#define kMinSEVAndMetadataLen (kMinServerEncryptedValueLen + kMetadataLen) #define CHECK_AND_RETURN(x) \ if (!(x)) { \ return false; \ - } + } else \ + ((void)0) mc_FLE2IndexedEncryptedValueV2_t *mc_FLE2IndexedEncryptedValueV2_new(void) { return bson_malloc0(sizeof(mc_FLE2IndexedEncryptedValueV2_t)); @@ -539,7 +540,7 @@ bool mc_FLE2IndexedEncryptedValueV2_parse(mc_FLE2IndexedEncryptedValueV2_t *iev, } mc_reader_t reader; - mc_reader_init_from_buffer(&reader, buf, __FUNCTION__); + mc_reader_init_from_buffer(&reader, buf, __func__); CHECK_AND_RETURN(mc_reader_read_u8(&reader, &iev->fle_blob_subtype, status)); @@ -655,7 +656,7 @@ bool mc_FLE2IndexedEncryptedValueV2_serialize(const mc_FLE2IndexedEncryptedValue uint32_t expected_len = mc_FLE2IndexedEncryptedValueV2_serialized_length(iev); mc_writer_t writer; _mongocrypt_buffer_resize(buf, expected_len); - mc_writer_init_from_buffer(&writer, buf, __FUNCTION__); + mc_writer_init_from_buffer(&writer, buf, __func__); // Serialize fle_blob_subtype CHECK_AND_RETURN(mc_writer_write_u8(&writer, iev->fle_blob_subtype, status)); @@ -721,7 +722,7 @@ static bool is_fle2_range_indexed_supported_type(int bson_type) { case BSON_TYPE_INT64: case BSON_TYPE_DATE_TIME: case BSON_TYPE_DOUBLE: -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() case BSON_TYPE_DECIMAL128: #endif return true; diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev.c index 0d2654d..dbe96a2 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev.c @@ -27,7 +27,8 @@ #define CHECK_AND_RETURN(x) \ if (!(x)) { \ return false; \ - } + } else \ + ((void)0) struct _mc_FLE2IndexedEqualityEncryptedValue_t { _mongocrypt_buffer_t S_KeyId; @@ -58,7 +59,7 @@ bool mc_FLE2IndexedEqualityEncryptedValueTokens_init_from_buffer(mc_FLE2IndexedE BSON_ASSERT_PARAM(buf); mc_reader_t reader; - mc_reader_init_from_buffer(&reader, buf, __FUNCTION__); + mc_reader_init_from_buffer(&reader, buf, __func__); CHECK_AND_RETURN(mc_reader_read_u64(&reader, &tokens->counter, status)); @@ -78,7 +79,7 @@ static bool mc_fle2IndexedEncryptedValue_encrypt(_mongocrypt_crypto_t *crypto, _mongocrypt_buffer_t *out, mongocrypt_status_t *status); -bool safe_uint32_t_sum(const uint32_t a, const uint32_t b, uint32_t *out, mongocrypt_status_t *status) { +static bool safe_uint32_t_sum(const uint32_t a, const uint32_t b, uint32_t *out, mongocrypt_status_t *status) { if (a > UINT32_MAX - b) { CLIENT_ERR("safe_uint32_t_sum overflow, %" PRIu32 ", %" PRIu32, a, b); return false; @@ -98,7 +99,8 @@ bool mc_FLE2IndexedEncryptedValue_write(_mongocrypt_crypto_t *crypto, #define CHECK_AND_GOTO(x) \ if (!(x)) { \ goto cleanup; \ - } + } else \ + ((void)0) bool ok = false; @@ -130,12 +132,12 @@ bool mc_FLE2IndexedEncryptedValue_write(_mongocrypt_crypto_t *crypto, &encryption_out, status)); mc_writer_t writer; - mc_writer_init_from_buffer(&writer, buf, __FUNCTION__); + mc_writer_init_from_buffer(&writer, buf, __func__); const uint8_t subtype = (uint8_t)MC_SUBTYPE_FLE2IndexedEqualityEncryptedValue; if (((int)original_bson_type < 0) || ((int)original_bson_type > 0xFF)) { - CLIENT_ERR("Field 't' must be a valid BSON type, got: %d", original_bson_type); + CLIENT_ERR("Field 't' must be a valid BSON type, got: %d", (int)original_bson_type); CHECK_AND_GOTO(false); } @@ -164,7 +166,8 @@ static bool mc_fle2IndexedEncryptedValue_encrypt(_mongocrypt_crypto_t *crypto, #define CHECK_AND_GOTO(x) \ if (!(x)) { \ goto cleanup; \ - } + } else \ + ((void)0) const _mongocrypt_value_encryption_algorithm_t *fle2alg = _mcFLE2Algorithm(); bool ok = false; @@ -191,7 +194,7 @@ static bool mc_fle2IndexedEncryptedValue_encrypt(_mongocrypt_crypto_t *crypto, _mongocrypt_buffer_resize(out, ciphertext_len); mc_writer_t writer; - mc_writer_init_from_buffer(&writer, &in, __FUNCTION__); + mc_writer_init_from_buffer(&writer, &in, __func__); uint64_t length; length = ClientEncryptedValue->len; @@ -236,7 +239,7 @@ bool mc_FLE2IndexedEncryptedValue_parse(mc_FLE2IndexedEncryptedValue_t *iev, } mc_reader_t reader; - mc_reader_init_from_buffer(&reader, buf, __FUNCTION__); + mc_reader_init_from_buffer(&reader, buf, __func__); CHECK_AND_RETURN(mc_reader_read_u8(&reader, &iev->fle_blob_subtype, status)); @@ -364,7 +367,7 @@ static bool mc_FLE2IndexedEncryptedValue_decrypt(_mongocrypt_crypto_t *crypto, } mc_reader_t reader; - mc_reader_init_from_buffer(&reader, &iev->Inner, __FUNCTION__); + mc_reader_init_from_buffer(&reader, &iev->Inner, __func__); /* Parse Inner for K_KeyId. */ uint64_t length; /* length is sizeof(K_KeyId) + ClientEncryptedValue_length. */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-common.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-common.c index 4e9992a..9506685 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-common.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-uev-common.c @@ -21,7 +21,8 @@ #define CHECK_AND_RETURN(x) \ if (!(x)) { \ return false; \ - } + } else \ + ((void)0) bool _mc_FLE2UnindexedEncryptedValueCommon_parse(const _mongocrypt_buffer_t *buf, uint8_t *fle_blob_subtype, @@ -36,7 +37,7 @@ bool _mc_FLE2UnindexedEncryptedValueCommon_parse(const _mongocrypt_buffer_t *buf BSON_ASSERT_PARAM(ciphertext); mc_reader_t reader; - mc_reader_init_from_buffer(&reader, buf, __FUNCTION__); + mc_reader_init_from_buffer(&reader, buf, __func__); /* Read fle_blob_subtype. */ CHECK_AND_RETURN(mc_reader_read_u8(&reader, fle_blob_subtype, status)); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-rfds.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-rfds.c index 0622bfd..14fb07d 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-rfds.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-rfds.c @@ -302,10 +302,7 @@ bool mc_FLE2RangeFindDriverSpec_parse(mc_FLE2RangeFindDriverSpec_t *spec, spec->upper.included = op.op_type == FLE2RangeOperator_kLte; break; case FLE2RangeOperator_kNone: - default: - ERR_WITH_BSON(in, "unsupported operator type %s", op.op_type_str); - goto fail; - break; + default: ERR_WITH_BSON(in, "unsupported operator type %s", op.op_type_str); goto fail; } if (spec->field && 0 != strcmp(spec->field, op.field)) { @@ -352,7 +349,8 @@ bool mc_makeRangeFindPlaceholder(mc_makeRangeFindPlaceholder_args_t *args, if (!(stmt)) { \ CLIENT_ERR("error appending BSON for placeholder"); \ goto fail; \ - } + } else \ + ((void)0) // create edgesInfo. @@ -431,7 +429,8 @@ bool mc_FLE2RangeFindDriverSpec_to_placeholders(mc_FLE2RangeFindDriverSpec_t *sp if (!(stmt)) { \ CLIENT_ERR("error transforming BSON for FLE2RangeFindDriverSpec: %s", #stmt); \ goto fail; \ - } + } else \ + ((void)0) TRY(bson_iter_init_find(&posInf, &infDoc, "p")); TRY(bson_iter_init_find(&negInf, &infDoc, "n")); @@ -579,6 +578,8 @@ static void payloadId_init_mutex(void) { _mongocrypt_mutex_init(&payloadId_mutex); } +void mc_reset_payloadId_for_testing(void); // -Wmissing-prototypes: for testing only. + void mc_reset_payloadId_for_testing(void) { mlib_call_once(&payloadId_init_flag, payloadId_init_mutex); MONGOCRYPT_WITH_MUTEX(payloadId_mutex) { diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-tag-and-encrypted-metadata-block.c b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-tag-and-encrypted-metadata-block.c index 4a625b1..10021b0 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-fle2-tag-and-encrypted-metadata-block.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-fle2-tag-and-encrypted-metadata-block.c @@ -22,7 +22,8 @@ #define CHECK_AND_RETURN(x) \ if (!(x)) { \ return false; \ - } + } else \ + ((void)0) void mc_FLE2TagAndEncryptedMetadataBlock_init(mc_FLE2TagAndEncryptedMetadataBlock_t *metadata) { BSON_ASSERT_PARAM(metadata); @@ -49,7 +50,7 @@ bool mc_FLE2TagAndEncryptedMetadataBlock_parse(mc_FLE2TagAndEncryptedMetadataBlo } mc_reader_t reader; - mc_reader_init_from_buffer(&reader, buf, __FUNCTION__); + mc_reader_init_from_buffer(&reader, buf, __func__); mc_FLE2TagAndEncryptedMetadataBlock_init(metadata); @@ -70,7 +71,7 @@ bool mc_FLE2TagAndEncryptedMetadataBlock_serialize(const mc_FLE2TagAndEncryptedM _mongocrypt_buffer_resize(buf, kMetadataLen); mc_writer_t writer; - mc_writer_init_from_buffer(&writer, buf, __FUNCTION__); + mc_writer_init_from_buffer(&writer, buf, __func__); CHECK_AND_RETURN(mc_writer_write_buffer(&writer, &metadata->encryptedCount, kFieldLen, status)); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-optional-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-optional-private.h index 42a92eb..5d7f411 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-optional-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-optional-private.h @@ -89,7 +89,7 @@ typedef struct { #define OPT_DOUBLE_C(val) \ { .set = true, .value = val } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() typedef struct { bool set; mc_dec128 value; diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-parse-utils-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-parse-utils-private.h new file mode 100644 index 0000000..4118e82 --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/src/mc-parse-utils-private.h @@ -0,0 +1,27 @@ +/* + * 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_PARSE_UTILS_PRIVATE_H +#define MC_PARSE_UTILS_PRIVATE_H + +#include "mongocrypt-buffer-private.h" + +/* Validates that the given bson_iter_t points to bindata element, with + * the given subtype. If so, it copies the binary data to @out and returns true. + * If validation fails, then it returns false and sets an error in @status.*/ +bool parse_bindata(bson_subtype_t subtype, bson_iter_t *iter, _mongocrypt_buffer_t *out, mongocrypt_status_t *status); + +#endif /* MC_PARSE_UTILS_PRIVATE_H */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-parse-utils.c b/ext/libmongocrypt/libmongocrypt/src/mc-parse-utils.c new file mode 100644 index 0000000..ada5971 --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/src/mc-parse-utils.c @@ -0,0 +1,48 @@ +/* + * 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-parse-utils-private.h" +#include "mongocrypt-private.h" +#include "mongocrypt-util-private.h" + +bool parse_bindata(bson_subtype_t subtype, bson_iter_t *iter, _mongocrypt_buffer_t *out, mongocrypt_status_t *status) { + BSON_ASSERT_PARAM(iter); + BSON_ASSERT_PARAM(out); + + bson_subtype_t parsed_subtype; + uint32_t len; + const uint8_t *data; + const char *field_name = bson_iter_key(iter); + if (bson_iter_type(iter) != BSON_TYPE_BINARY) { + CLIENT_ERR("Field '%s' expected to be bindata, got: %s", + field_name, + mc_bson_type_to_string(bson_iter_type(iter))); + return false; + } + bson_iter_binary(iter, &parsed_subtype, &len, &data); + if (parsed_subtype != subtype) { + CLIENT_ERR("Field '%s' expected to be bindata subtype %d, got: %d", + field_name, + (int)subtype, + (int)parsed_subtype); + return false; + } + if (!_mongocrypt_buffer_copy_from_binary_iter(out, iter)) { + CLIENT_ERR("Unable to create mongocrypt buffer for BSON binary field in '%s'", field_name); + return false; + } + return true; +} diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation-private.h index 268eef3..303b7ff 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation-private.h @@ -53,7 +53,7 @@ typedef struct { // mc_getEdgesInt32 implements the Edge Generation algorithm described in // SERVER-67751 for int32_t. -mc_edges_t *mc_getEdgesInt32(mc_getEdgesInt32_args_t args, mongocrypt_status_t *status, bool use_range_v2); +mc_edges_t *mc_getEdgesInt32(mc_getEdgesInt32_args_t args, mongocrypt_status_t *status); typedef struct { int64_t value; @@ -65,7 +65,7 @@ typedef struct { // mc_getEdgesInt64 implements the Edge Generation algorithm described in // SERVER-67751 for int64_t. -mc_edges_t *mc_getEdgesInt64(mc_getEdgesInt64_args_t args, mongocrypt_status_t *status, bool use_range_v2); +mc_edges_t *mc_getEdgesInt64(mc_getEdgesInt64_args_t args, mongocrypt_status_t *status); typedef struct { double value; @@ -78,9 +78,9 @@ typedef struct { // mc_getEdgesDouble implements the Edge Generation algorithm described in // SERVER-67751 for double. -mc_edges_t *mc_getEdgesDouble(mc_getEdgesDouble_args_t args, mongocrypt_status_t *status, bool use_range_v2); +mc_edges_t *mc_getEdgesDouble(mc_getEdgesDouble_args_t args, mongocrypt_status_t *status); -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() typedef struct { mc_dec128 value; size_t sparsity; @@ -89,7 +89,7 @@ typedef struct { mc_optional_int32_t trimFactor; } mc_getEdgesDecimal128_args_t; -mc_edges_t *mc_getEdgesDecimal128(mc_getEdgesDecimal128_args_t args, mongocrypt_status_t *status, bool use_range_v2); +mc_edges_t *mc_getEdgesDecimal128(mc_getEdgesDecimal128_args_t args, mongocrypt_status_t *status); #endif // MONGOCRYPT_HAVE_DECIMAL128_SUPPORT BSON_STATIC_ASSERT2(ull_is_u64, sizeof(uint64_t) == sizeof(unsigned long long)); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation.c b/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation.c index 83b1900..41bc800 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation.c @@ -35,11 +35,8 @@ int32_t mc_edges_get_used_trimFactor(const mc_edges_t *edges) { return edges->usedTrimFactor; } -static mc_edges_t *mc_edges_new(const char *leaf, - size_t sparsity, - mc_optional_int32_t opt_trimFactor, - mongocrypt_status_t *status, - bool use_range_v2) { +static mc_edges_t * +mc_edges_new(const char *leaf, size_t sparsity, mc_optional_int32_t opt_trimFactor, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(leaf); if (sparsity < 1) { CLIENT_ERR("sparsity must be 1 or larger"); @@ -47,11 +44,11 @@ static mc_edges_t *mc_edges_new(const char *leaf, } const size_t leaf_len = strlen(leaf); - const int32_t trimFactor = trimFactorDefault(leaf_len, opt_trimFactor, use_range_v2); + const int32_t trimFactor = trimFactorDefault(leaf_len, opt_trimFactor); if (trimFactor != 0 && mc_cmp_greater_equal_su(trimFactor, leaf_len)) { // We append a total of leaf_len + 1 (for the root) - trimFactor edges. When this number is equal to 1, we // degenerate into equality, which is not desired, so trimFactor must be less than leaf_len. - CLIENT_ERR("trimFactor must be less than the number of bits (%ld) used to represent an element of the domain, " + CLIENT_ERR("trimFactor must be less than the number of bits (%zu) used to represent an element of the domain, " "but got %" PRId32, leaf_len, trimFactor); @@ -163,7 +160,7 @@ mc_bitstring mc_convert_to_bitstring_u128(mlib_int128 i) { return ret; } -mc_edges_t *mc_getEdgesInt32(mc_getEdgesInt32_args_t args, mongocrypt_status_t *status, bool use_range_v2) { +mc_edges_t *mc_getEdgesInt32(mc_getEdgesInt32_args_t args, mongocrypt_status_t *status) { mc_OSTType_Int32 got; if (!mc_getTypeInfo32((mc_getTypeInfo32_args_t){.value = args.value, .min = args.min, .max = args.max}, &got, @@ -179,11 +176,11 @@ mc_edges_t *mc_getEdgesInt32(mc_getEdgesInt32_args_t args, mongocrypt_status_t * mc_bitstring valueBin = mc_convert_to_bitstring_u32(got.value); size_t offset = mc_count_leading_zeros_u32(got.max); const char *leaf = valueBin.str + offset; - mc_edges_t *ret = mc_edges_new(leaf, args.sparsity, args.trimFactor, status, use_range_v2); + mc_edges_t *ret = mc_edges_new(leaf, args.sparsity, args.trimFactor, status); return ret; } -mc_edges_t *mc_getEdgesInt64(mc_getEdgesInt64_args_t args, mongocrypt_status_t *status, bool use_range_v2) { +mc_edges_t *mc_getEdgesInt64(mc_getEdgesInt64_args_t args, mongocrypt_status_t *status) { mc_OSTType_Int64 got; if (!mc_getTypeInfo64((mc_getTypeInfo64_args_t){.value = args.value, .min = args.min, .max = args.max}, &got, @@ -199,19 +196,18 @@ mc_edges_t *mc_getEdgesInt64(mc_getEdgesInt64_args_t args, mongocrypt_status_t * mc_bitstring valueBin = mc_convert_to_bitstring_u64(got.value); size_t offset = mc_count_leading_zeros_u64(got.max); const char *leaf = valueBin.str + offset; - mc_edges_t *ret = mc_edges_new(leaf, args.sparsity, args.trimFactor, status, use_range_v2); + mc_edges_t *ret = mc_edges_new(leaf, args.sparsity, args.trimFactor, status); return ret; } -mc_edges_t *mc_getEdgesDouble(mc_getEdgesDouble_args_t args, mongocrypt_status_t *status, bool use_range_v2) { +mc_edges_t *mc_getEdgesDouble(mc_getEdgesDouble_args_t args, mongocrypt_status_t *status) { mc_OSTType_Double got; if (!mc_getTypeInfoDouble((mc_getTypeInfoDouble_args_t){.value = args.value, .min = args.min, .max = args.max, .precision = args.precision}, &got, - status, - use_range_v2)) { + status)) { return NULL; } @@ -223,12 +219,12 @@ mc_edges_t *mc_getEdgesDouble(mc_getEdgesDouble_args_t args, mongocrypt_status_t mc_bitstring valueBin = mc_convert_to_bitstring_u64(got.value); size_t offset = mc_count_leading_zeros_u64(got.max); const char *leaf = valueBin.str + offset; - mc_edges_t *ret = mc_edges_new(leaf, args.sparsity, args.trimFactor, status, use_range_v2); + mc_edges_t *ret = mc_edges_new(leaf, args.sparsity, args.trimFactor, status); return ret; } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT -mc_edges_t *mc_getEdgesDecimal128(mc_getEdgesDecimal128_args_t args, mongocrypt_status_t *status, bool use_range_v2) { +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() +mc_edges_t *mc_getEdgesDecimal128(mc_getEdgesDecimal128_args_t args, mongocrypt_status_t *status) { mc_OSTType_Decimal128 got; if (!mc_getTypeInfoDecimal128( (mc_getTypeInfoDecimal128_args_t){ @@ -238,8 +234,7 @@ mc_edges_t *mc_getEdgesDecimal128(mc_getEdgesDecimal128_args_t args, mongocrypt_ .precision = args.precision, }, &got, - status, - use_range_v2)) { + status)) { return NULL; } @@ -248,7 +243,7 @@ mc_edges_t *mc_getEdgesDecimal128(mc_getEdgesDecimal128_args_t args, mongocrypt_ mc_bitstring bits = mc_convert_to_bitstring_u128(got.value); size_t offset = mc_count_leading_zeros_u128(got.max); const char *leaf = bits.str + offset; - mc_edges_t *ret = mc_edges_new(leaf, args.sparsity, args.trimFactor, status, use_range_v2); + mc_edges_t *ret = mc_edges_new(leaf, args.sparsity, args.trimFactor, status); return ret; } #endif // MONGOCRYPT_HAVE_DECIMAL128_SUPPORT diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding-private.h index 2250b1f..8c2832c 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding-private.h @@ -97,10 +97,9 @@ bool mc_canUsePrecisionModeDouble(double min, * `out`. Returns false and sets `status` on error. */ bool mc_getTypeInfoDouble(mc_getTypeInfoDouble_args_t args, mc_OSTType_Double *out, - mongocrypt_status_t *status, - bool use_range_v2) MONGOCRYPT_WARN_UNUSED_RESULT; + mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() /** * @brief OST-encoding of a Decimal128 */ @@ -131,11 +130,10 @@ bool mc_canUsePrecisionModeDecimal(mc_dec128 min, */ bool mc_getTypeInfoDecimal128(mc_getTypeInfoDecimal128_args_t args, mc_OSTType_Decimal128 *out, - mongocrypt_status_t *status, - bool use_range_v2) MONGOCRYPT_WARN_UNUSED_RESULT; + mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; #endif // MONGOCRYPT_HAVE_DECIMAL128_SUPPORT extern const int64_t mc_FLERangeSparsityDefault; -int32_t trimFactorDefault(size_t maxlen, mc_optional_int32_t trimFactor, bool use_range_v2); +int32_t trimFactorDefault(size_t maxlen, mc_optional_int32_t trimFactor); #endif /* MC_RANGE_ENCODING_PRIVATE_H */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding.c b/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding.c index e7d423b..049a63a 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding.c @@ -165,7 +165,7 @@ bool mc_getTypeInfo64(mc_getTypeInfo64_args_t args, mc_OSTType_Int64 *out, mongo #define exp10Double(x) pow(10, x) #define SCALED_DOUBLE_BOUNDS 9007199254740992.0 // 2^53 -uint64_t subtract_int64_t(int64_t max, int64_t min) { +static uint64_t subtract_int64_t(int64_t max, int64_t min) { BSON_ASSERT(max > min); // If the values have the same sign, then simple subtraction // will work because we know max > min. @@ -180,7 +180,7 @@ uint64_t subtract_int64_t(int64_t max, int64_t min) { return u_return; } -bool ceil_log2_double(uint64_t i, uint32_t *maxBitsOut, mongocrypt_status_t *status) { +static bool ceil_log2_double(uint64_t i, uint32_t *maxBitsOut, mongocrypt_status_t *status) { if (i == 0) { CLIENT_ERR("Invalid input to ceil_log2_double function. Input cannot be 0."); return false; @@ -284,10 +284,7 @@ bool mc_canUsePrecisionModeDouble(double min, return true; } -bool mc_getTypeInfoDouble(mc_getTypeInfoDouble_args_t args, - mc_OSTType_Double *out, - mongocrypt_status_t *status, - bool use_range_v2) { +bool mc_getTypeInfoDouble(mc_getTypeInfoDouble_args_t args, mc_OSTType_Double *out, mongocrypt_status_t *status) { if (args.min.set != args.max.set || args.min.set != args.precision.set) { CLIENT_ERR("min, max, and precision must all be set or must all be unset"); return false; @@ -350,7 +347,7 @@ bool mc_getTypeInfoDouble(mc_getTypeInfoDouble_args_t args, use_precision_mode = mc_canUsePrecisionModeDouble(args.min.value, args.max.value, args.precision.value, &bits_range, status); - if (!use_precision_mode && use_range_v2) { + if (!use_precision_mode) { if (!mongocrypt_status_ok(status)) { return false; } @@ -421,7 +418,7 @@ bool mc_getTypeInfoDouble(mc_getTypeInfoDouble_args_t args, return true; } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() /** * @brief There is no shipped algorithm for creating a full 128-bit integer from * a Decimal128, but it's easy enough to write one of our own. @@ -604,8 +601,7 @@ bool mc_canUsePrecisionModeDecimal(mc_dec128 min, bool mc_getTypeInfoDecimal128(mc_getTypeInfoDecimal128_args_t args, mc_OSTType_Decimal128 *out, - mongocrypt_status_t *status, - bool use_range_v2) { + mongocrypt_status_t *status) { /// Basic param checks if (args.min.set != args.max.set || args.min.set != args.precision.set) { CLIENT_ERR("min, max, and precision must all be set or must all be unset"); @@ -673,7 +669,7 @@ bool mc_getTypeInfoDecimal128(mc_getTypeInfoDecimal128_args_t args, use_precision_mode = mc_canUsePrecisionModeDecimal(args.min.value, args.max.value, args.precision.value, &bits_range, status); - if (use_range_v2 && !use_precision_mode) { + if (!use_precision_mode) { if (!mongocrypt_status_ok(status)) { return false; } @@ -852,18 +848,13 @@ bool mc_getTypeInfoDecimal128(mc_getTypeInfoDecimal128_args_t args, #endif // defined MONGOCRYPT_HAVE_DECIMAL128_SUPPORT const int64_t mc_FLERangeSparsityDefault = 2; -const int32_t mc_FLERangeTrimFactorDefault = 6; +static const int32_t mc_FLERangeTrimFactorDefault = 6; -int32_t trimFactorDefault(size_t maxlen, mc_optional_int32_t trimFactor, bool use_range_v2) { +int32_t trimFactorDefault(size_t maxlen, mc_optional_int32_t trimFactor) { if (trimFactor.set) { return trimFactor.value; } - if (!use_range_v2) { - // Preserve old default. - return 0; - } - if (mc_cmp_greater_su(mc_FLERangeTrimFactorDefault, maxlen - 1)) { return (int32_t)(maxlen - 1); } else { diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-generator.template.h b/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-generator.template.h index 9da1bff..e7770b0 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-generator.template.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-generator.template.h @@ -100,8 +100,7 @@ static inline DECORATE_NAME(MinCoverGenerator) UINT_T max, size_t sparsity, mc_optional_int32_t opt_trimFactor, - mongocrypt_status_t *status, - bool use_range_v2) { + mongocrypt_status_t *status) { BSON_ASSERT_PARAM(status); if (UINT_COMPARE(rangeMin, rangeMax) > 0) { @@ -123,9 +122,9 @@ static inline DECORATE_NAME(MinCoverGenerator) return NULL; } size_t maxlen = (size_t)BITS - DECORATE_NAME(mc_count_leading_zeros)(max); - int32_t trimFactor = trimFactorDefault(maxlen, opt_trimFactor, use_range_v2); + int32_t trimFactor = trimFactorDefault(maxlen, opt_trimFactor); if (trimFactor != 0 && mc_cmp_greater_equal_su(trimFactor, maxlen)) { - CLIENT_ERR("Trim factor must be less than the number of bits (%ld) used to represent an element of the domain, " + CLIENT_ERR("Trim factor must be less than the number of bits (%zu) used to represent an element of the domain, " "but got %" PRId32, maxlen, trimFactor); @@ -174,7 +173,7 @@ static inline bool DECORATE_NAME(MinCoverGenerator_isLevelStored)(DECORATE_NAME( return 0 == maskedBits || (level >= trimFactor_sz && 0 == (level % mcg->_sparsity)); } -char * +static char * DECORATE_NAME(MinCoverGenerator_toString)(DECORATE_NAME(MinCoverGenerator) * mcg, UINT_T start, size_t maskedBits) { BSON_ASSERT_PARAM(mcg); BSON_ASSERT(maskedBits <= mcg->_maxlen); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-private.h index 2129dff..0a77adb 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-private.h @@ -53,8 +53,7 @@ typedef struct { // mc_getMincoverInt32 implements the Mincover Generation algorithm described in // SERVER-68600 for int32_t. mc_mincover_t *mc_getMincoverInt32(mc_getMincoverInt32_args_t args, - mongocrypt_status_t *status, - bool use_range_v2) MONGOCRYPT_WARN_UNUSED_RESULT; + mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; typedef struct { int64_t lowerBound; @@ -70,8 +69,7 @@ typedef struct { // mc_getMincoverInt64 implements the Mincover Generation algorithm described in // SERVER-68600 for int64_t. mc_mincover_t *mc_getMincoverInt64(mc_getMincoverInt64_args_t args, - mongocrypt_status_t *status, - bool use_range_v2) MONGOCRYPT_WARN_UNUSED_RESULT; + mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; typedef struct { double lowerBound; @@ -88,10 +86,9 @@ typedef struct { // mc_getMincoverDouble implements the Mincover Generation algorithm described // in SERVER-68600 for double. mc_mincover_t *mc_getMincoverDouble(mc_getMincoverDouble_args_t args, - mongocrypt_status_t *status, - bool use_range_v2) MONGOCRYPT_WARN_UNUSED_RESULT; + mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() typedef struct { mc_dec128 lowerBound; bool includeLowerBound; @@ -106,8 +103,7 @@ typedef struct { // mc_getMincoverDecimal128 implements the Mincover Generation algorithm // described in SERVER-68600 for Decimal128 (as mc_dec128). mc_mincover_t *mc_getMincoverDecimal128(mc_getMincoverDecimal128_args_t args, - mongocrypt_status_t *status, - bool use_range_v2) MONGOCRYPT_WARN_UNUSED_RESULT; + mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; #endif // MONGOCRYPT_HAVE_DECIMAL128_SUPPORT #endif /* MC_RANGE_MINCOVER_PRIVATE_H */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover.c b/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover.c index 3e8d8d4..febe1bd 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover.c @@ -80,7 +80,7 @@ void mc_mincover_destroy(mc_mincover_t *mincover) { // The 128-bit version is only required for Decimal128, otherwise generates // unused-fn warnings -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() #define UINT_T mlib_int128 #define UINT_C MLIB_INT128 #define UINT_FMT_S "s" @@ -133,7 +133,7 @@ void mc_mincover_destroy(mc_mincover_t *mincover) { } else \ (void)0 -mc_mincover_t *mc_getMincoverInt32(mc_getMincoverInt32_args_t args, mongocrypt_status_t *status, bool use_range_v2) { +mc_mincover_t *mc_getMincoverInt32(mc_getMincoverInt32_args_t args, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(status); CHECK_BOUNDS(args, PRId32, IDENTITY, LESSTHAN); mc_OSTType_Int32 a, b; @@ -156,7 +156,7 @@ mc_mincover_t *mc_getMincoverInt32(mc_getMincoverInt32_args_t args, mongocrypt_s } MinCoverGenerator_u32 *mcg = - MinCoverGenerator_new_u32(a.value, b.value, a.max, args.sparsity, args.trimFactor, status, use_range_v2); + MinCoverGenerator_new_u32(a.value, b.value, a.max, args.sparsity, args.trimFactor, status); if (!mcg) { return NULL; } @@ -166,7 +166,7 @@ mc_mincover_t *mc_getMincoverInt32(mc_getMincoverInt32_args_t args, mongocrypt_s return mc; } -mc_mincover_t *mc_getMincoverInt64(mc_getMincoverInt64_args_t args, mongocrypt_status_t *status, bool use_range_v2) { +mc_mincover_t *mc_getMincoverInt64(mc_getMincoverInt64_args_t args, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(status); CHECK_BOUNDS(args, PRId64, IDENTITY, LESSTHAN); mc_OSTType_Int64 a, b; @@ -189,7 +189,7 @@ mc_mincover_t *mc_getMincoverInt64(mc_getMincoverInt64_args_t args, mongocrypt_s } MinCoverGenerator_u64 *mcg = - MinCoverGenerator_new_u64(a.value, b.value, a.max, args.sparsity, args.trimFactor, status, use_range_v2); + MinCoverGenerator_new_u64(a.value, b.value, a.max, args.sparsity, args.trimFactor, status); if (!mcg) { return NULL; } @@ -201,7 +201,7 @@ mc_mincover_t *mc_getMincoverInt64(mc_getMincoverInt64_args_t args, mongocrypt_s // mc_getMincoverDouble implements the Mincover Generation algorithm described // in SERVER-68600 for double. -mc_mincover_t *mc_getMincoverDouble(mc_getMincoverDouble_args_t args, mongocrypt_status_t *status, bool use_range_v2) { +mc_mincover_t *mc_getMincoverDouble(mc_getMincoverDouble_args_t args, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(status); CHECK_BOUNDS(args, "g", IDENTITY, LESSTHAN); @@ -211,8 +211,7 @@ mc_mincover_t *mc_getMincoverDouble(mc_getMincoverDouble_args_t args, mongocrypt .max = args.max, .precision = args.precision}, &a, - status, - use_range_v2)) { + status)) { return NULL; } if (!mc_getTypeInfoDouble((mc_getTypeInfoDouble_args_t){.value = args.upperBound, @@ -220,8 +219,7 @@ mc_mincover_t *mc_getMincoverDouble(mc_getMincoverDouble_args_t args, mongocrypt .max = args.max, .precision = args.precision}, &b, - status, - use_range_v2)) { + status)) { return NULL; } @@ -233,7 +231,7 @@ mc_mincover_t *mc_getMincoverDouble(mc_getMincoverDouble_args_t args, mongocrypt } MinCoverGenerator_u64 *mcg = - MinCoverGenerator_new_u64(a.value, b.value, a.max, args.sparsity, args.trimFactor, status, use_range_v2); + MinCoverGenerator_new_u64(a.value, b.value, a.max, args.sparsity, args.trimFactor, status); if (!mcg) { return NULL; } @@ -243,9 +241,8 @@ mc_mincover_t *mc_getMincoverDouble(mc_getMincoverDouble_args_t args, mongocrypt return mc; } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT -mc_mincover_t * -mc_getMincoverDecimal128(mc_getMincoverDecimal128_args_t args, mongocrypt_status_t *status, bool use_range_v2) { +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() +mc_mincover_t *mc_getMincoverDecimal128(mc_getMincoverDecimal128_args_t args, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(status); #define ToString(Dec) (mc_dec128_to_string(Dec).str) CHECK_BOUNDS(args, "s", ToString, mc_dec128_less); @@ -256,8 +253,7 @@ mc_getMincoverDecimal128(mc_getMincoverDecimal128_args_t args, mongocrypt_status .max = args.max, .precision = args.precision}, &a, - status, - use_range_v2)) { + status)) { return NULL; } if (!mc_getTypeInfoDecimal128((mc_getTypeInfoDecimal128_args_t){.value = args.upperBound, @@ -265,8 +261,7 @@ mc_getMincoverDecimal128(mc_getMincoverDecimal128_args_t args, mongocrypt_status .max = args.max, .precision = args.precision}, &b, - status, - use_range_v2)) { + status)) { return NULL; } @@ -278,7 +273,7 @@ mc_getMincoverDecimal128(mc_getMincoverDecimal128_args_t args, mongocrypt_status } MinCoverGenerator_u128 *mcg = - MinCoverGenerator_new_u128(a.value, b.value, a.max, args.sparsity, args.trimFactor, status, use_range_v2); + MinCoverGenerator_new_u128(a.value, b.value, a.max, args.sparsity, args.trimFactor, status); if (!mcg) { return NULL; } diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts-private.h index 80f4c80..13ba550 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts-private.h @@ -55,7 +55,7 @@ BSON_STATIC_ASSERT2(alignof_mc_RangeOpts_t, * "trimFactor": Optional, * } */ -bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, mongocrypt_status_t *status); +bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, mongocrypt_status_t *status); /* * mc_RangeOpts_to_FLE2RangeInsertSpec creates a placeholder value to be @@ -76,7 +76,6 @@ bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, bool mc_RangeOpts_to_FLE2RangeInsertSpec(const mc_RangeOpts_t *ro, const bson_t *v, bson_t *out, - bool use_range_v2, mongocrypt_status_t *status); /* mc_RangeOpts_appendMin appends the minimum value of the range for a given @@ -104,8 +103,7 @@ bool mc_RangeOpts_appendTrimFactor(const mc_RangeOpts_t *ro, bson_type_t valueType, const char *fieldName, bson_t *out, - mongocrypt_status_t *status, - bool use_range_v2); + mongocrypt_status_t *status); void mc_RangeOpts_cleanup(mc_RangeOpts_t *ro); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts.c b/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts.c index 729ef49..40b76ff 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts.c @@ -25,31 +25,24 @@ #include // DBL_MAX -#define CLIENT_ERR_PREFIXED_HELPER(Prefix, ErrorString, ...) CLIENT_ERR(Prefix ": " ErrorString, ##__VA_ARGS__) -#define CLIENT_ERR_PREFIXED(ErrorString, ...) CLIENT_ERR_PREFIXED_HELPER(ERROR_PREFIX, ErrorString, ##__VA_ARGS__) - // Common logic for testing field name, tracking duplication, and presence. #define IF_FIELD(Name) \ if (0 == strcmp(field, #Name)) { \ if (has_##Name) { \ - CLIENT_ERR_PREFIXED("Unexpected duplicate field '" #Name "'"); \ + CLIENT_ERR(ERROR_PREFIX "Unexpected duplicate field '" #Name "'"); \ return false; \ } \ - has_##Name = true; + has_##Name = true; \ + ((void)0) #define END_IF_FIELD \ continue; \ - } - -#define CHECK_HAS(Name) \ - if (!has_##Name) { \ - CLIENT_ERR_PREFIXED("Missing field '" #Name "'"); \ - return false; \ - } + } \ + else((void)0) -#define ERROR_PREFIX "Error parsing RangeOpts" +#define ERROR_PREFIX "Error parsing RangeOpts: " -bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, mongocrypt_status_t *status) { +bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, mongocrypt_status_t *status) { bson_iter_t iter = {0}; bool has_min = false, has_max = false, has_sparsity = false, has_precision = false, has_trimFactor = false; BSON_ASSERT_PARAM(ro); @@ -60,7 +53,7 @@ bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, ro->bson = bson_copy(in); if (!bson_iter_init(&iter, ro->bson)) { - CLIENT_ERR_PREFIXED("Invalid BSON"); + CLIENT_ERR(ERROR_PREFIX "Invalid BSON"); return false; } @@ -68,54 +61,63 @@ bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, const char *field = bson_iter_key(&iter); BSON_ASSERT(field); - IF_FIELD(min) - ro->min.set = true; - ro->min.value = iter; - END_IF_FIELD + IF_FIELD(min); + { + ro->min.set = true; + ro->min.value = iter; + } + END_IF_FIELD; - IF_FIELD(max) - ro->max.set = true; - ro->max.value = iter; - END_IF_FIELD + IF_FIELD(max); + { + ro->max.set = true; + ro->max.value = iter; + } + END_IF_FIELD; - IF_FIELD(sparsity) - if (!BSON_ITER_HOLDS_INT64(&iter)) { - CLIENT_ERR_PREFIXED("Expected int64 for sparsity, got: %s", mc_bson_type_to_string(bson_iter_type(&iter))); - return false; - }; - ro->sparsity = bson_iter_int64(&iter); - END_IF_FIELD + IF_FIELD(sparsity); + { + if (!BSON_ITER_HOLDS_INT64(&iter)) { + CLIENT_ERR(ERROR_PREFIX "Expected int64 for sparsity, got: %s", + mc_bson_type_to_string(bson_iter_type(&iter))); + return false; + } + ro->sparsity = bson_iter_int64(&iter); + } + END_IF_FIELD; - IF_FIELD(precision) { + IF_FIELD(precision); + { if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("'precision' must be an int32"); + CLIENT_ERR(ERROR_PREFIX "'precision' must be an int32"); return false; } int32_t val = bson_iter_int32(&iter); if (val < 0) { - CLIENT_ERR_PREFIXED("'precision' must be non-negative"); + CLIENT_ERR(ERROR_PREFIX "'precision' must be non-negative"); return false; } ro->precision = OPT_I32(val); } - END_IF_FIELD + END_IF_FIELD; - IF_FIELD(trimFactor) { + IF_FIELD(trimFactor); + { if (!BSON_ITER_HOLDS_INT32(&iter)) { - CLIENT_ERR_PREFIXED("Expected int32 for trimFactor, got: %s", - mc_bson_type_to_string(bson_iter_type(&iter))); + CLIENT_ERR(ERROR_PREFIX "Expected int32 for trimFactor, got: %s", + mc_bson_type_to_string(bson_iter_type(&iter))); return false; - }; + } int32_t val = bson_iter_int32(&iter); if (val < 0) { - CLIENT_ERR_PREFIXED("'trimFactor' must be non-negative"); + CLIENT_ERR(ERROR_PREFIX "'trimFactor' must be non-negative"); return false; } ro->trimFactor = OPT_I32(val); } - END_IF_FIELD + END_IF_FIELD; - CLIENT_ERR_PREFIXED("Unrecognized field: '%s'", field); + CLIENT_ERR(ERROR_PREFIX "Unrecognized field: '%s'", field); return false; } @@ -124,35 +126,35 @@ bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, // applies to double/decimal128. // Do not error if trimFactor is not present. It is optional. - if (!has_sparsity && use_range_v2) { + if (!has_sparsity) { ro->sparsity = mc_FLERangeSparsityDefault; } // Expect precision only to be set for double or decimal128. if (has_precision) { if (!ro->min.set) { - CLIENT_ERR_PREFIXED("setting precision requires min"); + CLIENT_ERR(ERROR_PREFIX "setting precision requires min"); return false; } bson_type_t minType = bson_iter_type(&ro->min.value); if (minType != BSON_TYPE_DOUBLE && minType != BSON_TYPE_DECIMAL128) { - CLIENT_ERR_PREFIXED("expected 'precision' to be set with double or decimal128 " - "index, but got: %s min", - mc_bson_type_to_string(minType)); + CLIENT_ERR(ERROR_PREFIX "expected 'precision' to be set with double or decimal128 " + "index, but got: %s min", + mc_bson_type_to_string(minType)); return false; } if (!ro->max.set) { - CLIENT_ERR_PREFIXED("setting precision requires max"); + CLIENT_ERR(ERROR_PREFIX "setting precision requires max"); return false; } bson_type_t maxType = bson_iter_type(&ro->max.value); if (maxType != BSON_TYPE_DOUBLE && maxType != BSON_TYPE_DECIMAL128) { - CLIENT_ERR_PREFIXED("expected 'precision' to be set with double or decimal128 " - "index, but got: %s max", - mc_bson_type_to_string(maxType)); + CLIENT_ERR(ERROR_PREFIX "expected 'precision' to be set with double or decimal128 " + "index, but got: %s max", + mc_bson_type_to_string(maxType)); return false; } } @@ -161,10 +163,10 @@ bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, if (ro->min.set && ro->max.set) { bson_type_t minType = bson_iter_type(&ro->min.value), maxType = bson_iter_type(&ro->max.value); if (minType != maxType) { - CLIENT_ERR_PREFIXED("expected 'min' and 'max' to be same type, but got: %s " - "min and %s max", - mc_bson_type_to_string(minType), - mc_bson_type_to_string(maxType)); + CLIENT_ERR(ERROR_PREFIX "expected 'min' and 'max' to be same type, but got: %s " + "min and %s max", + mc_bson_type_to_string(minType), + mc_bson_type_to_string(maxType)); return false; } } @@ -175,8 +177,8 @@ bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, bson_type_t minType = bson_iter_type(&ro->min.value); if (minType == BSON_TYPE_DOUBLE || minType == BSON_TYPE_DECIMAL128) { if (!has_precision) { - CLIENT_ERR_PREFIXED("expected 'precision' to be set with 'min' for %s", - mc_bson_type_to_string(minType)); + CLIENT_ERR(ERROR_PREFIX "expected 'precision' to be set with 'min' for %s", + mc_bson_type_to_string(minType)); return false; } } @@ -186,8 +188,8 @@ bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, bson_type_t maxType = bson_iter_type(&ro->max.value); if (maxType == BSON_TYPE_DOUBLE || maxType == BSON_TYPE_DECIMAL128) { if (!has_precision) { - CLIENT_ERR_PREFIXED("expected 'precision' to be set with 'max' for %s", - mc_bson_type_to_string(maxType)); + CLIENT_ERR(ERROR_PREFIX "expected 'precision' to be set with 'max' for %s", + mc_bson_type_to_string(maxType)); return false; } } @@ -195,11 +197,6 @@ bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, } if (ro->trimFactor.set) { - if (!use_range_v2) { - // Once `use_range_v2` is default true, this block may be removed. - CLIENT_ERR_PREFIXED("'trimFactor' is not supported for QE range v1"); - return false; - } // At this point, we do not know the type of the field if min and max are unspecified. Wait to // validate the value of trimFactor. } @@ -208,12 +205,11 @@ bool mc_RangeOpts_parse(mc_RangeOpts_t *ro, const bson_t *in, bool use_range_v2, } #undef ERROR_PREFIX -#define ERROR_PREFIX "Error making FLE2RangeInsertSpec" +#define ERROR_PREFIX "Error making FLE2RangeInsertSpec: " bool mc_RangeOpts_to_FLE2RangeInsertSpec(const mc_RangeOpts_t *ro, const bson_t *v, bson_t *out, - bool use_range_v2, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(ro); BSON_ASSERT_PARAM(v); @@ -222,17 +218,17 @@ bool mc_RangeOpts_to_FLE2RangeInsertSpec(const mc_RangeOpts_t *ro, bson_iter_t v_iter; if (!bson_iter_init_find(&v_iter, v, "v")) { - CLIENT_ERR_PREFIXED("Unable to find 'v' in input"); + 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_PREFIXED("Error appending to BSON"); + CLIENT_ERR(ERROR_PREFIX "Error appending to BSON"); return false; } if (!bson_append_iter(&child, "v", 1, &v_iter)) { - CLIENT_ERR_PREFIXED("Error appending to BSON"); + CLIENT_ERR(ERROR_PREFIX "Error appending to BSON"); return false; } @@ -247,25 +243,23 @@ bool mc_RangeOpts_to_FLE2RangeInsertSpec(const mc_RangeOpts_t *ro, if (ro->precision.set) { BSON_ASSERT(ro->precision.value <= INT32_MAX); if (!BSON_APPEND_INT32(&child, "precision", (int32_t)ro->precision.value)) { - CLIENT_ERR_PREFIXED("Error appending to BSON"); + CLIENT_ERR(ERROR_PREFIX "Error appending to BSON"); return false; } } - if (use_range_v2) { - if (!mc_RangeOpts_appendTrimFactor(ro, bson_iter_type(&v_iter), "trimFactor", &child, status, use_range_v2)) { - return false; - } + if (!mc_RangeOpts_appendTrimFactor(ro, bson_iter_type(&v_iter), "trimFactor", &child, status)) { + return false; } if (!bson_append_document_end(out, &child)) { - CLIENT_ERR_PREFIXED("Error appending to BSON"); + CLIENT_ERR(ERROR_PREFIX "Error appending to BSON"); return false; } return true; } #undef ERROR_PREFIX -#define ERROR_PREFIX "Error appending min to FLE2RangeInsertSpec" +#define ERROR_PREFIX "Error appending min to FLE2RangeInsertSpec: " bool mc_RangeOpts_appendMin(const mc_RangeOpts_t *ro, bson_type_t valueType, @@ -279,48 +273,48 @@ bool mc_RangeOpts_appendMin(const mc_RangeOpts_t *ro, if (ro->min.set) { if (bson_iter_type(&ro->min.value) != valueType) { - CLIENT_ERR_PREFIXED("expected matching 'min' and value type. Got range option " - "'min' of type %s and value of type %s", - mc_bson_type_to_string(bson_iter_type(&ro->min.value)), - mc_bson_type_to_string(valueType)); + CLIENT_ERR(ERROR_PREFIX "expected matching 'min' and value type. Got range option " + "'min' of type %s and value of type %s", + mc_bson_type_to_string(bson_iter_type(&ro->min.value)), + mc_bson_type_to_string(valueType)); return false; } if (!bson_append_iter(out, fieldName, -1, &ro->min.value)) { - CLIENT_ERR_PREFIXED("failed to append BSON"); + CLIENT_ERR(ERROR_PREFIX "failed to append BSON"); return false; } return true; } if (valueType == BSON_TYPE_INT32 || valueType == BSON_TYPE_INT64 || valueType == BSON_TYPE_DATE_TIME) { - CLIENT_ERR_PREFIXED("Range option 'min' is required for type: %s", mc_bson_type_to_string(valueType)); + CLIENT_ERR(ERROR_PREFIX "Range option 'min' is required for type: %s", mc_bson_type_to_string(valueType)); return false; } else if (valueType == BSON_TYPE_DOUBLE) { if (!BSON_APPEND_DOUBLE(out, fieldName, -DBL_MAX)) { - CLIENT_ERR_PREFIXED("failed to append BSON"); + CLIENT_ERR(ERROR_PREFIX "failed to append BSON"); return false; } } else if (valueType == BSON_TYPE_DECIMAL128) { -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() const bson_decimal128_t min = mc_dec128_to_bson_decimal128(MC_DEC128_LARGEST_NEGATIVE); if (!BSON_APPEND_DECIMAL128(out, fieldName, &min)) { - CLIENT_ERR_PREFIXED("failed to append BSON"); + CLIENT_ERR(ERROR_PREFIX "failed to append BSON"); return false; } #else // ↑↑↑↑↑↑↑↑ With Decimal128 / Without ↓↓↓↓↓↓↓↓↓↓ - CLIENT_ERR_PREFIXED("unsupported BSON type (Decimal128) for range: libmongocrypt " - "was built without extended Decimal128 support"); + CLIENT_ERR(ERROR_PREFIX "unsupported BSON type (Decimal128) for range: libmongocrypt " + "was built without extended Decimal128 support"); return false; #endif // MONGOCRYPT_HAVE_DECIMAL128_SUPPORT } else { - CLIENT_ERR_PREFIXED("unsupported BSON type: %s for range", mc_bson_type_to_string(valueType)); + CLIENT_ERR(ERROR_PREFIX "unsupported BSON type: %s for range", mc_bson_type_to_string(valueType)); return false; } return true; } #undef ERROR_PREFIX -#define ERROR_PREFIX "Error appending max to FLE2RangeInsertSpec" +#define ERROR_PREFIX "Error appending max to FLE2RangeInsertSpec: " bool mc_RangeOpts_appendMax(const mc_RangeOpts_t *ro, bson_type_t valueType, @@ -334,56 +328,53 @@ bool mc_RangeOpts_appendMax(const mc_RangeOpts_t *ro, if (ro->max.set) { if (bson_iter_type(&ro->max.value) != valueType) { - CLIENT_ERR_PREFIXED("expected matching 'max' and value type. Got range option " - "'max' of type %s and value of type %s", - mc_bson_type_to_string(bson_iter_type(&ro->max.value)), - mc_bson_type_to_string(valueType)); + CLIENT_ERR(ERROR_PREFIX "expected matching 'max' and value type. Got range option " + "'max' of type %s and value of type %s", + mc_bson_type_to_string(bson_iter_type(&ro->max.value)), + mc_bson_type_to_string(valueType)); return false; } if (!bson_append_iter(out, fieldName, -1, &ro->max.value)) { - CLIENT_ERR_PREFIXED("failed to append BSON"); + CLIENT_ERR(ERROR_PREFIX "failed to append BSON"); return false; } return true; } if (valueType == BSON_TYPE_INT32 || valueType == BSON_TYPE_INT64 || valueType == BSON_TYPE_DATE_TIME) { - CLIENT_ERR_PREFIXED("Range option 'max' is required for type: %s", mc_bson_type_to_string(valueType)); + CLIENT_ERR(ERROR_PREFIX "Range option 'max' is required for type: %s", mc_bson_type_to_string(valueType)); return false; } else if (valueType == BSON_TYPE_DOUBLE) { if (!BSON_APPEND_DOUBLE(out, fieldName, DBL_MAX)) { - CLIENT_ERR_PREFIXED("failed to append BSON"); + CLIENT_ERR(ERROR_PREFIX "failed to append BSON"); return false; } } else if (valueType == BSON_TYPE_DECIMAL128) { -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() const bson_decimal128_t max = mc_dec128_to_bson_decimal128(MC_DEC128_LARGEST_POSITIVE); if (!BSON_APPEND_DECIMAL128(out, fieldName, &max)) { - CLIENT_ERR_PREFIXED("failed to append BSON"); + CLIENT_ERR(ERROR_PREFIX "failed to append BSON"); return false; } #else // ↑↑↑↑↑↑↑↑ With Decimal128 / Without ↓↓↓↓↓↓↓↓↓↓ - CLIENT_ERR_PREFIXED("unsupported BSON type (Decimal128) for range: libmongocrypt " - "was built without extended Decimal128 support"); + CLIENT_ERR(ERROR_PREFIX "unsupported BSON type (Decimal128) for range: libmongocrypt " + "was built without extended Decimal128 support"); return false; #endif // MONGOCRYPT_HAVE_DECIMAL128_SUPPORT } else { - CLIENT_ERR_PREFIXED("unsupported BSON type: %s for range", mc_bson_type_to_string(valueType)); + CLIENT_ERR(ERROR_PREFIX "unsupported BSON type: %s for range", mc_bson_type_to_string(valueType)); return false; } return true; } #undef ERROR_PREFIX -#define ERROR_PREFIX "Error in getNumberOfBits" +#define ERROR_PREFIX "Error in getNumberOfBits: " // Used to calculate max trim factor. Returns the number of bits required to represent any number in // the domain. -bool mc_getNumberOfBits(const mc_RangeOpts_t *ro, - bson_type_t valueType, - uint32_t *bitsOut, - mongocrypt_status_t *status, - bool use_range_v2) { +static bool +mc_getNumberOfBits(const mc_RangeOpts_t *ro, bson_type_t valueType, uint32_t *bitsOut, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(ro); BSON_ASSERT_PARAM(bitsOut); @@ -450,13 +441,13 @@ bool mc_getNumberOfBits(const mc_RangeOpts_t *ro, } mc_getTypeInfoDouble_args_t args = {value, rmin, rmax, prec}; mc_OSTType_Double out; - if (!mc_getTypeInfoDouble(args, &out, status, use_range_v2)) { + if (!mc_getTypeInfoDouble(args, &out, status)) { return false; } *bitsOut = 64 - (uint32_t)mc_count_leading_zeros_u64(out.max); return true; } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() else if (valueType == BSON_TYPE_DECIMAL128) { mc_dec128 value = MC_DEC128_ZERO; mc_optional_dec128_t rmin = {false, MC_DEC128_ZERO}, rmax = {false, MC_DEC128_ZERO}; @@ -469,26 +460,25 @@ bool mc_getNumberOfBits(const mc_RangeOpts_t *ro, } mc_getTypeInfoDecimal128_args_t args = {value, rmin, rmax, prec}; mc_OSTType_Decimal128 out; - if (!mc_getTypeInfoDecimal128(args, &out, status, use_range_v2)) { + if (!mc_getTypeInfoDecimal128(args, &out, status)) { return false; } *bitsOut = 128 - (uint32_t)mc_count_leading_zeros_u128(out.max); return true; } #endif - CLIENT_ERR_PREFIXED("unsupported BSON type: %s for range", mc_bson_type_to_string(valueType)); + CLIENT_ERR(ERROR_PREFIX "unsupported BSON type: %s for range", mc_bson_type_to_string(valueType)); return false; } #undef ERROR_PREFIX -#define ERROR_PREFIX "Error appending trim factor to FLE2RangeInsertSpec" +#define ERROR_PREFIX "Error appending trim factor to FLE2RangeInsertSpec: " bool mc_RangeOpts_appendTrimFactor(const mc_RangeOpts_t *ro, bson_type_t valueType, const char *fieldName, bson_t *out, - mongocrypt_status_t *status, - bool use_range_v2) { + mongocrypt_status_t *status) { BSON_ASSERT_PARAM(ro); BSON_ASSERT_PARAM(fieldName); BSON_ASSERT_PARAM(out); @@ -500,20 +490,20 @@ bool mc_RangeOpts_appendTrimFactor(const mc_RangeOpts_t *ro, } uint32_t nbits; - if (!mc_getNumberOfBits(ro, valueType, &nbits, status, use_range_v2)) { + if (!mc_getNumberOfBits(ro, valueType, &nbits, status)) { return false; } // if nbits = 0, we want to allow trim factor = 0. uint32_t test = nbits ? nbits : 1; if (mc_cmp_greater_equal_su(ro->trimFactor.value, test)) { - CLIENT_ERR_PREFIXED("Trim factor (%d) must be less than the total number of bits (%d) used to represent " - "any element in the domain.", - ro->trimFactor.value, - nbits); + CLIENT_ERR(ERROR_PREFIX "Trim factor (%" PRId32 ") must be less than the total number of bits (%" PRIu32 + ") used to represent any element in the domain.", + ro->trimFactor.value, + nbits); return false; } if (!BSON_APPEND_INT32(out, fieldName, ro->trimFactor.value)) { - CLIENT_ERR_PREFIXED("failed to append BSON"); + CLIENT_ERR(ERROR_PREFIX "failed to append BSON"); return false; } return true; diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-reader-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-reader-private.h index e8df9c4..ab6f0eb 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-reader-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-reader-private.h @@ -25,7 +25,7 @@ * A non-owning forward-only cursor api to read a buffer. * * Tracks length of buffer and current position of buffer. parser_name is - * typically __FUNCTION__ to provide useful error messages automatically. + * typically __func__ to provide useful error messages automatically. * * All numbers are read as little endian. * @@ -37,7 +37,7 @@ * mongocrypt_status_t *status * * mc_reader_t reader; - * mc_reader_init_from_buffer (&reader, buf, __FUNCTION__); + * mc_reader_init_from_buffer (&reader, buf, __func__); * * _mongocrypt_buffer_t in; * if (!mc_reader_read_uuid_buffer (&reader, &in, status)) { diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-reader.c b/ext/libmongocrypt/libmongocrypt/src/mc-reader.c index 65eca69..63c95be 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-reader.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-reader.c @@ -21,7 +21,8 @@ #define CHECK_AND_RETURN(x) \ if (!(x)) { \ return false; \ - } + } else \ + ((void)0) #define CHECK_REMAINING_BUFFER_AND_RET(read_size) \ if ((reader->pos + (read_size)) > reader->len) { \ @@ -31,7 +32,8 @@ reader->pos + (read_size), \ reader->len); \ return false; \ - } + } else \ + ((void)0) void mc_reader_init(mc_reader_t *reader, const uint8_t *ptr, uint64_t len, const char *parser_name) { BSON_ASSERT_PARAM(reader); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker-private.h index 5aa5506..287d29a 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker-private.h @@ -34,9 +34,6 @@ mc_schema_broker_t *mc_schema_broker_new(void); void mc_schema_broker_destroy(mc_schema_broker_t *sb); -// mc_schema_broker_use_rangev2 enables rangev2 behavior. TODO(MONGOCRYPT-711) remove once rangev1 code is removed. -void mc_schema_broker_use_rangev2(mc_schema_broker_t *sb); - // mc_schema_broker_request requests a schema for a collection. Ignores duplicates. // Returns error if two requests have different databases (not-yet supported). bool mc_schema_broker_request(mc_schema_broker_t *sb, const char *db, const char *coll, mongocrypt_status_t *status); diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker.c b/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker.c index 34f06a4..4616922 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker.c @@ -50,18 +50,12 @@ struct mc_schema_broker_t { char *db; // Database shared by all schemas. mc_schema_entry_t *ll; size_t ll_len; - bool use_range_v2; }; mc_schema_broker_t *mc_schema_broker_new(void) { return bson_malloc0(sizeof(mc_schema_broker_t)); } -void mc_schema_broker_use_rangev2(mc_schema_broker_t *sb) { - BSON_ASSERT_PARAM(sb); - sb->use_range_v2 = true; -} - bool mc_schema_broker_request(mc_schema_broker_t *sb, const char *db, const char *coll, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(sb); BSON_ASSERT_PARAM(db); @@ -208,7 +202,6 @@ static inline bool mc_schema_entry_satisfy_from_collinfo(mc_schema_entry_t *se, const bson_t *collinfo, const char *coll, const char *db, - bool use_range_v2, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(se); BSON_ASSERT_PARAM(collinfo); @@ -255,7 +248,7 @@ static inline bool mc_schema_entry_satisfy_from_collinfo(mc_schema_entry_t *se, return false; } - if (!mc_EncryptedFieldConfig_parse(&se->encryptedFields.efc, &se->encryptedFields.bson, status, use_range_v2)) { + if (!mc_EncryptedFieldConfig_parse(&se->encryptedFields.efc, &se->encryptedFields.bson, status)) { return false; } se->encryptedFields.set = true; @@ -351,7 +344,7 @@ bool mc_schema_broker_satisfy_from_collinfo(mc_schema_broker_t *sb, } } - if (!mc_schema_entry_satisfy_from_collinfo(se, collinfo, coll, sb->db, sb->use_range_v2, status)) { + if (!mc_schema_entry_satisfy_from_collinfo(se, collinfo, coll, sb->db, status)) { return false; } @@ -426,10 +419,7 @@ bool mc_schema_broker_satisfy_from_encryptedFieldsMap(mc_schema_broker_t *sb, goto loop_fail; } - if (!mc_EncryptedFieldConfig_parse(&it->encryptedFields.efc, - &it->encryptedFields.bson, - status, - sb->use_range_v2)) { + if (!mc_EncryptedFieldConfig_parse(&it->encryptedFields.efc, &it->encryptedFields.bson, status)) { goto loop_fail; } @@ -473,7 +463,7 @@ bool mc_schema_broker_satisfy_from_cache(mc_schema_broker_t *sb, goto loop_skip; } - if (!mc_schema_entry_satisfy_from_collinfo(it, collinfo, sb->db, it->coll, sb->use_range_v2, status)) { + if (!mc_schema_entry_satisfy_from_collinfo(it, collinfo, sb->db, it->coll, status)) { goto loop_fail; } diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-str-encode-string-sets-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-str-encode-string-sets-private.h index 61f2b31..db88fb8 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-str-encode-string-sets-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-str-encode-string-sets-private.h @@ -92,4 +92,4 @@ void mc_substring_set_iter_init(mc_substring_set_iter_t *it, mc_substring_set_t // true otherwise. bool mc_substring_set_iter_next(mc_substring_set_iter_t *it, const char **str, uint32_t *byte_len, uint32_t *count); -#endif \ No newline at end of file +#endif diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-str-encode-string-sets.c b/ext/libmongocrypt/libmongocrypt/src/mc-str-encode-string-sets.c index 2d6caac..ee0fccc 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-str-encode-string-sets.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-str-encode-string-sets.c @@ -166,8 +166,8 @@ static void mc_substring_set_node_destroy(mc_substring_set_node_t *node) { } // FNV-1a hash function -const uint32_t FNV1APRIME = 16777619; -const uint32_t FNV1ABASIS = 2166136261; +static const uint32_t FNV1APRIME = 16777619; +static const uint32_t FNV1ABASIS = 2166136261; static uint32_t fnv1a(const uint8_t *data, uint32_t len) { BSON_ASSERT_PARAM(data); @@ -301,4 +301,4 @@ bool mc_substring_set_iter_next(mc_substring_set_iter_t *it, const char **str, u } it->cur_node = (void *)cur->next; return true; -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-text-search-str-encode-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-text-search-str-encode-private.h index 7bdfeb3..e2e6d3a 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-text-search-str-encode-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-text-search-str-encode-private.h @@ -42,4 +42,11 @@ mc_str_encode_sets_t *mc_text_search_str_encode(const mc_FLE2TextSearchInsertSpe void mc_str_encode_sets_destroy(mc_str_encode_sets_t *sets); -#endif /* MONGOCRYPT_TEXT_SEARCH_STR_ENCODE_PRIVATE_H */ \ No newline at end of file +// Applies case/diacritic folding to the string value in spec (if applicable), and returns +// the resulting string as a BSON string element in *out. Returns false and an error if the string +// is not valid UTF-8 or is unsuitable per the query parameters in the spec. +bool mc_text_search_str_query(const mc_FLE2TextSearchInsertSpec_t *spec, + _mongocrypt_buffer_t *out, + mongocrypt_status_t *status); + +#endif /* MONGOCRYPT_TEXT_SEARCH_STR_ENCODE_PRIVATE_H */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-text-search-str-encode.c b/ext/libmongocrypt/libmongocrypt/src/mc-text-search-str-encode.c index c6bc829..2d27914 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-text-search-str-encode.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-text-search-str-encode.c @@ -14,9 +14,11 @@ * limitations under the License. */ +#include "mc-fle2-encryption-placeholder-private.h" #include "mc-str-encode-string-sets-private.h" #include "mc-text-search-str-encode-private.h" #include "mongocrypt-buffer-private.h" +#include "mongocrypt-crypto-private.h" #include "mongocrypt.h" #include "unicode/fold.h" #include @@ -181,7 +183,7 @@ mc_str_encode_sets_t *mc_text_search_str_encode(const mc_FLE2TextSearchInsertSpe mongocrypt_status_t *status) { BSON_ASSERT_PARAM(spec); if (spec->len > MAX_ENCODE_BYTE_LEN) { - CLIENT_ERR("StrEncode: String passed in was too long: String was %u bytes, but max is %u bytes", + CLIENT_ERR("StrEncode: String passed in was too long: String was %" PRIu32 " bytes, but max is %d bytes", spec->len, MAX_ENCODE_BYTE_LEN); return NULL; @@ -245,4 +247,78 @@ void mc_str_encode_sets_destroy(mc_str_encode_sets_t *sets) { mc_affix_set_destroy(sets->prefix_set); mc_substring_set_destroy(sets->substring_set); bson_free(sets); -} \ No newline at end of file +} + +bool mc_text_search_str_query(const mc_FLE2TextSearchInsertSpec_t *spec, + _mongocrypt_buffer_t *out, + mongocrypt_status_t *status) { + BSON_ASSERT_PARAM(spec); + BSON_ASSERT_PARAM(out); + + if (spec->len > MAX_ENCODE_BYTE_LEN) { + CLIENT_ERR("StrQuery: String passed in was too long: String was %" PRIu32 " bytes, but max is %d bytes", + spec->len, + MAX_ENCODE_BYTE_LEN); + return false; + } + + _mongocrypt_buffer_init(out); + if (!bson_utf8_validate(spec->v, spec->len, false /* allow_null */)) { + CLIENT_ERR("StrQuery: String passed in was not valid UTF-8"); + return false; + } + + uint32_t folded_codepoint_len = 0; + + if (spec->casef || spec->diacf) { + char *folded_str; + size_t folded_str_bytes_len; + if (!unicode_fold(spec->v, + spec->len, + (spec->casef * kUnicodeFoldToLower) | (spec->diacf * kUnicodeFoldRemoveDiacritics), + &folded_str, + &folded_str_bytes_len, + status)) { + return false; + } + _mongocrypt_buffer_copy_from_string_as_bson_value(out, folded_str, (int)folded_str_bytes_len); + folded_codepoint_len = mc_get_utf8_codepoint_length(folded_str, (uint32_t)folded_str_bytes_len); + bson_free(folded_str); + } else { + _mongocrypt_buffer_copy_from_string_as_bson_value(out, spec->v, (int)spec->len); + folded_codepoint_len = mc_get_utf8_codepoint_length(spec->v, spec->len); + } + + if (spec->substr.set || spec->suffix.set || spec->prefix.set) { + uint32_t min = 0, max = 0; + if (spec->substr.set) { + min = spec->substr.value.lb; + max = spec->substr.value.ub; + } else if (spec->suffix.set) { + min = spec->suffix.value.lb; + max = spec->suffix.value.ub; + } else { + min = spec->prefix.value.lb; + max = spec->prefix.value.ub; + } + if (folded_codepoint_len == 0) { + CLIENT_ERR("StrQuery: string value cannot be empty for substring, suffix, or prefix queries"); + return false; + } + if (folded_codepoint_len > max) { + CLIENT_ERR("StrQuery: string value was longer than the maximum query length " + "for this field after folding -- folded codepoint len: %u, max query len: %u", + folded_codepoint_len, + max); + return false; + } + if (folded_codepoint_len < min) { + CLIENT_ERR("StrQuery: string value was shorter than the minimum query length " + "for this field after folding -- folded codepoint len: %u, min query len: %u", + folded_codepoint_len, + min); + return false; + } + } + return true; +} diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-tokens-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-tokens-private.h index 633cc4c..1c6f711 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-tokens-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-tokens-private.h @@ -197,38 +197,56 @@ DECL_TOKEN_TYPE(mc_ServerTextSuffixToken, DECL_TOKEN_TYPE(mc_ServerTextPrefixToken, const mc_ServerTokenDerivationLevel1Token_t *serverTokenDerivationLevel1Token); -DECL_TOKEN_TYPE(mc_EDCTextExactDerivedFromDataTokenAndContentionFactorToken, +DECL_TOKEN_TYPE(mc_EDCTextExactDerivedFromDataToken, const mc_EDCTextExactToken_t *edcTextExactToken, - const _mongocrypt_buffer_t *v, + const _mongocrypt_buffer_t *v); +DECL_TOKEN_TYPE(mc_EDCTextSubstringDerivedFromDataToken, + const mc_EDCTextSubstringToken_t *edcTextSubstringToken, + const _mongocrypt_buffer_t *v); +DECL_TOKEN_TYPE(mc_EDCTextSuffixDerivedFromDataToken, + const mc_EDCTextSuffixToken_t *edcTextSuffixToken, + const _mongocrypt_buffer_t *v); +DECL_TOKEN_TYPE(mc_EDCTextPrefixDerivedFromDataToken, + const mc_EDCTextPrefixToken_t *edcTextPrefixToken, + const _mongocrypt_buffer_t *v); + +DECL_TOKEN_TYPE(mc_EDCTextExactDerivedFromDataTokenAndContentionFactorToken, + const mc_EDCTextExactDerivedFromDataToken_t *edcTextExactToken, uint64_t u); DECL_TOKEN_TYPE(mc_EDCTextSubstringDerivedFromDataTokenAndContentionFactorToken, - const mc_EDCTextSubstringToken_t *edcTextSubstringToken, - const _mongocrypt_buffer_t *v, + const mc_EDCTextSubstringDerivedFromDataToken_t *edcTextSubstringToken, uint64_t u); DECL_TOKEN_TYPE(mc_EDCTextSuffixDerivedFromDataTokenAndContentionFactorToken, - const mc_EDCTextSuffixToken_t *edcTextSuffixToken, - const _mongocrypt_buffer_t *v, + const mc_EDCTextSuffixDerivedFromDataToken_t *edcTextSuffixToken, uint64_t u); DECL_TOKEN_TYPE(mc_EDCTextPrefixDerivedFromDataTokenAndContentionFactorToken, - const mc_EDCTextPrefixToken_t *edcTextPrefixToken, - const _mongocrypt_buffer_t *v, + const mc_EDCTextPrefixDerivedFromDataToken_t *edcTextPrefixToken, uint64_t u); -DECL_TOKEN_TYPE(mc_ESCTextExactDerivedFromDataTokenAndContentionFactorToken, +DECL_TOKEN_TYPE(mc_ESCTextExactDerivedFromDataToken, const mc_ESCTextExactToken_t *escTextExactToken, - const _mongocrypt_buffer_t *v, + const _mongocrypt_buffer_t *v); +DECL_TOKEN_TYPE(mc_ESCTextSubstringDerivedFromDataToken, + const mc_ESCTextSubstringToken_t *escTextSubstringToken, + const _mongocrypt_buffer_t *v); +DECL_TOKEN_TYPE(mc_ESCTextSuffixDerivedFromDataToken, + const mc_ESCTextSuffixToken_t *escTextSuffixToken, + const _mongocrypt_buffer_t *v); +DECL_TOKEN_TYPE(mc_ESCTextPrefixDerivedFromDataToken, + const mc_ESCTextPrefixToken_t *escTextPrefixToken, + const _mongocrypt_buffer_t *v); + +DECL_TOKEN_TYPE(mc_ESCTextExactDerivedFromDataTokenAndContentionFactorToken, + const mc_ESCTextExactDerivedFromDataToken_t *escTextExactToken, uint64_t u); DECL_TOKEN_TYPE(mc_ESCTextSubstringDerivedFromDataTokenAndContentionFactorToken, - const mc_ESCTextSubstringToken_t *escTextSubstringToken, - const _mongocrypt_buffer_t *v, + const mc_ESCTextSubstringDerivedFromDataToken_t *escTextSubstringToken, uint64_t u); DECL_TOKEN_TYPE(mc_ESCTextSuffixDerivedFromDataTokenAndContentionFactorToken, - const mc_ESCTextSuffixToken_t *escTextSuffixToken, - const _mongocrypt_buffer_t *v, + const mc_ESCTextSuffixDerivedFromDataToken_t *escTextSuffixToken, uint64_t u); DECL_TOKEN_TYPE(mc_ESCTextPrefixDerivedFromDataTokenAndContentionFactorToken, - const mc_ESCTextPrefixToken_t *escTextPrefixToken, - const _mongocrypt_buffer_t *v, + const mc_ESCTextPrefixDerivedFromDataToken_t *escTextPrefixToken, uint64_t u); DECL_TOKEN_TYPE(mc_ServerTextExactDerivedFromDataToken, diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-tokens.c b/ext/libmongocrypt/libmongocrypt/src/mc-tokens.c index 95234b1..c9ea158 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-tokens.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-tokens.c @@ -168,7 +168,7 @@ IMPL_TOKEN_NEW_CONST(mc_ServerZerosEncryptionToken, mc_ServerDerivedFromDataToke // d = 17 bytes of 0, AnchorPaddingTokenRoot = HMAC(ESCToken, d) #define ANCHOR_PADDING_TOKEN_D_LENGTH 17 -const uint8_t mc_AnchorPaddingTokenDValue[ANCHOR_PADDING_TOKEN_D_LENGTH] = +static const uint8_t mc_AnchorPaddingTokenDValue[ANCHOR_PADDING_TOKEN_D_LENGTH] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; DEF_TOKEN_TYPE(mc_AnchorPaddingTokenRoot, const mc_ESCToken_t *ESCToken) { @@ -233,97 +233,89 @@ IMPL_TOKEN_NEW_CONST(mc_ServerTextPrefixToken, mc_ServerTokenDerivationLevel1Token_get(serverTokenDerivationLevel1Token), TEXT_PREFIX_ID) -#define IMPL_TOKEN_NEW_FROM_DATA_AND_CONTENTION(Name, Key, BufferArg, UintArg) \ - { \ - BSON_CONCAT(Name, _t) *t = bson_malloc(sizeof(BSON_CONCAT(Name, _t))); \ - _mongocrypt_buffer_t tmp; \ - _mongocrypt_buffer_init(&tmp); \ - _mongocrypt_buffer_resize(&tmp, MONGOCRYPT_HMAC_SHA256_LEN); \ - _mongocrypt_buffer_init(&t->data); \ - _mongocrypt_buffer_resize(&t->data, MONGOCRYPT_HMAC_SHA256_LEN); \ - if (!_mongocrypt_hmac_sha_256(crypto, Key, BufferArg, &tmp, status)) { \ - BSON_CONCAT(Name, _destroy)(t); \ - _mongocrypt_buffer_cleanup(&tmp); \ - return NULL; \ - } \ - _mongocrypt_buffer_t uint_arg; \ - _mongocrypt_buffer_copy_from_uint64_le(&uint_arg, UintArg); \ - if (!_mongocrypt_hmac_sha_256(crypto, &tmp, &uint_arg, &t->data, status)) { \ - BSON_CONCAT(Name, _destroy)(t); \ - _mongocrypt_buffer_cleanup(&tmp); \ - _mongocrypt_buffer_cleanup(&uint_arg); \ - return NULL; \ - } \ - _mongocrypt_buffer_cleanup(&tmp); \ - _mongocrypt_buffer_cleanup(&uint_arg); \ - return t; \ - } +DEF_TOKEN_TYPE(mc_EDCTextExactDerivedFromDataToken, + const mc_EDCTextExactToken_t *edcTextExactToken, + const _mongocrypt_buffer_t *v) +IMPL_TOKEN_NEW(mc_EDCTextExactDerivedFromDataToken, mc_EDCTextExactToken_get(edcTextExactToken), v) +DEF_TOKEN_TYPE(mc_EDCTextSubstringDerivedFromDataToken, + const mc_EDCTextSubstringToken_t *edcTextSubstringToken, + const _mongocrypt_buffer_t *v) +IMPL_TOKEN_NEW(mc_EDCTextSubstringDerivedFromDataToken, mc_EDCTextSubstringToken_get(edcTextSubstringToken), v) +DEF_TOKEN_TYPE(mc_EDCTextSuffixDerivedFromDataToken, + const mc_EDCTextSuffixToken_t *edcTextSuffixToken, + const _mongocrypt_buffer_t *v) +IMPL_TOKEN_NEW(mc_EDCTextSuffixDerivedFromDataToken, mc_EDCTextSuffixToken_get(edcTextSuffixToken), v) +DEF_TOKEN_TYPE(mc_EDCTextPrefixDerivedFromDataToken, + const mc_EDCTextPrefixToken_t *edcTextPrefixToken, + const _mongocrypt_buffer_t *v) +IMPL_TOKEN_NEW(mc_EDCTextPrefixDerivedFromDataToken, mc_EDCTextPrefixToken_get(edcTextPrefixToken), v) DEF_TOKEN_TYPE(mc_EDCTextExactDerivedFromDataTokenAndContentionFactorToken, - const mc_EDCTextExactToken_t *edcTextExactToken, - const _mongocrypt_buffer_t *v, + const mc_EDCTextExactDerivedFromDataToken_t *edcTextExactToken, uint64_t u) -IMPL_TOKEN_NEW_FROM_DATA_AND_CONTENTION(mc_EDCTextExactDerivedFromDataTokenAndContentionFactorToken, - mc_EDCTextExactToken_get(edcTextExactToken), - v, - u) +IMPL_TOKEN_NEW_CONST(mc_EDCTextExactDerivedFromDataTokenAndContentionFactorToken, + mc_EDCTextExactDerivedFromDataToken_get(edcTextExactToken), + u) DEF_TOKEN_TYPE(mc_EDCTextSubstringDerivedFromDataTokenAndContentionFactorToken, - const mc_EDCTextSubstringToken_t *edcTextSubstringToken, - const _mongocrypt_buffer_t *v, + const mc_EDCTextSubstringDerivedFromDataToken_t *edcTextSubstringToken, uint64_t u) -IMPL_TOKEN_NEW_FROM_DATA_AND_CONTENTION(mc_EDCTextSubstringDerivedFromDataTokenAndContentionFactorToken, - mc_EDCTextSubstringToken_get(edcTextSubstringToken), - v, - u) +IMPL_TOKEN_NEW_CONST(mc_EDCTextSubstringDerivedFromDataTokenAndContentionFactorToken, + mc_EDCTextSubstringDerivedFromDataToken_get(edcTextSubstringToken), + u) DEF_TOKEN_TYPE(mc_EDCTextSuffixDerivedFromDataTokenAndContentionFactorToken, - const mc_EDCTextSuffixToken_t *edcTextSuffixToken, - const _mongocrypt_buffer_t *v, + const mc_EDCTextSuffixDerivedFromDataToken_t *edcTextSuffixToken, uint64_t u) -IMPL_TOKEN_NEW_FROM_DATA_AND_CONTENTION(mc_EDCTextSuffixDerivedFromDataTokenAndContentionFactorToken, - mc_EDCTextSuffixToken_get(edcTextSuffixToken), - v, - u) +IMPL_TOKEN_NEW_CONST(mc_EDCTextSuffixDerivedFromDataTokenAndContentionFactorToken, + mc_EDCTextSuffixDerivedFromDataToken_get(edcTextSuffixToken), + u) DEF_TOKEN_TYPE(mc_EDCTextPrefixDerivedFromDataTokenAndContentionFactorToken, - const mc_EDCTextPrefixToken_t *edcTextPrefixToken, - const _mongocrypt_buffer_t *v, + const mc_EDCTextPrefixDerivedFromDataToken_t *edcTextPrefixToken, uint64_t u) -IMPL_TOKEN_NEW_FROM_DATA_AND_CONTENTION(mc_EDCTextPrefixDerivedFromDataTokenAndContentionFactorToken, - mc_EDCTextPrefixToken_get(edcTextPrefixToken), - v, - u) +IMPL_TOKEN_NEW_CONST(mc_EDCTextPrefixDerivedFromDataTokenAndContentionFactorToken, + mc_EDCTextPrefixDerivedFromDataToken_get(edcTextPrefixToken), + u) -DEF_TOKEN_TYPE(mc_ESCTextExactDerivedFromDataTokenAndContentionFactorToken, +DEF_TOKEN_TYPE(mc_ESCTextExactDerivedFromDataToken, const mc_ESCTextExactToken_t *escTextExactToken, - const _mongocrypt_buffer_t *v, + const _mongocrypt_buffer_t *v) +IMPL_TOKEN_NEW(mc_ESCTextExactDerivedFromDataToken, mc_ESCTextExactToken_get(escTextExactToken), v) +DEF_TOKEN_TYPE(mc_ESCTextSubstringDerivedFromDataToken, + const mc_ESCTextSubstringToken_t *escTextSubstringToken, + const _mongocrypt_buffer_t *v) +IMPL_TOKEN_NEW(mc_ESCTextSubstringDerivedFromDataToken, mc_ESCTextSubstringToken_get(escTextSubstringToken), v) +DEF_TOKEN_TYPE(mc_ESCTextSuffixDerivedFromDataToken, + const mc_ESCTextSuffixToken_t *escTextSuffixToken, + const _mongocrypt_buffer_t *v) +IMPL_TOKEN_NEW(mc_ESCTextSuffixDerivedFromDataToken, mc_ESCTextSuffixToken_get(escTextSuffixToken), v) +DEF_TOKEN_TYPE(mc_ESCTextPrefixDerivedFromDataToken, + const mc_ESCTextPrefixToken_t *escTextPrefixToken, + const _mongocrypt_buffer_t *v) +IMPL_TOKEN_NEW(mc_ESCTextPrefixDerivedFromDataToken, mc_ESCTextPrefixToken_get(escTextPrefixToken), v) + +DEF_TOKEN_TYPE(mc_ESCTextExactDerivedFromDataTokenAndContentionFactorToken, + const mc_ESCTextExactDerivedFromDataToken_t *escTextExactToken, uint64_t u) -IMPL_TOKEN_NEW_FROM_DATA_AND_CONTENTION(mc_ESCTextExactDerivedFromDataTokenAndContentionFactorToken, - mc_ESCTextExactToken_get(escTextExactToken), - v, - u) +IMPL_TOKEN_NEW_CONST(mc_ESCTextExactDerivedFromDataTokenAndContentionFactorToken, + mc_ESCTextExactDerivedFromDataToken_get(escTextExactToken), + u) DEF_TOKEN_TYPE(mc_ESCTextSubstringDerivedFromDataTokenAndContentionFactorToken, - const mc_ESCTextSubstringToken_t *escTextSubstringToken, - const _mongocrypt_buffer_t *v, + const mc_ESCTextSubstringDerivedFromDataToken_t *escTextSubstringToken, uint64_t u) -IMPL_TOKEN_NEW_FROM_DATA_AND_CONTENTION(mc_ESCTextSubstringDerivedFromDataTokenAndContentionFactorToken, - mc_ESCTextSubstringToken_get(escTextSubstringToken), - v, - u) +IMPL_TOKEN_NEW_CONST(mc_ESCTextSubstringDerivedFromDataTokenAndContentionFactorToken, + mc_ESCTextSubstringDerivedFromDataToken_get(escTextSubstringToken), + u) DEF_TOKEN_TYPE(mc_ESCTextSuffixDerivedFromDataTokenAndContentionFactorToken, - const mc_ESCTextSuffixToken_t *escTextSuffixToken, - const _mongocrypt_buffer_t *v, + const mc_ESCTextSuffixDerivedFromDataToken_t *escTextSuffixToken, uint64_t u) -IMPL_TOKEN_NEW_FROM_DATA_AND_CONTENTION(mc_ESCTextSuffixDerivedFromDataTokenAndContentionFactorToken, - mc_ESCTextSuffixToken_get(escTextSuffixToken), - v, - u) +IMPL_TOKEN_NEW_CONST(mc_ESCTextSuffixDerivedFromDataTokenAndContentionFactorToken, + mc_ESCTextSuffixDerivedFromDataToken_get(escTextSuffixToken), + u) DEF_TOKEN_TYPE(mc_ESCTextPrefixDerivedFromDataTokenAndContentionFactorToken, - const mc_ESCTextPrefixToken_t *escTextPrefixToken, - const _mongocrypt_buffer_t *v, + const mc_ESCTextPrefixDerivedFromDataToken_t *escTextPrefixToken, uint64_t u) -IMPL_TOKEN_NEW_FROM_DATA_AND_CONTENTION(mc_ESCTextPrefixDerivedFromDataTokenAndContentionFactorToken, - mc_ESCTextPrefixToken_get(escTextPrefixToken), - v, - u) +IMPL_TOKEN_NEW_CONST(mc_ESCTextPrefixDerivedFromDataTokenAndContentionFactorToken, + mc_ESCTextPrefixDerivedFromDataToken_get(escTextPrefixToken), + u) DEF_TOKEN_TYPE(mc_ServerTextExactDerivedFromDataToken, const mc_ServerTextExactToken_t *serverTextExactToken, diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-writer-private.h b/ext/libmongocrypt/libmongocrypt/src/mc-writer-private.h index ef1abd5..c50a14f 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-writer-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mc-writer-private.h @@ -25,7 +25,7 @@ * A non-owning forward-only cursor api to write to a buffer. * * Tracks length of buffer and current position of buffer. parser_name is - * typically __FUNCTION__ to provide useful error messages automatically. + * typically __func__ to provide useful error messages automatically. * * All numbers are written as little endian. */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mc-writer.c b/ext/libmongocrypt/libmongocrypt/src/mc-writer.c index b6c0b9f..16e46cb 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mc-writer.c +++ b/ext/libmongocrypt/libmongocrypt/src/mc-writer.c @@ -21,7 +21,8 @@ #define CHECK_AND_RETURN(x) \ if (!(x)) { \ return false; \ - } + } else \ + ((void)0) #define CHECK_REMAINING_BUFFER_AND_RET(write_size) \ if ((write_size) > writer->len - writer->pos) { \ @@ -30,7 +31,8 @@ (writer->len - writer->pos), \ (uint64_t)(write_size)); \ return false; \ - } + } else \ + ((void)0) void mc_writer_init(mc_writer_t *writer, uint8_t *ptr, uint64_t len, const char *parser_name) { BSON_ASSERT_PARAM(writer); diff --git a/ext/libmongocrypt/libmongocrypt/src/mlib/error.h b/ext/libmongocrypt/libmongocrypt/src/mlib/error.h index 327fd59..6fa1840 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mlib/error.h +++ b/ext/libmongocrypt/libmongocrypt/src/mlib/error.h @@ -51,4 +51,4 @@ static inline mstr merror_system_error_string(int errn) { #endif } -#endif // MLIB_ERROR_PRIVATE_H \ No newline at end of file +#endif // MLIB_ERROR_PRIVATE_H diff --git a/ext/libmongocrypt/libmongocrypt/src/mlib/int128.h b/ext/libmongocrypt/libmongocrypt/src/mlib/int128.h index d433383..474c235 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mlib/int128.h +++ b/ext/libmongocrypt/libmongocrypt/src/mlib/int128.h @@ -9,6 +9,12 @@ #include #include +// Deliberately using old-style casts for C and C++ compatibility. +#if defined(__cplusplus) && defined(__clang__) +_Pragma("clang diagnostic push"); +_Pragma("clang diagnostic ignored \"-Wold-style-cast\""); +#endif + MLIB_C_LINKAGE_BEGIN /** @@ -496,7 +502,7 @@ static mlib_constexpr_fn mlib_int128_divmod_result mlib_int128_divmod(mlib_int12 u[2] |= (uint32_t)(numer.r.lo >> (64 - d)); u[4] |= (uint32_t)(numer.r.hi >> (64 - d)); v[2] |= (uint32_t)(denom.r.lo >> (64 - d)); - }; + } uint32_t q[2] = {0}; if (has_three) { @@ -644,4 +650,9 @@ static mlib_constexpr_fn mlib_int128_charbuf mlib_int128_format(mlib_int128 i) { MLIB_C_LINKAGE_END +// Deliberately using old-style casts for C and C++ compatibility. +#if defined(__cplusplus) && defined(__clang__) +_Pragma("clang diagnostic pop"); +#endif + #endif // MLIB_INT128_H_INCLUDED diff --git a/ext/libmongocrypt/libmongocrypt/src/mlib/int128.test.cpp b/ext/libmongocrypt/libmongocrypt/src/mlib/int128.test.cpp index 3a0854a..388ac33 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mlib/int128.test.cpp +++ b/ext/libmongocrypt/libmongocrypt/src/mlib/int128.test.cpp @@ -10,6 +10,11 @@ #include #include +// Deliberately using old-style casts for C and C++ compatibility. +#if defined(__clang__) +_Pragma("clang diagnostic ignored \"-Wold-style-cast\""); +#endif + #if (defined(__GNUC__) && __GNUC__ < 7 && !defined(__clang__)) || (defined(_MSC_VER) && _MSC_VER < 1920) // Old GCC and old MSVC have partially-broken constexpr that prevents us from // properly using static_assert with from_string() diff --git a/ext/libmongocrypt/libmongocrypt/src/mlib/path.h b/ext/libmongocrypt/libmongocrypt/src/mlib/path.h index 262014d..6c2b4fd 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mlib/path.h +++ b/ext/libmongocrypt/libmongocrypt/src/mlib/path.h @@ -60,7 +60,7 @@ static inline char mpath_preferred_sep(mpath_format f) { * @return mstr A new string which must be freed with mstr_free() */ static inline mstr mpath_current_path(void) { -#if _WIN32 +#if defined(_WIN32) while (1) { DWORD len = GetCurrentDirectoryW(0, NULL); wchar_t *wstr = calloc(sizeof(wchar_t), len); @@ -76,12 +76,12 @@ static inline mstr mpath_current_path(void) { } #else mstr_mut mut = mstr_new(8096); - char *p = getcwd(mut.data, mut.len); + char *p = getcwd(mut.raw.data, mut.raw.len); if (p == NULL) { mstr_free(mut.mstr); return MSTR_NULL; } - mstr ret = mstr_copy_cstr(mut.data); + mstr ret = mstr_copy_cstr(mut.raw.data); mstr_free(mut.mstr); return ret; #endif @@ -167,7 +167,7 @@ static inline mstr mpath_join(mstr_view base, mstr_view suffix, mpath_format f) // We must insert a path separator between the two strings assert(base.len <= SIZE_MAX - suffix.len - 1u); mstr_mut r = mstr_new(base.len + suffix.len + 1); - char *p = r.data; + char *p = r.raw.data; memcpy(p, base.data, base.len); p += base.len; *p++ = mpath_preferred_sep(f); @@ -255,7 +255,7 @@ static inline mstr_view mpath_relative_path(mstr_view path, mpath_format f) { static inline mstr mpath_to_format(mpath_format from, mstr_view path, mpath_format to) { mstr_mut ret = mstr_new(path.len); const char *p = path.data; - char *out = ret.data; + char *out = ret.raw.data; const char *stop = path.data + path.len; for (; p != stop; ++p, ++out) { if (mpath_is_sep(*p, from)) { diff --git a/ext/libmongocrypt/libmongocrypt/src/mlib/path.test.c b/ext/libmongocrypt/libmongocrypt/src/mlib/path.test.c index a661d5f..72eb55f 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mlib/path.test.c +++ b/ext/libmongocrypt/libmongocrypt/src/mlib/path.test.c @@ -1,8 +1,5 @@ #include "./path.h" -#define CHECK(Expr) \ - ((Expr) ? 0 : ((fprintf(stderr, "%s:%d: Check '%s' failed\n", __FILE__, __LINE__, #Expr), abort()), 0)) - #define TEST_DECOMP(Part, Given, Expect) \ MSTR_ASSERT_EQ(mpath_##Part(mstrv_view_cstr(Given), MPATH_NATIVE), mstrv_view_cstr(Expect)) @@ -12,7 +9,7 @@ static void test_make_absolute(mpath_format f, const char *part, const char *bas mstr_free(result); } -int main() { +int main(void) { mstr s = mstr_copy_cstr("/foo/bar/baz.txt"); MSTR_ASSERT_EQ(mpath_parent(s.view, MPATH_NATIVE), mstrv_lit("/foo/bar")); MSTR_ASSERT_EQ(mpath_parent(mpath_parent(s.view, MPATH_NATIVE), MPATH_NATIVE), mstrv_lit("/foo")); @@ -67,4 +64,4 @@ int main() { mstr_assign(&s, mpath_absolute(mstrv_lit("Z:/foo"), MPATH_POSIX)); mstr_free(s); -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/src/mlib/str.h b/ext/libmongocrypt/libmongocrypt/src/mlib/str.h index 1477b52..a2ba154 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mlib/str.h +++ b/ext/libmongocrypt/libmongocrypt/src/mlib/str.h @@ -17,6 +17,12 @@ #include /* For strncasecmp. */ #endif +// Deliberately using old-style casts for C and C++ compatibility. +#if defined(__cplusplus) && defined(__clang__) +_Pragma("clang diagnostic push"); +_Pragma("clang diagnostic ignored \"-Wold-style-cast\""); +#endif + MLIB_C_LINKAGE_BEGIN /** @@ -70,28 +76,26 @@ typedef struct mstr_view { * relinquish ownership of that `mstr` to the callee/caller, respectively. * Passing or returning an `mstr_view` is non-owning. */ -typedef struct mstr { - union { - struct { - /** - * @brief Pointer to the beginning of the code unit array. - * - * @note DO NOT MODIFY - */ - const char *data; - /** - * @brief Length of the pointed-to code unit array - * - * @note DO NOT MODIFY - */ - size_t len; - }; - +typedef union mstr { + struct { /** - * @brief A non-owning `mstr_view` of the string + * @brief Pointer to the beginning of the code unit array. + * + * @note DO NOT MODIFY */ - mstr_view view; - }; + const char *data; + /** + * @brief Length of the pointed-to code unit array + * + * @note DO NOT MODIFY + */ + size_t len; + } raw; + + /** + * @brief A non-owning `mstr_view` of the string + */ + mstr_view view; } mstr; /** @@ -100,34 +104,32 @@ typedef struct mstr { * Returned by @ref mstr_new(). Once initialization is complete, the result can * be used as an @ref mstr by accessing the @ref mstr_mut::mstr member. */ -typedef struct mstr_mut { - union { - struct { - /** - * @brief Pointer to the beginning of the mutable code unit array. - * - * @note DO NOT MODIFY THE POINTER VALUE. Only modify the pointed-to - * characters. - */ - char *data; - /** - * @brief Length of the pointed-to code unit array. - * - * @note DO NOT MODIFY - */ - size_t len; - }; - /// Convert the mutable string to an immutable string - struct mstr mstr; - /// Convert the mutable string to an immutable string view - mstr_view view; - }; +typedef union mstr_mut { + struct { + /** + * @brief Pointer to the beginning of the mutable code unit array. + * + * @note DO NOT MODIFY THE POINTER VALUE. Only modify the pointed-to + * characters. + */ + char *data; + /** + * @brief Length of the pointed-to code unit array. + * + * @note DO NOT MODIFY + */ + size_t len; + } raw; + /// Convert the mutable string to an immutable string + union mstr mstr; + /// Convert the mutable string to an immutable string view + mstr_view view; } mstr_mut; /** * @brief A null @ref mstr */ -#define MSTR_NULL (MLIB_INIT(mstr){{{NULL, 0}}}) +#define MSTR_NULL (MLIB_INIT(mstr){{NULL, 0}}) /** * @brief A null @ref mstr_view */ @@ -153,7 +155,7 @@ typedef struct mstr_mut { static inline mstr_mut mstr_new(size_t len) { #ifndef __clang_analyzer__ assert(len < SIZE_MAX); - return MLIB_INIT(mstr_mut){{{(char *)calloc(1, len + 1), len}}}; + return MLIB_INIT(mstr_mut){{(char *)calloc(1, len + 1), len}}; #else // Clang-analyzer is smart enough to see the calloc(), but not smart enough // to link it to the free() in mstr_free() @@ -195,7 +197,7 @@ static inline mstr_view mstrv_view_cstr(const char *s) { */ static inline mstr mstr_copy_data(const char *s, size_t len) { mstr_mut r = mstr_new(len); - memcpy(r.data, s, len); + memcpy(r.raw.data, s, len); return r.mstr; } @@ -225,7 +227,7 @@ static inline mstr mstr_copy(mstr_view s) { * @param s The string to free */ static inline void mstr_free(mstr s) { - free((char *)s.data); + free((char *)s.raw.data); } /** @@ -236,21 +238,21 @@ static inline void mstr_free(mstr s) { * @param new_len The new length of the string */ static inline void mstrm_resize(mstr_mut *s, size_t new_len) { - if (new_len <= s->len) { - s->len = new_len; + if (new_len <= s->raw.len) { + s->raw.len = new_len; } else { - const size_t old_len = s->len; + const size_t old_len = s->raw.len; #ifndef __clang_analyzer__ // Clang-analyzer is smart enough to see the calloc(), but not smart // enough to link it to the free() in mstr_free() assert(new_len < SIZE_MAX); - s->data = (char *)realloc((char *)s->data, new_len + 1); + s->raw.data = (char *)realloc((char *)s->raw.data, new_len + 1); #endif - s->len = new_len; + s->raw.len = new_len; assert(new_len >= old_len); - memset(s->data + old_len, 0, new_len - old_len); + memset(s->raw.data + old_len, 0, new_len - old_len); } - s->data[new_len] = (char)0; + s->raw.data[new_len] = (char)0; } /** @@ -369,7 +371,7 @@ static inline mstr mstr_splice(mstr_view s, size_t at, size_t del_count, mstr_vi assert(s.len - del_count <= SIZE_MAX - insert.len); const size_t new_size = s.len - del_count + insert.len; mstr_mut ret = mstr_new(new_size); - char *p = ret.data; + char *p = ret.raw.data; memcpy(p, s.data, at); p += at; if (insert.data) { @@ -451,7 +453,7 @@ static inline mstr mstr_substr(mstr_view s, size_t at, size_t len) { len = remain; } mstr_mut r = mstr_new(len); - memcpy(r.data, s.data + at, len); + memcpy(r.raw.data, s.data + at, len); return r.mstr; } @@ -607,7 +609,7 @@ static inline void _mstr_assert_(mstr_view left, if (!B) { mstr_assign(&pstr, mstr_prepend(pstr.view, mstrv_lit("not "))); } - _mstr_assert_fail_(left, pstr.data, right, file, line); + _mstr_assert_fail_(left, pstr.raw.data, right, file, line); } } @@ -767,9 +769,9 @@ static inline mstr_narrow_result mstr_win32_narrow(const wchar_t *wstring) { wcflags, wstring, -1, - ret.data, + ret.raw.data, // Plus one byte for the NUL - (int)(ret.len + 1), + (int)(ret.raw.len + 1), NULL, NULL); assert(length == got_len); @@ -906,4 +908,9 @@ static mlib_constexpr_fn size_t mlib_strnmcopy(char *dst, size_t dst_bufsize, co MLIB_C_LINKAGE_END +// Deliberately using old-style casts for C and C++ compatibility. +#if defined(__cplusplus) && defined(__clang__) +_Pragma("clang diagnostic pop"); +#endif + #endif // MONGOCRYPT_STR_PRIVATE_H diff --git a/ext/libmongocrypt/libmongocrypt/src/mlib/str.test.c b/ext/libmongocrypt/libmongocrypt/src/mlib/str.test.c index f052912..625f0a5 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mlib/str.test.c +++ b/ext/libmongocrypt/libmongocrypt/src/mlib/str.test.c @@ -5,16 +5,16 @@ #define test_predicate(Bool, Left, Pred, Right) MSTR_ASSERT(Bool, mstrv_lit(Left), Pred, mstrv_lit(Right)) -int main() { +int main(void) { // Test the null-initializers: mstr str = MSTR_NULL; mstr_view null_view = MSTRV_NULL; (void)null_view; str = mstr_copy_cstr("foo"); - CHECK(str.len == 3); + CHECK(str.raw.len == 3); MSTR_ASSERT_EQ(str.view, mstrv_lit("foo")); - CHECK(strncmp(str.data, "foo", 3) == 0); + CHECK(strncmp(str.raw.data, "foo", 3) == 0); mstr_inplace_append(&str, mstrv_lit("bar")); MSTR_ASSERT_EQ(str.view, mstrv_lit("foobar")); diff --git a/ext/libmongocrypt/libmongocrypt/src/mlib/thread.h b/ext/libmongocrypt/libmongocrypt/src/mlib/thread.h index 8cb26c5..5746031 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mlib/thread.h +++ b/ext/libmongocrypt/libmongocrypt/src/mlib/thread.h @@ -40,7 +40,7 @@ typedef struct mlib_once_flag { */ typedef void (*mlib_init_once_fn_t)(void); -#if _WIN32 +#if defined(_WIN32) /** * An indirection layer for mlib_once on Windows platforms. Do not use directly. */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mlib/user-check.h b/ext/libmongocrypt/libmongocrypt/src/mlib/user-check.h index 422e603..528fb25 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mlib/user-check.h +++ b/ext/libmongocrypt/libmongocrypt/src/mlib/user-check.h @@ -1,4 +1,4 @@ #ifndef MLIB_USER #error \ "The file being compiled transitively #include'd a mongo-mlib header, but is not a direct consumer of mlib, which is a private library for MongoDB C driver libraries" -#endif \ No newline at end of file +#endif diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo-private.h b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo-private.h index 2d8d24c..aa8f1af 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo-private.h @@ -20,4 +20,4 @@ void _mongocrypt_cache_collinfo_init(_mongocrypt_cache_t *cache); -#endif /* MONGOCRYPT_CACHE_COLLINFO_PRIVATE_H */ \ No newline at end of file +#endif /* MONGOCRYPT_CACHE_COLLINFO_PRIVATE_H */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo.c index a25a5ae..b9a55a0 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-collinfo.c @@ -14,6 +14,10 @@ * limitations under the License. */ +#include "mongocrypt-cache-collinfo-private.h" + +// + #include "mongocrypt-cache-private.h" /* The collinfo cache. diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ciphertext-private.h b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ciphertext-private.h index 1ab91d6..258b796 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ciphertext-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ciphertext-private.h @@ -22,7 +22,7 @@ #include "mongocrypt.h" /** - * Produced by mongocrypt-marking.c from _mongocrypt_marking_t + * Produced by mongocrypt-marking.u.fle1.c from _mongocrypt_marking_t * as encrypted payloads for blob_subtypes: * FLE1DeterministicEncryptedValue(1) * FLE1RandomEncryptedValue(2) diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto-private.h b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto-private.h index e06ab89..99e1919 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto-private.h @@ -77,18 +77,18 @@ typedef struct { // FLE1 algorithm: AES-256-CBC HMAC/SHA-512-256 (SHA-512 truncated to 256 bits) // Algorithm is documented in [FLE and // AEAD](https://docs.google.com/document/d/1D8xTXWo1B1dunO0bDZhPdolKTMbbD5fUIgsERubWRmY) -const _mongocrypt_value_encryption_algorithm_t *_mcFLE1Algorithm(); +const _mongocrypt_value_encryption_algorithm_t *_mcFLE1Algorithm(void); // FLE2 general algorithm: AES-256-CTR HMAC/SHA-256 // Algorithm is documented in [AEAD with // CTR](https://docs.google.com/document/d/1eCU7R8Kjr-mdyz6eKvhNIDVmhyYQcAaLtTfHeK7a_vE/). -const _mongocrypt_value_encryption_algorithm_t *_mcFLE2AEADAlgorithm(); +const _mongocrypt_value_encryption_algorithm_t *_mcFLE2AEADAlgorithm(void); // FLE2 used with FLE2IndexedEncryptedValue: AES-256-CTR no HMAC -const _mongocrypt_value_encryption_algorithm_t *_mcFLE2Algorithm(); +const _mongocrypt_value_encryption_algorithm_t *_mcFLE2Algorithm(void); // FLE2AEAD general algorithm: AES-256-CBC HMAC/SHA-256 -const _mongocrypt_value_encryption_algorithm_t *_mcFLE2v2AEADAlgorithm(); +const _mongocrypt_value_encryption_algorithm_t *_mcFLE2v2AEADAlgorithm(void); bool _mongocrypt_random(_mongocrypt_crypto_t *crypto, _mongocrypt_buffer_t *out, diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto.c index 2d2a4c4..4ba284c 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto.c @@ -305,9 +305,7 @@ bool _mongocrypt_hmac_sha_256(_mongocrypt_crypto_t *crypto, BSON_ASSERT_PARAM(out); if (key->len != MONGOCRYPT_MAC_KEY_LEN) { - CLIENT_ERR("invalid hmac_sha_256 key length. Got %" PRIu32 ", expected: %" PRIu32, - key->len, - MONGOCRYPT_MAC_KEY_LEN); + CLIENT_ERR("invalid hmac_sha_256 key length. Got %" PRIu32 ", expected: %d", key->len, MONGOCRYPT_MAC_KEY_LEN); return false; } @@ -501,12 +499,14 @@ static bool _encrypt_step(_mongocrypt_crypto_t *crypto, *bytes_written = 0; if (MONGOCRYPT_IV_LEN != iv->len) { - CLIENT_ERR("IV should have length %d, but has length %d", MONGOCRYPT_IV_LEN, iv->len); + CLIENT_ERR("IV should have length %d, but has length %" PRIu32, MONGOCRYPT_IV_LEN, iv->len); return false; } if (MONGOCRYPT_ENC_KEY_LEN != enc_key->len) { - CLIENT_ERR("Encryption key should have length %d, but has length %d", MONGOCRYPT_ENC_KEY_LEN, enc_key->len); + CLIENT_ERR("Encryption key should have length %d, but has length %" PRIu32, + MONGOCRYPT_ENC_KEY_LEN, + enc_key->len); return false; } @@ -575,7 +575,9 @@ static bool _encrypt_step(_mongocrypt_crypto_t *crypto, } if (*bytes_written % MONGOCRYPT_BLOCK_SIZE != 0) { - CLIENT_ERR("encryption failure, wrote %d bytes, not a multiple of %d", *bytes_written, MONGOCRYPT_BLOCK_SIZE); + CLIENT_ERR("encryption failure, wrote %" PRIu32 " bytes, not a multiple of %d", + *bytes_written, + MONGOCRYPT_BLOCK_SIZE); return false; } @@ -628,12 +630,12 @@ static bool _hmac_step(_mongocrypt_crypto_t *crypto, _mongocrypt_buffer_init(&to_hmac); if (MONGOCRYPT_MAC_KEY_LEN != Km->len) { - CLIENT_ERR("HMAC key wrong length: %d", Km->len); + CLIENT_ERR("HMAC key wrong length: %" PRIu32, Km->len); goto done; } if (out->len != MONGOCRYPT_HMAC_LEN) { - CLIENT_ERR("out wrong length: %d", out->len); + CLIENT_ERR("out wrong length: %" PRIu32, out->len); goto done; } @@ -761,18 +763,18 @@ static bool _mongocrypt_do_encryption(_mongocrypt_crypto_t *crypto, return false; } if (expect_ciphertext_len != ciphertext->len) { - CLIENT_ERR("output ciphertext should have been allocated with %d bytes", expect_ciphertext_len); + CLIENT_ERR("output ciphertext should have been allocated with %" PRIu32 " bytes", expect_ciphertext_len); return false; } if (MONGOCRYPT_IV_LEN != iv->len) { - CLIENT_ERR("IV should have length %d, but has length %d", MONGOCRYPT_IV_LEN, iv->len); + CLIENT_ERR("IV should have length %d, but has length %" PRIu32, MONGOCRYPT_IV_LEN, iv->len); return false; } const uint32_t expected_key_len = (key_format == KEY_FORMAT_FLE2) ? MONGOCRYPT_ENC_KEY_LEN : MONGOCRYPT_KEY_LEN; if (key->len != expected_key_len) { - CLIENT_ERR("key should have length %d, but has length %d", expected_key_len, key->len); + CLIENT_ERR("key should have length %" PRIu32 ", but has length %" PRIu32, expected_key_len, key->len); return false; } @@ -886,11 +888,13 @@ static bool _decrypt_step(_mongocrypt_crypto_t *crypto, *bytes_written = 0; if (MONGOCRYPT_IV_LEN != iv->len) { - CLIENT_ERR("IV should have length %d, but has length %d", MONGOCRYPT_IV_LEN, iv->len); + CLIENT_ERR("IV should have length %d, but has length %" PRIu32, MONGOCRYPT_IV_LEN, iv->len); return false; } if (MONGOCRYPT_ENC_KEY_LEN != enc_key->len) { - CLIENT_ERR("encryption key should have length %d, but has length %d", MONGOCRYPT_ENC_KEY_LEN, enc_key->len); + CLIENT_ERR("encryption key should have length %d, but has length %" PRIu32, + MONGOCRYPT_ENC_KEY_LEN, + enc_key->len); return false; } @@ -986,8 +990,8 @@ static bool _mongocrypt_do_decryption(_mongocrypt_crypto_t *crypto, return false; } if (plaintext->len != expect_plaintext_len) { - CLIENT_ERR("output plaintext should have been allocated with %d bytes, " - "but has: %d", + CLIENT_ERR("output plaintext should have been allocated with %" PRIu32 " bytes, " + "but has: %" PRIu32, expect_plaintext_len, plaintext->len); return false; @@ -1004,13 +1008,13 @@ static bool _mongocrypt_do_decryption(_mongocrypt_crypto_t *crypto, const uint32_t expected_key_len = (key_format == KEY_FORMAT_FLE2) ? MONGOCRYPT_ENC_KEY_LEN : MONGOCRYPT_KEY_LEN; if (expected_key_len != key->len) { - CLIENT_ERR("key should have length %d, but has length %d", expected_key_len, key->len); + CLIENT_ERR("key should have length %" PRIu32 ", but has length %" PRIu32, expected_key_len, key->len); return false; } const uint32_t min_cipherlen = _mongocrypt_calculate_ciphertext_len(0, mode, hmac, NULL); if (ciphertext->len < min_cipherlen) { - CLIENT_ERR("corrupt ciphertext - must be >= %d bytes", min_cipherlen); + CLIENT_ERR("corrupt ciphertext - must be >= %" PRIu32 " bytes", min_cipherlen); return false; } @@ -1138,7 +1142,9 @@ static bool _mongocrypt_do_decryption(_mongocrypt_crypto_t *crypto, _mc_##name##_do_encryption, \ _mc_##name##_do_decryption, \ }; \ - const _mongocrypt_value_encryption_algorithm_t *_mc##name##Algorithm() { return &_mc##name##Algorithm_definition; } + const _mongocrypt_value_encryption_algorithm_t *_mc##name##Algorithm(void) { \ + return &_mc##name##Algorithm_definition; \ + } // FLE1 algorithm: AES-256-CBC HMAC/SHA-512-256 (SHA-512 truncated to 256 bits) DECLARE_ALGORITHM(FLE1, CBC, SHA_512_256) @@ -1181,7 +1187,7 @@ bool _mongocrypt_random(_mongocrypt_crypto_t *crypto, BSON_ASSERT_PARAM(out); if (count != out->len) { - CLIENT_ERR("out should have length %d, but has length %d", count, out->len); + CLIENT_ERR("out should have length %" PRIu32 ", but has length %" PRIu32, count, out->len); return false; } @@ -1233,11 +1239,11 @@ bool _mongocrypt_calculate_deterministic_iv(_mongocrypt_crypto_t *crypto, BSON_ASSERT_PARAM(out); if (MONGOCRYPT_KEY_LEN != key->len) { - CLIENT_ERR("key should have length %d, but has length %d\n", MONGOCRYPT_KEY_LEN, key->len); + CLIENT_ERR("key should have length %d, but has length %" PRIu32 "\n", MONGOCRYPT_KEY_LEN, key->len); goto done; } if (MONGOCRYPT_IV_LEN != out->len) { - CLIENT_ERR("out should have length %d, but has length %d\n", MONGOCRYPT_IV_LEN, out->len); + CLIENT_ERR("out should have length %d, but has length %" PRIu32 "\n", MONGOCRYPT_IV_LEN, out->len); goto done; } @@ -1300,7 +1306,7 @@ bool _mongocrypt_wrap_key(_mongocrypt_crypto_t *crypto, _mongocrypt_buffer_init(encrypted_dek); if (dek->len != MONGOCRYPT_KEY_LEN) { - CLIENT_ERR("data encryption key is incorrect length, expected: %" PRIu32 ", got: %" PRIu32, + CLIENT_ERR("data encryption key is incorrect length, expected: %d, got: %" PRIu32, MONGOCRYPT_KEY_LEN, dek->len); goto done; @@ -1348,9 +1354,7 @@ bool _mongocrypt_unwrap_key(_mongocrypt_crypto_t *crypto, dek->len = bytes_written; if (dek->len != MONGOCRYPT_KEY_LEN) { - CLIENT_ERR("decrypted key is incorrect length, expected: %" PRIu32 ", got: %" PRIu32, - MONGOCRYPT_KEY_LEN, - dek->len); + CLIENT_ERR("decrypted key is incorrect length, expected: %d, got: %" PRIu32, MONGOCRYPT_KEY_LEN, dek->len); return false; } return true; diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-datakey.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-datakey.c index 09f62cf..16e09e1 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-datakey.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-datakey.c @@ -469,7 +469,8 @@ static bool _finalize(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out) { if (!(_stmt)) { \ bson_destroy(&key_doc); \ return _mongocrypt_ctx_fail_w_msg(ctx, "unable to construct BSON doc"); \ - } + } else \ + ((void)0) dkctx = (_mongocrypt_ctx_datakey_t *)ctx; @@ -566,4 +567,4 @@ bool mongocrypt_ctx_datakey_init(mongocrypt_ctx_t *ctx) { ret = true; done: return ret; -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-decrypt.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-decrypt.c index 3b6d7bf..b20170d 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-decrypt.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-decrypt.c @@ -29,19 +29,22 @@ #define CHECK_AND_RETURN(cond) \ if (!(cond)) { \ goto fail; \ - } + } else \ + ((void)0) #define CHECK_AND_RETURN_STATUS(cond, msg) \ if (!(cond)) { \ CLIENT_ERR(msg); \ goto fail; \ - } + } else \ + ((void)0) #define CHECK_AND_RETURN_KB_STATUS(cond) \ if (!(cond)) { \ _mongocrypt_key_broker_status(kb, status); \ goto fail; \ - } + } else \ + ((void)0) static bool _replace_FLE2IndexedEncryptedValue_with_plaintext(void *ctx, _mongocrypt_buffer_t *in, diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-encrypt.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-encrypt.c index 57f499a..1f05919 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-encrypt.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-encrypt.c @@ -15,6 +15,7 @@ */ #include "mc-efc-private.h" +#include "mc-fle-blob-subtype-private.h" #include "mc-fle2-rfds-private.h" #include "mc-tokens-private.h" #include "mongocrypt-ciphertext-private.h" @@ -280,13 +281,13 @@ static bool _collect_key_from_marking(void *ctx, _mongocrypt_buffer_t *in, mongo } if (marking.type == MONGOCRYPT_MARKING_FLE1_BY_ID) { - res = _mongocrypt_key_broker_request_id(kb, &marking.key_id); + res = _mongocrypt_key_broker_request_id(kb, &marking.u.fle1.key_id); } else if (marking.type == MONGOCRYPT_MARKING_FLE1_BY_ALTNAME) { - res = _mongocrypt_key_broker_request_name(kb, &marking.key_alt_name); + res = _mongocrypt_key_broker_request_name(kb, &marking.u.fle1.key_alt_name); } else { BSON_ASSERT(marking.type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION); - res = _mongocrypt_key_broker_request_id(kb, &marking.fle2.index_key_id) - && _mongocrypt_key_broker_request_id(kb, &marking.fle2.user_key_id); + res = _mongocrypt_key_broker_request_id(kb, &marking.u.fle2.index_key_id) + && _mongocrypt_key_broker_request_id(kb, &marking.u.fle2.user_key_id); } if (!res) { @@ -574,7 +575,8 @@ static bool _try_run_csfle_marking(mongocrypt_ctx_t *ctx) { static bool _mongocrypt_fle2_insert_update_find(mc_fle_blob_subtype_t subtype) { return (subtype == MC_SUBTYPE_FLE2InsertUpdatePayload) || (subtype == MC_SUBTYPE_FLE2InsertUpdatePayloadV2) || (subtype == MC_SUBTYPE_FLE2FindEqualityPayload) || (subtype == MC_SUBTYPE_FLE2FindEqualityPayloadV2) - || (subtype == MC_SUBTYPE_FLE2FindRangePayload) || (subtype == MC_SUBTYPE_FLE2FindRangePayloadV2); + || (subtype == MC_SUBTYPE_FLE2FindRangePayload) || (subtype == MC_SUBTYPE_FLE2FindRangePayloadV2) + || (subtype == MC_SUBTYPE_FLE2FindTextPayload); } static bool @@ -608,7 +610,7 @@ _marking_to_bson_value(void *ctx, _mongocrypt_marking_t *marking, bson_value_t * } else if (!_mongocrypt_serialize_ciphertext(&ciphertext, &serialized_ciphertext)) { CLIENT_ERR("malformed ciphertext"); goto fail; - }; + } /* ownership of serialized_ciphertext is transferred to caller. */ out->value_type = BSON_TYPE_BINARY; @@ -671,7 +673,6 @@ typedef struct { // must omit the "encryptionInformation" field when sent to mongod / mongos. static moe_result must_omit_encryptionInformation(const char *command_name, const bson_t *command, - bool use_range_v2, const mc_EncryptedFieldConfig_t *efc, mongocrypt_status_t *status) { // eligible_commands may omit encryptionInformation if the command does not @@ -696,12 +697,10 @@ static moe_result must_omit_encryptionInformation(const char *command_name, // - Server 8.0 requires `encryptionInformation` if "range" fields are referenced. Otherwise ignores. // Only send `encryptionInformation` if "range" fields are present to support both server versions. bool uses_range_fields = false; - if (use_range_v2) { - for (const mc_EncryptedField_t *ef = efc->fields; ef != NULL; ef = ef->next) { - if (ef->supported_queries & SUPPORTS_RANGE_QUERIES) { - uses_range_fields = true; - break; - } + for (const mc_EncryptedField_t *ef = efc->fields; ef != NULL; ef = ef->next) { + if (ef->supported_queries & SUPPORTS_RANGE_QUERIES) { + uses_range_fields = true; + break; } } return (moe_result){.ok = true, .must_omit = !uses_range_fields}; @@ -818,7 +817,7 @@ static bool _fle2_append_compactionTokens(mongocrypt_t *crypt, const _mongocrypt_buffer_t *ecoct_buf = mc_ECOCToken_get(ecoct); - if (crypt->opts.use_range_v2 && (ptr->supported_queries & SUPPORTS_RANGE_QUERIES)) { + if ((ptr->supported_queries & SUPPORTS_RANGE_QUERIES)) { // Append the document {ecoc: , anchorPaddingToken: } esct = mc_ESCToken_new(crypto, cl1t, status); if (!esct) { @@ -1061,7 +1060,7 @@ static bool _fle2_fixup_encryptedFields_strEncodeVersion(const char *cmd_name, } else { // Check strEncodeVersion for match against EFC if (!BSON_ITER_HOLDS_INT32(&sev_iter)) { - CLIENT_ERR("expected 'strEncodeVersion' to be type int32, got: %d", bson_iter_type(&sev_iter)); + CLIENT_ERR("expected 'strEncodeVersion' to be type int32, got: %d", (int)bson_iter_type(&sev_iter)); return false; } int32_t version = bson_iter_int32(&sev_iter); @@ -1139,11 +1138,7 @@ static bool _fle2_finalize(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out) { const mc_EncryptedFieldConfig_t *target_efc = mc_schema_broker_get_encryptedFields(ectx->sb, ectx->target_coll, NULL); - moe_result result = must_omit_encryptionInformation(command_name, - &converted, - ctx->crypt->opts.use_range_v2, - target_efc, - ctx->status); + moe_result result = must_omit_encryptionInformation(command_name, &converted, target_efc, ctx->status); if (!result.ok) { bson_destroy(&converted); return _mongocrypt_ctx_fail(ctx); @@ -1311,29 +1306,25 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t * if (ctx->opts.query_type.set) { switch (ctx->opts.query_type.value) { case MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED: - if (ctx->crypt->opts.use_range_v2) { - _mongocrypt_ctx_fail_w_msg(ctx, "Cannot use rangePreview query type with Range V2"); - goto fail; - } + _mongocrypt_ctx_fail_w_msg(ctx, "Cannot use rangePreview query type with Range V2"); + goto fail; // fallthrough case MONGOCRYPT_QUERY_TYPE_RANGE: - case MONGOCRYPT_QUERY_TYPE_EQUALITY: marking.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; } } else { - marking.fle2.type = MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT; + marking.u.fle2.type = MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT; } switch (ctx->opts.index_type.value) { - case MONGOCRYPT_INDEX_TYPE_EQUALITY: marking.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_EQUALITY; break; - case MONGOCRYPT_INDEX_TYPE_NONE: marking.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED; break; + case MONGOCRYPT_INDEX_TYPE_EQUALITY: marking.u.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_EQUALITY; break; + case MONGOCRYPT_INDEX_TYPE_NONE: marking.u.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED; break; case MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED: - if (ctx->crypt->opts.use_range_v2) { - _mongocrypt_ctx_fail_w_msg(ctx, "Cannot use rangePreview index type with Range V2"); - goto fail; - } + _mongocrypt_ctx_fail_w_msg(ctx, "Cannot use rangePreview index type with Range V2"); + goto fail; // fallthrough - case MONGOCRYPT_INDEX_TYPE_RANGE: marking.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_RANGE; break; + case MONGOCRYPT_INDEX_TYPE_RANGE: marking.u.fle2.algorithm = MONGOCRYPT_FLE2_ALGORITHM_RANGE; break; default: // This might be unreachable because of other validation. Better safe than // sorry. @@ -1354,21 +1345,17 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t * // RangeOpts with query_type is handled above. BSON_ASSERT(!ctx->opts.query_type.set); - if (!mc_RangeOpts_to_FLE2RangeInsertSpec(&ctx->opts.rangeopts.value, - &old_v, - &new_v, - ctx->crypt->opts.use_range_v2, - ctx->status)) { + if (!mc_RangeOpts_to_FLE2RangeInsertSpec(&ctx->opts.rangeopts.value, &old_v, &new_v, ctx->status)) { _mongocrypt_ctx_fail(ctx); goto fail; } - if (!bson_iter_init_find(&marking.v_iter, &new_v, "v")) { + if (!bson_iter_init_find(&marking.u.fle1.v_iter, &new_v, "v")) { _mongocrypt_ctx_fail_w_msg(ctx, "invalid input BSON, must contain 'v'"); goto fail; } - marking.fle2.sparsity = ctx->opts.rangeopts.value.sparsity; + marking.u.fle2.sparsity = ctx->opts.rangeopts.value.sparsity; } else { bson_t as_bson; @@ -1379,21 +1366,21 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t * goto fail; } - if (!bson_iter_init_find(&marking.v_iter, &as_bson, "v")) { + if (!bson_iter_init_find(&marking.u.fle1.v_iter, &as_bson, "v")) { _mongocrypt_ctx_fail_w_msg(ctx, "invalid input BSON, must contain 'v'"); goto fail; } } - _mongocrypt_buffer_copy_to(&ctx->opts.key_id, &marking.fle2.user_key_id); + _mongocrypt_buffer_copy_to(&ctx->opts.key_id, &marking.u.fle2.user_key_id); if (!_mongocrypt_buffer_empty(&ctx->opts.index_key_id)) { - _mongocrypt_buffer_copy_to(&ctx->opts.index_key_id, &marking.fle2.index_key_id); + _mongocrypt_buffer_copy_to(&ctx->opts.index_key_id, &marking.u.fle2.index_key_id); } else { - _mongocrypt_buffer_copy_to(&ctx->opts.key_id, &marking.fle2.index_key_id); + _mongocrypt_buffer_copy_to(&ctx->opts.key_id, &marking.u.fle2.index_key_id); } if (ctx->opts.contention_factor.set) { - marking.fle2.maxContentionFactor = ctx->opts.contention_factor.value; + marking.u.fle2.maxContentionFactor = ctx->opts.contention_factor.value; } else if (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_EQUALITY) { _mongocrypt_ctx_fail_w_msg(ctx, "contention factor required for indexed algorithm"); goto fail; @@ -1494,11 +1481,11 @@ static bool _finalize(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out) { return _mongocrypt_ctx_fail_w_msg(ctx, "invalid msg, must contain 'v'"); } - memcpy(&marking.v_iter, &iter, sizeof(bson_iter_t)); - marking.algorithm = ctx->opts.algorithm; - _mongocrypt_buffer_set_to(&ctx->opts.key_id, &marking.key_id); + memcpy(&marking.u.fle1.v_iter, &iter, sizeof(bson_iter_t)); + marking.u.fle1.algorithm = ctx->opts.algorithm; + _mongocrypt_buffer_set_to(&ctx->opts.key_id, &marking.u.fle1.key_id); if (ctx->opts.key_alt_names) { - bson_value_copy(&ctx->opts.key_alt_names->value, &marking.key_alt_name); + bson_value_copy(&ctx->opts.key_alt_names->value, &marking.u.fle1.key_alt_name); marking.type = MONGOCRYPT_MARKING_FLE1_BY_ALTNAME; } @@ -1901,7 +1888,7 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms matches = (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_EQUALITY); break; default: - CLIENT_ERR("unsupported value for query_type: %d", ctx->opts.query_type.value); + CLIENT_ERR("unsupported value for query_type: %d", (int)ctx->opts.query_type.value); return _mongocrypt_ctx_fail(ctx); } @@ -2238,10 +2225,16 @@ static bool needs_ismaster_check(mongocrypt_ctx_t *ctx) { // `find_collections_in_pipeline` finds other collection names in an aggregate pipeline that may need schemas. static bool find_collections_in_pipeline(mc_schema_broker_t *sb, - bson_iter_t pipeline_iter, + bson_iter_t *pipeline_iter_ptr, const char *db, mstr_view path, mongocrypt_status_t *status) { + BSON_ASSERT_PARAM(sb); + BSON_ASSERT_PARAM(pipeline_iter_ptr); + BSON_ASSERT_PARAM(db); + + bson_iter_t pipeline_iter = *pipeline_iter_ptr; // Operate on a copy. + bson_iter_t array_iter; if (!BSON_ITER_HOLDS_ARRAY(&pipeline_iter) || !bson_iter_recurse(&pipeline_iter, &array_iter)) { CLIENT_ERR("failed to recurse pipeline at path: %s", path.data); @@ -2287,7 +2280,7 @@ static bool find_collections_in_pipeline(mc_schema_broker_t *sb, mstr subpath = mstr_append(path, mstrv_lit(".")); mstr_inplace_append(&subpath, mstrv_view_cstr(stage_key)); mstr_inplace_append(&subpath, mstrv_lit(".$lookup.pipeline")); - if (!find_collections_in_pipeline(sb, lookup_iter, db, subpath.view, status)) { + if (!find_collections_in_pipeline(sb, &lookup_iter, db, subpath.view, status)) { mstr_free(subpath); return false; } @@ -2310,7 +2303,7 @@ static bool find_collections_in_pipeline(mc_schema_broker_t *sb, mstr_inplace_append(&subpath, mstrv_view_cstr(stage_key)); mstr_inplace_append(&subpath, mstrv_lit(".$facet.")); mstr_inplace_append(&subpath, mstrv_view_cstr(field)); - if (!find_collections_in_pipeline(sb, facet_iter, db, subpath.view, status)) { + if (!find_collections_in_pipeline(sb, &facet_iter, db, subpath.view, status)) { mstr_free(subpath); return false; } @@ -2346,7 +2339,7 @@ static bool find_collections_in_pipeline(mc_schema_broker_t *sb, mstr subpath = mstr_append(path, mstrv_lit(".")); mstr_inplace_append(&subpath, mstrv_view_cstr(stage_key)); mstr_inplace_append(&subpath, mstrv_lit(".$unionWith.pipeline")); - if (!find_collections_in_pipeline(sb, unionWith_iter, db, subpath.view, status)) { + if (!find_collections_in_pipeline(sb, &unionWith_iter, db, subpath.view, status)) { mstr_free(subpath); return false; } @@ -2373,7 +2366,7 @@ find_collections_in_agg(mongocrypt_binary_t *cmd, mc_schema_broker_t *sb, const return true; } - return find_collections_in_pipeline(sb, iter, db, mstrv_lit("aggregate.pipeline"), status); + return find_collections_in_pipeline(sb, &iter, db, mstrv_lit("aggregate.pipeline"), status); } bool mongocrypt_ctx_encrypt_init(mongocrypt_ctx_t *ctx, const char *db, int32_t db_len, mongocrypt_binary_t *cmd) { @@ -2409,9 +2402,6 @@ bool mongocrypt_ctx_encrypt_init(mongocrypt_ctx_t *ctx, const char *db, int32_t ctx->vtable.cleanup = _cleanup; ectx->bypass_query_analysis = ctx->crypt->opts.bypass_query_analysis; ectx->sb = mc_schema_broker_new(); - if (ctx->crypt->opts.use_range_v2) { - mc_schema_broker_use_rangev2(ectx->sb); - } if (!cmd || !cmd->data) { return _mongocrypt_ctx_fail_w_msg(ctx, "invalid command"); diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-rewrap-many-datakey.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-rewrap-many-datakey.c index 32fc6f7..e24865c 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-rewrap-many-datakey.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-rewrap-many-datakey.c @@ -136,6 +136,18 @@ static mongocrypt_kms_ctx_t *_next_kms_ctx_encrypt(mongocrypt_ctx_t *ctx) { mongocrypt_ctx_t *dkctx = NULL; BSON_ASSERT_PARAM(ctx); + /* Check if any need retry */ + { + _mongocrypt_ctx_rmd_datakey_t *it = rmdctx->datakeys; + while (it != NULL) { + _mongocrypt_ctx_datakey_t *dkctx = (_mongocrypt_ctx_datakey_t *)it->dkctx; + if (dkctx->kms.should_retry) { + dkctx->kms.should_retry = false; // Reset retry state. + return &dkctx->kms; + } + it = it->next; + } + } /* No more datakey contexts requiring KMS. */ if (!rmdctx->datakeys_iter) { diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx.c index f0384d9..db5b0b4 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx.c @@ -262,12 +262,8 @@ bool mongocrypt_ctx_setopt_algorithm(mongocrypt_ctx_t *ctx, const char *algorith ctx->opts.index_type.value = MONGOCRYPT_INDEX_TYPE_RANGE; ctx->opts.index_type.set = true; } else if (mstr_eq_ignore_case(algo_str, mstrv_lit(MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR))) { - if (ctx->crypt->opts.use_range_v2) { - _mongocrypt_ctx_fail_w_msg(ctx, "Algorithm 'rangePreview' is deprecated, please use 'range'"); - return false; - } - ctx->opts.index_type.value = MONGOCRYPT_INDEX_TYPE_RANGEPREVIEW_DEPRECATED; - ctx->opts.index_type.set = true; + _mongocrypt_ctx_fail_w_msg(ctx, "Algorithm 'rangePreview' is deprecated, please use 'range'"); + return false; } else { char *error = bson_strdup_printf("unsupported algorithm string \"%.*s\"", algo_str.len <= (size_t)INT_MAX ? (int)algo_str.len : INT_MAX, @@ -1068,12 +1064,8 @@ bool mongocrypt_ctx_setopt_query_type(mongocrypt_ctx_t *ctx, const char *query_t ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_RANGE; ctx->opts.query_type.set = true; } else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED_STR))) { - if (ctx->crypt->opts.use_range_v2) { - _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'rangePreview' is deprecated, please use 'range'"); - return false; - } - ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED; - ctx->opts.query_type.set = true; + _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'rangePreview' is deprecated, please use 'range'"); + return false; } else { /* don't check if qt_str.len fits in int; we want the diagnostic output */ char *error = bson_strdup_printf("Unsupported query_type \"%.*s\"", @@ -1128,7 +1120,7 @@ bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_bin return _mongocrypt_ctx_fail_w_msg(ctx, "invalid BSON"); } - if (!mc_RangeOpts_parse(&ctx->opts.rangeopts.value, &as_bson, ctx->crypt->opts.use_range_v2, ctx->status)) { + if (!mc_RangeOpts_parse(&ctx->opts.rangeopts.value, &as_bson, ctx->status)) { return _mongocrypt_ctx_fail(ctx); } diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-dll-private.h b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-dll-private.h index 3debb73..7560b3f 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-dll-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-dll-private.h @@ -6,9 +6,9 @@ #include -#if _WIN32 +#if defined(_WIN32) #define MCR_DLL_SUFFIX ".dll" -#elif __APPLE__ +#elif defined(__APPLE__) #define MCR_DLL_SUFFIX ".dylib" #else #define MCR_DLL_SUFFIX ".so" @@ -54,6 +54,23 @@ static inline void mcr_dll_close(mcr_dll dll) { mstr_free(dll.error_string); } +// All currently supported platforms require casting to/from `void*` for dynamically loaded function symbols by +// necessity despite being undefined behavior according to the C standard specification. +#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +// GCC requires silencing `-Wpedantic` for this cast. +#define MC_BEGIN_CAST_FUNCTION_TYPE_STRICT_IGNORE \ + _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wpedantic\"") +#define MC_END_CAST_FUNCTION_TYPE_STRICT_IGNORE _Pragma("GCC diagnostic pop") +#elif defined(__clang__) +#define MC_BEGIN_CAST_FUNCTION_TYPE_STRICT_IGNORE \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wunknown-warning-option\"") \ + _Pragma("clang diagnostic ignored \"-Wcast-function-type-strict\"") +#define MC_END_CAST_FUNCTION_TYPE_STRICT_IGNORE _Pragma("clang diagnostic pop") +#else +#define MC_BEGIN_CAST_FUNCTION_TYPE_STRICT_IGNORE +#define MC_END_CAST_FUNCTION_TYPE_STRICT_IGNORE +#endif + /** * @brief Obtain a pointer to an exported entity from the given dynamic library. * diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-broker.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-broker.c index 7af66c4..5bf7ae2 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-broker.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-broker.c @@ -24,11 +24,11 @@ typedef struct _auth_request_t { char *kmsid; } auth_request_t; -auth_request_t *auth_request_new() { +static auth_request_t *auth_request_new(void) { return bson_malloc0(sizeof(auth_request_t)); } -void auth_request_destroy(auth_request_t *ar) { +static void auth_request_destroy(auth_request_t *ar) { if (!ar) { return; } @@ -41,13 +41,13 @@ struct _mc_mapof_kmsid_to_authrequest_t { mc_array_t entries; }; -mc_mapof_kmsid_to_authrequest_t *mc_mapof_kmsid_to_authrequest_new(void) { +static mc_mapof_kmsid_to_authrequest_t *mc_mapof_kmsid_to_authrequest_new(void) { mc_mapof_kmsid_to_authrequest_t *k2a = bson_malloc0(sizeof(mc_mapof_kmsid_to_authrequest_t)); _mc_array_init(&k2a->entries, sizeof(auth_request_t *)); return k2a; } -void mc_mapof_kmsid_to_authrequest_destroy(mc_mapof_kmsid_to_authrequest_t *k2a) { +static void mc_mapof_kmsid_to_authrequest_destroy(mc_mapof_kmsid_to_authrequest_t *k2a) { if (!k2a) { return; } @@ -59,7 +59,7 @@ void mc_mapof_kmsid_to_authrequest_destroy(mc_mapof_kmsid_to_authrequest_t *k2a) bson_free(k2a); } -bool mc_mapof_kmsid_to_authrequest_has(const mc_mapof_kmsid_to_authrequest_t *k2a, const char *kmsid) { +static bool mc_mapof_kmsid_to_authrequest_has(const mc_mapof_kmsid_to_authrequest_t *k2a, const char *kmsid) { BSON_ASSERT_PARAM(k2a); BSON_ASSERT_PARAM(kmsid); for (size_t i = 0; i < k2a->entries.len; i++) { @@ -71,25 +71,25 @@ bool mc_mapof_kmsid_to_authrequest_has(const mc_mapof_kmsid_to_authrequest_t *k2 return false; } -size_t mc_mapof_kmsid_to_authrequest_len(const mc_mapof_kmsid_to_authrequest_t *k2a) { +static size_t mc_mapof_kmsid_to_authrequest_len(const mc_mapof_kmsid_to_authrequest_t *k2a) { BSON_ASSERT_PARAM(k2a); return k2a->entries.len; } -bool mc_mapof_kmsid_to_authrequest_empty(const mc_mapof_kmsid_to_authrequest_t *k2a) { +static bool mc_mapof_kmsid_to_authrequest_empty(const mc_mapof_kmsid_to_authrequest_t *k2a) { BSON_ASSERT_PARAM(k2a); return k2a->entries.len == 0; } // `mc_mapof_kmsid_to_authrequest_put` moves `to_put` into the map and takes ownership of `to_put`. // No checking is done to prohibit duplicate entries. -void mc_mapof_kmsid_to_authrequest_put(mc_mapof_kmsid_to_authrequest_t *k2a, auth_request_t *to_put) { +static void mc_mapof_kmsid_to_authrequest_put(mc_mapof_kmsid_to_authrequest_t *k2a, auth_request_t *to_put) { BSON_ASSERT_PARAM(k2a); _mc_array_append_val(&k2a->entries, to_put); } -auth_request_t *mc_mapof_kmsid_to_authrequest_at(mc_mapof_kmsid_to_authrequest_t *k2a, size_t i) { +static auth_request_t *mc_mapof_kmsid_to_authrequest_at(mc_mapof_kmsid_to_authrequest_t *k2a, size_t i) { BSON_ASSERT_PARAM(k2a); return _mc_array_index(&k2a->entries, auth_request_t *, i); diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking-private.h b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking-private.h index f759c15..b64abc6 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking-private.h @@ -39,10 +39,10 @@ typedef struct { _mongocrypt_buffer_t key_id; bson_value_t key_alt_name; - }; + } fle1; mc_FLE2EncryptionPlaceholder_t fle2; - }; + } u; } _mongocrypt_marking_t; // `_mongocrypt_marking_t` inherits extended alignment from libbson. To dynamically allocate, use aligned allocation @@ -67,7 +67,6 @@ bool _mongocrypt_marking_to_ciphertext(void *ctx, mc_mincover_t *mc_get_mincover_from_FLE2RangeFindSpec(mc_FLE2RangeFindSpec_t *findSpec, size_t sparsity, - mongocrypt_status_t *status, - bool use_range_v2) MONGOCRYPT_WARN_UNUSED_RESULT; + mongocrypt_status_t *status) MONGOCRYPT_WARN_UNUSED_RESULT; #endif /* MONGOCRYPT_MARKING_PRIVATE_H */ diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking.c index 5002563..806b8b1 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking.c @@ -21,6 +21,7 @@ #include "mc-fle2-find-equality-payload-private.h" #include "mc-fle2-find-range-payload-private-v2.h" #include "mc-fle2-find-range-payload-private.h" +#include "mc-fle2-find-text-payload-private.h" #include "mc-fle2-insert-update-payload-private-v2.h" #include "mc-fle2-insert-update-payload-private.h" #include "mc-fle2-payload-uev-private.h" @@ -65,7 +66,7 @@ _mongocrypt_marking_parse_fle1_placeholder(const bson_t *in, _mongocrypt_marking BSON_ASSERT(field); if (0 == strcmp("ki", field)) { has_ki = true; - if (!_mongocrypt_buffer_from_uuid_iter(&out->key_id, &iter)) { + if (!_mongocrypt_buffer_from_uuid_iter(&out->u.fle1.key_id, &iter)) { CLIENT_ERR("key id must be a UUID"); return false; } @@ -85,14 +86,14 @@ _mongocrypt_marking_parse_fle1_placeholder(const bson_t *in, _mongocrypt_marking } /* CDRIVER-3100 We must make a copy of this value; the result of * bson_iter_value is ephemeral. */ - bson_value_copy(value, &out->key_alt_name); + bson_value_copy(value, &out->u.fle1.key_alt_name); out->type = MONGOCRYPT_MARKING_FLE1_BY_ALTNAME; continue; } if (0 == strcmp("v", field)) { has_v = true; - memcpy(&out->v_iter, &iter, sizeof(bson_iter_t)); + memcpy(&out->u.fle1.v_iter, &iter, sizeof(bson_iter_t)); continue; } @@ -110,7 +111,7 @@ _mongocrypt_marking_parse_fle1_placeholder(const bson_t *in, _mongocrypt_marking CLIENT_ERR("invalid algorithm value: %d", algorithm); return false; } - out->algorithm = (mongocrypt_encryption_algorithm_t)algorithm; + out->u.fle1.algorithm = (mongocrypt_encryption_algorithm_t)algorithm; continue; } @@ -147,7 +148,7 @@ _mongocrypt_marking_parse_fle2_placeholder(const bson_t *in, _mongocrypt_marking BSON_ASSERT_PARAM(out); out->type = MONGOCRYPT_MARKING_FLE2_ENCRYPTION; - return mc_FLE2EncryptionPlaceholder_parse(&out->fle2, in, status); + return mc_FLE2EncryptionPlaceholder_parse(&out->u.fle2, in, status); } bool _mongocrypt_marking_parse_unowned(const _mongocrypt_buffer_t *in, @@ -191,13 +192,13 @@ void _mongocrypt_marking_cleanup(_mongocrypt_marking_t *marking) { return; } if (marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION) { - mc_FLE2EncryptionPlaceholder_cleanup(&marking->fle2); + mc_FLE2EncryptionPlaceholder_cleanup(&marking->u.fle2); return; } // else FLE1 - _mongocrypt_buffer_cleanup(&marking->key_id); - bson_value_destroy(&marking->key_alt_name); + _mongocrypt_buffer_cleanup(&marking->u.fle1.key_id); + bson_value_destroy(&marking->u.fle1.key_alt_name); } /** @@ -278,7 +279,8 @@ DERIVE_TOKEN_IMPL(ESC) * Calculates: * E?CToken = HMAC(collectionLevel1Token, n) * E?CTextToken = HMAC(E?CToken, t) - * E?CTextDerivedFromDataTokenAndContentionFactorToken = HMAC(HMAC(E?CTextToken, v) cf) + * E?CTextDerivedFromDataToken = HMAC(E?CTextToken, v) + * E?CTextDerivedFromDataTokenAndContentionFactorToken = HMAC(E?CTextDerivedFromDataToken, cf) * * E?C = EDC|ESC * n = 1 for EDC, 2 for ESC @@ -286,7 +288,9 @@ DERIVE_TOKEN_IMPL(ESC) * t = 1 for Exact, 2 for Substring, 3 for Suffix, 4 for Prefix * cf = contentionFactor * - * E?CTextDerivedFromDataTokenAndContentionFactorToken is saved to out. + * If {useContentionFactor} is False, E?CTextDerivedFromDataToken is saved to out, and + * {contentionFactor} is ignored. + * Otherwise, E?CTextDerivedFromDataTokenAndContentionFactorToken is saved to out. * Note that {out} is initialized even on failure. */ #define DERIVE_TEXT_SEARCH_TOKEN_IMPL(Name, Type) \ @@ -294,13 +298,13 @@ DERIVE_TOKEN_IMPL(ESC) _mongocrypt_buffer_t *out, \ const mc_CollectionsLevel1Token_t *level1Token, \ const _mongocrypt_buffer_t *value, \ + bool useContentionFactor, \ int64_t contentionFactor, \ mongocrypt_status_t *status) { \ BSON_ASSERT_PARAM(crypto); \ BSON_ASSERT_PARAM(out); \ BSON_ASSERT_PARAM(level1Token); \ BSON_ASSERT_PARAM(value); \ - BSON_ASSERT(contentionFactor >= 0); \ \ _mongocrypt_buffer_init(out); \ \ @@ -313,13 +317,28 @@ DERIVE_TOKEN_IMPL(ESC) if (!textToken) { \ return false; \ } \ + mc_##Name##Text##Type##DerivedFromDataToken_t *fromDataToken = \ + mc_##Name##Text##Type##DerivedFromDataToken_new(crypto, textToken, value, status); \ + mc_##Name##Text##Type##Token_destroy(textToken); \ + if (!fromDataToken) { \ + return false; \ + } \ + \ + if (!useContentionFactor) { \ + /* FindTextPayload uses *fromDataToken */ \ + _mongocrypt_buffer_copy_to(mc_##Name##Text##Type##DerivedFromDataToken_get(fromDataToken), out); \ + mc_##Name##Text##Type##DerivedFromDataToken_destroy(fromDataToken); \ + return true; \ + } \ + \ + BSON_ASSERT(contentionFactor >= 0); \ + /* InsertUpdatePayload continues through *fromDataTokenAndContentionFactor */ \ mc_##Name##Text##Type##DerivedFromDataTokenAndContentionFactorToken_t *fromDataAndContentionFactor = \ mc_##Name##Text##Type##DerivedFromDataTokenAndContentionFactorToken_new(crypto, \ - textToken, \ - value, \ + fromDataToken, \ (uint64_t)contentionFactor, \ status); \ - mc_##Name##Text##Type##Token_destroy(textToken); \ + mc_##Name##Text##Type##DerivedFromDataToken_destroy(fromDataToken); \ if (!fromDataAndContentionFactor) { \ return false; \ } \ @@ -495,7 +514,7 @@ static bool _fle2_placeholder_aes_aead_encrypt(_mongocrypt_key_broker_t *kb, // Range V2: p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor || isLeaf) static bool _fle2_derive_encrypted_token(_mongocrypt_crypto_t *crypto, _mongocrypt_buffer_t *out, - bool use_range_v2, + bool concatentate_leaf, const mc_CollectionsLevel1Token_t *collectionsLevel1Token, const _mongocrypt_buffer_t *escDerivedToken, const _mongocrypt_buffer_t *eccDerivedToken, @@ -512,7 +531,7 @@ static bool _fle2_derive_encrypted_token(_mongocrypt_crypto_t *crypto, const _mongocrypt_buffer_t *p = &tmp; if (!eccDerivedToken) { // FLE2v2 - if (use_range_v2 && is_leaf.set) { + if (concatentate_leaf && is_leaf.set) { // Range V2; concat isLeaf _mongocrypt_buffer_t isLeafBuf; if (!_mongocrypt_buffer_copy_from_data_and_size(&isLeafBuf, (uint8_t[]){is_leaf.value}, 1)) { @@ -597,7 +616,7 @@ static bool _get_tokenKey(_mongocrypt_key_broker_t *kb, } if (indexKey.len != MONGOCRYPT_KEY_LEN) { - CLIENT_ERR("invalid indexKey, expected len=%" PRIu32 ", got len=%" PRIu32, MONGOCRYPT_KEY_LEN, indexKey.len); + CLIENT_ERR("invalid indexKey, expected len=%d, got len=%" PRIu32, MONGOCRYPT_KEY_LEN, indexKey.len); _mongocrypt_buffer_cleanup(&indexKey); return false; } @@ -737,7 +756,7 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_common(_mongocrypt_key if (!_fle2_derive_encrypted_token( crypto, &out->encryptedTokens, - kb->crypt->opts.use_range_v2, + true, common->collectionsLevel1Token, &out->escDerivedToken, NULL, // unused in v2 @@ -801,7 +820,7 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertext(_mongocrypt BSON_ASSERT(kb->crypt); BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION); - mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2; + mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->u.fle2; _FLE2EncryptedPayloadCommon_t common = {{0}}; mc_FLE2InsertUpdatePayloadV2_t payload; mc_FLE2InsertUpdatePayloadV2_init(&payload); @@ -837,8 +856,7 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertext(_mongocrypt // get_edges creates and returns edges from an FLE2RangeInsertSpec. Returns NULL // on error. -static mc_edges_t * -get_edges(mc_FLE2RangeInsertSpec_t *insertSpec, size_t sparsity, mongocrypt_status_t *status, bool use_range_v2) { +static mc_edges_t *get_edges(mc_FLE2RangeInsertSpec_t *insertSpec, size_t sparsity, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(insertSpec); bson_type_t value_type = bson_iter_type(&insertSpec->v); @@ -849,8 +867,7 @@ get_edges(mc_FLE2RangeInsertSpec_t *insertSpec, size_t sparsity, mongocrypt_stat .max = OPT_I32(bson_iter_int32(&insertSpec->max)), .sparsity = sparsity, .trimFactor = insertSpec->trimFactor}, - status, - use_range_v2); + status); } else if (value_type == BSON_TYPE_INT64) { @@ -859,8 +876,7 @@ get_edges(mc_FLE2RangeInsertSpec_t *insertSpec, size_t sparsity, mongocrypt_stat .max = OPT_I64(bson_iter_int64(&insertSpec->max)), .sparsity = sparsity, .trimFactor = insertSpec->trimFactor}, - status, - use_range_v2); + status); } else if (value_type == BSON_TYPE_DATE_TIME) { @@ -869,8 +885,7 @@ get_edges(mc_FLE2RangeInsertSpec_t *insertSpec, size_t sparsity, mongocrypt_stat .max = OPT_I64(bson_iter_date_time(&insertSpec->max)), .sparsity = sparsity, .trimFactor = insertSpec->trimFactor}, - status, - use_range_v2); + status); } else if (value_type == BSON_TYPE_DOUBLE) { @@ -886,11 +901,11 @@ get_edges(mc_FLE2RangeInsertSpec_t *insertSpec, size_t sparsity, mongocrypt_stat args.precision = insertSpec->precision; } - return mc_getEdgesDouble(args, status, use_range_v2); + return mc_getEdgesDouble(args, status); } else if (value_type == BSON_TYPE_DECIMAL128) { -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() const mc_dec128 value = mc_dec128_from_bson_iter(&insertSpec->v); mc_getEdgesDecimal128_args_t args = { .value = value, @@ -904,7 +919,7 @@ get_edges(mc_FLE2RangeInsertSpec_t *insertSpec, size_t sparsity, mongocrypt_stat args.max = OPT_MC_DEC128(max); args.precision = insertSpec->precision; } - return mc_getEdgesDecimal128(args, status, use_range_v2); + return mc_getEdgesDecimal128(args, status); #else // ↑↑↑↑↑↑↑↑ With Decimal128 / Without ↓↓↓↓↓↓↓↓↓↓ CLIENT_ERR("unsupported BSON type (Decimal128) for range: libmongocrypt " "was built without extended Decimal128 support"); @@ -936,9 +951,8 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(_mo BSON_ASSERT_PARAM(ciphertext); BSON_ASSERT(kb->crypt); BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION); - const bool use_range_v2 = kb->crypt->opts.use_range_v2; - mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2; + mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->u.fle2; _FLE2EncryptedPayloadCommon_t common = {{0}}; mc_FLE2InsertUpdatePayloadV2_t payload; mc_FLE2InsertUpdatePayloadV2_init(&payload); @@ -948,14 +962,14 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(_mo // Parse the value ("v"), min ("min"), and max ("max") from // FLE2EncryptionPlaceholder for range insert. mc_FLE2RangeInsertSpec_t insertSpec; - if (!mc_FLE2RangeInsertSpec_parse(&insertSpec, &placeholder->v_iter, use_range_v2, status)) { + if (!mc_FLE2RangeInsertSpec_parse(&insertSpec, &placeholder->v_iter, status)) { goto fail; } if (!_mongocrypt_fle2_placeholder_to_insert_update_common(kb, &payload, &common, - &marking->fle2, + &marking->u.fle2, &insertSpec.v, status)) { goto fail; @@ -964,7 +978,7 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(_mo // g:= array { BSON_ASSERT(placeholder->sparsity >= 0 && (uint64_t)placeholder->sparsity <= (uint64_t)SIZE_MAX); - edges = get_edges(&insertSpec, (size_t)placeholder->sparsity, status, kb->crypt->opts.use_range_v2); + edges = get_edges(&insertSpec, (size_t)placeholder->sparsity, status); if (!edges) { goto fail; } @@ -1007,7 +1021,7 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(_mo // Or in Range V2: p := EncryptCTR(ECOCToken, ESCDerivedFromDataTokenAndContentionFactor || isLeaf) if (!_fle2_derive_encrypted_token(kb->crypt->crypto, &etc.encryptedTokens, - kb->crypt->opts.use_range_v2, + true, edge_tokens.collectionsLevel1Token, &etc.escDerivedToken, NULL, // ecc unsed in FLE2v2 @@ -1039,7 +1053,7 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(_mo { bson_t out; bson_init(&out); - mc_FLE2InsertUpdatePayloadV2_serializeForRange(&payload, &out, use_range_v2); + mc_FLE2InsertUpdatePayloadV2_serializeForRange(&payload, &out); _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out); } // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are @@ -1087,6 +1101,7 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(_mo &out->edcDerivedToken, \ collLevel1Token, \ value, \ + true, \ contentionFactor, \ status)) { \ return false; \ @@ -1095,6 +1110,7 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(_mo &out->escDerivedToken, \ collLevel1Token, \ value, \ + true, \ contentionFactor, \ status)) { \ return false; \ @@ -1117,8 +1133,48 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(_mo return false; \ } \ return true; \ + } \ + static bool _fle2_generate_Text##Type##FindTokenSet( \ + _mongocrypt_key_broker_t *kb, \ + mc_Text##Type##FindTokenSet_t *out, \ + const _mongocrypt_buffer_t *value, \ + const mc_CollectionsLevel1Token_t *collLevel1Token, \ + const mc_ServerTokenDerivationLevel1Token_t *serverLevel1Token, \ + mongocrypt_status_t *status) { \ + BSON_ASSERT_PARAM(kb); \ + BSON_ASSERT_PARAM(kb->crypt); \ + BSON_ASSERT_PARAM(out); \ + BSON_ASSERT_PARAM(value); \ + BSON_ASSERT_PARAM(collLevel1Token); \ + BSON_ASSERT_PARAM(serverLevel1Token); \ + if (!_fle2_derive_EDCText##Type##_token(kb->crypt->crypto, \ + &out->edcDerivedToken, \ + collLevel1Token, \ + value, \ + false, \ + 0, \ + status)) { \ + return false; \ + } \ + if (!_fle2_derive_ESCText##Type##_token(kb->crypt->crypto, \ + &out->escDerivedToken, \ + collLevel1Token, \ + value, \ + false, \ + 0, \ + status)) { \ + return false; \ + } \ + if (!_fle2_derive_serverText##Type##DerivedFromDataToken(kb->crypt->crypto, \ + &out->serverDerivedFromDataToken, \ + serverLevel1Token, \ + value, \ + status)) { \ + return false; \ + } \ + return true; \ } -GENERATE_TEXT_SEARCH_TOKEN_SET_FOR_TYPE_IMPL(Exact); +GENERATE_TEXT_SEARCH_TOKEN_SET_FOR_TYPE_IMPL(Exact) GENERATE_TEXT_SEARCH_TOKEN_SET_FOR_TYPE_IMPL(Substring) GENERATE_TEXT_SEARCH_TOKEN_SET_FOR_TYPE_IMPL(Suffix) GENERATE_TEXT_SEARCH_TOKEN_SET_FOR_TYPE_IMPL(Prefix) @@ -1313,6 +1369,98 @@ static bool _fle2_generate_TextSearchTokenSets(_mongocrypt_key_broker_t *kb, return res; } +static bool _fle2_generate_TextSearchFindTokenSets(_mongocrypt_key_broker_t *kb, + mc_TextSearchFindTokenSets_t *out, + const _mongocrypt_buffer_t *indexKeyId, + const mc_FLE2TextSearchInsertSpec_t *spec, + mongocrypt_status_t *status) { + BSON_ASSERT_PARAM(kb); + BSON_ASSERT_PARAM(kb->crypt); + BSON_ASSERT_PARAM(out); + BSON_ASSERT_PARAM(indexKeyId); + BSON_ASSERT_PARAM(spec); + + _mongocrypt_crypto_t *crypto = kb->crypt->crypto; + _FLE2EncryptedPayloadCommon_t common = {{0}}; + _mongocrypt_buffer_t asBsonValue = {0}; + bool res = false; + + int operator_count = (int)spec->substr.set + (int)spec->suffix.set + (int)spec->prefix.set; + if (operator_count > 1) { + CLIENT_ERR("Text search query specification cannot contain multiple query type specifications"); + goto fail; + } + + if (!mc_text_search_str_query(spec, &asBsonValue, status)) { + goto fail; + } + + // Start the token derivations + if (!_get_tokenKey(kb, indexKeyId, &common.tokenKey, status)) { + goto fail; + } + + common.collectionsLevel1Token = mc_CollectionsLevel1Token_new(crypto, &common.tokenKey, status); + if (!common.collectionsLevel1Token) { + CLIENT_ERR("unable to derive collectionLevel1Token"); + goto fail; + } + + common.serverTokenDerivationLevel1Token = mc_ServerTokenDerivationLevel1Token_new(crypto, &common.tokenKey, status); + if (!common.serverTokenDerivationLevel1Token) { + CLIENT_ERR("unable to derive serverTokenDerivationLevel1Token"); + goto fail; + } + + if (spec->substr.set) { + if (!_fle2_generate_TextSubstringFindTokenSet(kb, + &out->substring.value, + &asBsonValue, + common.collectionsLevel1Token, + common.serverTokenDerivationLevel1Token, + status)) { + goto fail; + } + out->substring.set = true; + } else if (spec->suffix.set) { + if (!_fle2_generate_TextSuffixFindTokenSet(kb, + &out->suffix.value, + &asBsonValue, + common.collectionsLevel1Token, + common.serverTokenDerivationLevel1Token, + status)) { + goto fail; + } + out->suffix.set = true; + + } else if (spec->prefix.set) { + if (!_fle2_generate_TextPrefixFindTokenSet(kb, + &out->prefix.value, + &asBsonValue, + common.collectionsLevel1Token, + common.serverTokenDerivationLevel1Token, + status)) { + goto fail; + } + out->prefix.set = true; + } else { + if (!_fle2_generate_TextExactFindTokenSet(kb, + &out->exact.value, + &asBsonValue, + common.collectionsLevel1Token, + common.serverTokenDerivationLevel1Token, + status)) { + goto fail; + } + out->exact.set = true; + } + res = true; +fail: + _mongocrypt_buffer_cleanup(&asBsonValue); + _FLE2EncryptedPayloadCommon_cleanup(&common); + return res; +} + /** * Payload subtype 11: FLE2InsertUpdatePayloadV2 for text search inserts/updates * @@ -1335,7 +1483,7 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForTextSearc BSON_ASSERT(kb->crypt); BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION); - mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2; + mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->u.fle2; BSON_ASSERT(placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT); BSON_ASSERT(placeholder->algorithm == MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH); @@ -1351,6 +1499,12 @@ static bool _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForTextSearc goto fail; } + // One of substr/suffix/prefix must be set for inserts + if (!(insertSpec.substr.set || insertSpec.suffix.set || insertSpec.prefix.set)) { + CLIENT_ERR("FLE2TextSearchInsertSpec is missing a substring, suffix, or prefix index specification"); + goto fail; + } + // t payload.valueType = BSON_TYPE_UTF8; @@ -1468,7 +1622,7 @@ static bool _mongocrypt_fle2_placeholder_to_find_ciphertext(_mongocrypt_key_brok _FLE2EncryptedPayloadCommon_t common = {{0}}; _mongocrypt_buffer_t value = {0}; - mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2; + mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->u.fle2; mc_FLE2FindEqualityPayloadV2_t payload; bool res = false; @@ -1526,10 +1680,8 @@ static bool isInfinite(bson_iter_t *iter) { // mc_get_mincover_from_FLE2RangeFindSpec creates and returns a mincover from an // FLE2RangeFindSpec. Returns NULL on error. -mc_mincover_t *mc_get_mincover_from_FLE2RangeFindSpec(mc_FLE2RangeFindSpec_t *findSpec, - size_t sparsity, - mongocrypt_status_t *status, - bool use_range_v2) { +mc_mincover_t * +mc_get_mincover_from_FLE2RangeFindSpec(mc_FLE2RangeFindSpec_t *findSpec, size_t sparsity, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(findSpec); BSON_ASSERT(findSpec->edgesInfo.set); @@ -1590,8 +1742,7 @@ mc_mincover_t *mc_get_mincover_from_FLE2RangeFindSpec(mc_FLE2RangeFindSpec_t *fi .max = OPT_I32(bson_iter_int32(&findSpec->edgesInfo.value.indexMax)), .sparsity = sparsity, .trimFactor = findSpec->edgesInfo.value.trimFactor}, - status, - use_range_v2); + status); case BSON_TYPE_INT64: BSON_ASSERT(bson_iter_type(&lowerBound) == BSON_TYPE_INT64); @@ -1607,8 +1758,7 @@ mc_mincover_t *mc_get_mincover_from_FLE2RangeFindSpec(mc_FLE2RangeFindSpec_t *fi .max = OPT_I64(bson_iter_int64(&findSpec->edgesInfo.value.indexMax)), .sparsity = sparsity, .trimFactor = findSpec->edgesInfo.value.trimFactor}, - status, - use_range_v2); + status); case BSON_TYPE_DATE_TIME: BSON_ASSERT(bson_iter_type(&lowerBound) == BSON_TYPE_DATE_TIME); BSON_ASSERT(bson_iter_type(&upperBound) == BSON_TYPE_DATE_TIME); @@ -1623,8 +1773,7 @@ mc_mincover_t *mc_get_mincover_from_FLE2RangeFindSpec(mc_FLE2RangeFindSpec_t *fi .max = OPT_I64(bson_iter_date_time(&findSpec->edgesInfo.value.indexMax)), .sparsity = sparsity, .trimFactor = findSpec->edgesInfo.value.trimFactor}, - status, - use_range_v2); + status); case BSON_TYPE_DOUBLE: { BSON_ASSERT(bson_iter_type(&lowerBound) == BSON_TYPE_DOUBLE); BSON_ASSERT(bson_iter_type(&upperBound) == BSON_TYPE_DOUBLE); @@ -1645,10 +1794,10 @@ mc_mincover_t *mc_get_mincover_from_FLE2RangeFindSpec(mc_FLE2RangeFindSpec_t *fi args.max = OPT_DOUBLE(bson_iter_double(&findSpec->edgesInfo.value.indexMax)); args.precision = findSpec->edgesInfo.value.precision; } - return mc_getMincoverDouble(args, status, use_range_v2); + return mc_getMincoverDouble(args, status); } case BSON_TYPE_DECIMAL128: { -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() BSON_ASSERT(bson_iter_type(&lowerBound) == BSON_TYPE_DECIMAL128); BSON_ASSERT(bson_iter_type(&upperBound) == BSON_TYPE_DECIMAL128); BSON_ASSERT(bson_iter_type(&findSpec->edgesInfo.value.indexMin) == BSON_TYPE_DECIMAL128); @@ -1665,7 +1814,7 @@ mc_mincover_t *mc_get_mincover_from_FLE2RangeFindSpec(mc_FLE2RangeFindSpec_t *fi args.max = OPT_MC_DEC128(mc_dec128_from_bson_iter(&findSpec->edgesInfo.value.indexMax)); args.precision = findSpec->edgesInfo.value.precision; } - return mc_getMincoverDecimal128(args, status, use_range_v2); + return mc_getMincoverDecimal128(args, status); #else // ↑↑↑↑↑↑↑↑ With Decimal128 / Without ↓↓↓↓↓↓↓↓↓↓ CLIENT_ERR("FLE2 find is not supported for Decimal128: libmongocrypt " "was built without Decimal128 support"); @@ -1708,8 +1857,7 @@ static bool _mongocrypt_fle2_placeholder_to_find_ciphertextForRange(_mongocrypt_ BSON_ASSERT_PARAM(marking); BSON_ASSERT_PARAM(ciphertext); - const bool use_range_v2 = kb->crypt->opts.use_range_v2; - mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2; + mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->u.fle2; mc_FLE2FindRangePayloadV2_t payload; bool res = false; mc_mincover_t *mincover = NULL; @@ -1724,7 +1872,7 @@ static bool _mongocrypt_fle2_placeholder_to_find_ciphertextForRange(_mongocrypt_ // Parse the query bounds and index bounds from FLE2EncryptionPlaceholder for // range find. mc_FLE2RangeFindSpec_t findSpec; - if (!mc_FLE2RangeFindSpec_parse(&findSpec, &placeholder->v_iter, use_range_v2, status)) { + if (!mc_FLE2RangeFindSpec_parse(&findSpec, &placeholder->v_iter, status)) { goto fail; } @@ -1735,8 +1883,7 @@ static bool _mongocrypt_fle2_placeholder_to_find_ciphertextForRange(_mongocrypt_ // g:= array { BSON_ASSERT(placeholder->sparsity >= 0 && (uint64_t)placeholder->sparsity <= (uint64_t)SIZE_MAX); - mincover = - mc_get_mincover_from_FLE2RangeFindSpec(&findSpec, (size_t)placeholder->sparsity, status, use_range_v2); + mincover = mc_get_mincover_from_FLE2RangeFindSpec(&findSpec, (size_t)placeholder->sparsity, status); if (!mincover) { goto fail; } @@ -1785,14 +1932,12 @@ static bool _mongocrypt_fle2_placeholder_to_find_ciphertextForRange(_mongocrypt_ } payload.payload.set = true; - if (use_range_v2) { - // Include "range" payload fields introduced in SERVER-91889. - payload.sparsity = OPT_I64(placeholder->sparsity); - payload.precision = findSpec.edgesInfo.value.precision; - payload.trimFactor = OPT_I32(mc_mincover_get_used_trimFactor(mincover)); - bson_value_copy(bson_iter_value(&findSpec.edgesInfo.value.indexMin), &payload.indexMin); - bson_value_copy(bson_iter_value(&findSpec.edgesInfo.value.indexMax), &payload.indexMax); - } + // Include "range" payload fields introduced in SERVER-91889. + payload.sparsity = OPT_I64(placeholder->sparsity); + payload.precision = findSpec.edgesInfo.value.precision; + payload.trimFactor = OPT_I32(mc_mincover_get_used_trimFactor(mincover)); + bson_value_copy(bson_iter_value(&findSpec.edgesInfo.value.indexMin), &payload.indexMin); + bson_value_copy(bson_iter_value(&findSpec.edgesInfo.value.indexMax), &payload.indexMax); } payload.payloadId = findSpec.payloadId; @@ -1802,7 +1947,7 @@ static bool _mongocrypt_fle2_placeholder_to_find_ciphertextForRange(_mongocrypt_ // Serialize. { bson_t out = BSON_INITIALIZER; - mc_FLE2FindRangePayloadV2_serialize(&payload, &out, use_range_v2); + mc_FLE2FindRangePayloadV2_serialize(&payload, &out); _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out); } _mongocrypt_buffer_steal(&ciphertext->key_id, &placeholder->index_key_id); @@ -1824,9 +1969,59 @@ static bool _mongocrypt_fle2_placeholder_to_find_ciphertextForTextSearch(_mongoc _mongocrypt_marking_t *marking, _mongocrypt_ciphertext_t *ciphertext, mongocrypt_status_t *status) { - // TODO MONGOCRYPT-761 implement find support for text search fields - CLIENT_ERR("Text search find is not yet supported"); - return false; + BSON_ASSERT_PARAM(kb); + BSON_ASSERT_PARAM(marking); + BSON_ASSERT_PARAM(ciphertext); + BSON_ASSERT(kb->crypt); + BSON_ASSERT(marking->type == MONGOCRYPT_MARKING_FLE2_ENCRYPTION); + + bool res = false; + mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->u.fle2; + BSON_ASSERT(placeholder->type == MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND); + BSON_ASSERT(placeholder->algorithm == MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH); + + mc_FLE2FindTextPayload_t payload; + mc_FLE2FindTextPayload_init(&payload); + + mc_FLE2TextSearchInsertSpec_t spec; + if (!mc_FLE2TextSearchInsertSpec_parse(&spec, &placeholder->v_iter, status)) { + goto fail; + } + + if (!_fle2_generate_TextSearchFindTokenSets(kb, &payload.tokenSets, &placeholder->index_key_id, &spec, status)) { + goto fail; + } + + payload.caseFold = spec.casef; + payload.diacriticFold = spec.diacf; + payload.maxContentionFactor = placeholder->maxContentionFactor; + if (spec.substr.set) { + payload.substringSpec.set = true; + payload.substringSpec.value = spec.substr.value; + } else if (spec.suffix.set) { + payload.suffixSpec.set = true; + payload.suffixSpec.value = spec.suffix.value; + } else if (spec.prefix.set) { + payload.prefixSpec.set = true; + payload.prefixSpec.value = spec.prefix.value; + } + + // Serialize. + { + bson_t out = BSON_INITIALIZER; + mc_FLE2FindTextPayload_serialize(&payload, &out); + _mongocrypt_buffer_steal_from_bson(&ciphertext->data, &out); + } + + // Do not set ciphertext->original_bson_type and ciphertext->key_id. They are + // not used for FLE2FindTextPayload. + ciphertext->blob_subtype = MC_SUBTYPE_FLE2FindTextPayload; + + res = true; + +fail: + mc_FLE2FindTextPayload_cleanup(&payload); + return res; } static bool _mongocrypt_fle2_placeholder_to_FLE2UnindexedEncryptedValue(_mongocrypt_key_broker_t *kb, @@ -1838,7 +2033,7 @@ static bool _mongocrypt_fle2_placeholder_to_FLE2UnindexedEncryptedValue(_mongocr BSON_ASSERT_PARAM(ciphertext); _mongocrypt_buffer_t plaintext = {0}; - mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->fle2; + mc_FLE2EncryptionPlaceholder_t *placeholder = &marking->u.fle2; _mongocrypt_buffer_t user_key = {0}; bool res = false; @@ -1904,12 +2099,13 @@ static bool _mongocrypt_fle1_marking_to_ciphertext(_mongocrypt_key_broker_t *kb, _mongocrypt_buffer_init(&key_id); _mongocrypt_buffer_init(&key_material); - /* Get the decrypted key for this marking. */ + /* Get the decrypted key for this marking.u.fle1. */ if (marking->type == MONGOCRYPT_MARKING_FLE1_BY_ALTNAME) { - key_found = _mongocrypt_key_broker_decrypted_key_by_name(kb, &marking->key_alt_name, &key_material, &key_id); - } else if (!_mongocrypt_buffer_empty(&marking->key_id)) { - key_found = _mongocrypt_key_broker_decrypted_key_by_id(kb, &marking->key_id, &key_material); - _mongocrypt_buffer_copy_to(&marking->key_id, &key_id); + key_found = + _mongocrypt_key_broker_decrypted_key_by_name(kb, &marking->u.fle1.key_alt_name, &key_material, &key_id); + } else if (!_mongocrypt_buffer_empty(&marking->u.fle1.key_id)) { + key_found = _mongocrypt_key_broker_decrypted_key_by_id(kb, &marking->u.fle1.key_id, &key_material); + _mongocrypt_buffer_copy_to(&marking->u.fle1.key_id, &key_id); } else { CLIENT_ERR("marking must have either key_id or key_alt_name"); goto fail; @@ -1920,11 +2116,11 @@ static bool _mongocrypt_fle1_marking_to_ciphertext(_mongocrypt_key_broker_t *kb, goto fail; } - ciphertext->original_bson_type = (uint8_t)bson_iter_type(&marking->v_iter); - if (marking->algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC) { + ciphertext->original_bson_type = (uint8_t)bson_iter_type(&marking->u.fle1.v_iter); + if (marking->u.fle1.algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC) { ciphertext->blob_subtype = MC_SUBTYPE_FLE1DeterministicEncryptedValue; } else { - BSON_ASSERT(marking->algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM); + BSON_ASSERT(marking->u.fle1.algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM); ciphertext->blob_subtype = MC_SUBTYPE_FLE1RandomEncryptedValue; } _mongocrypt_buffer_copy_to(&key_id, &ciphertext->key_id); @@ -1933,7 +2129,7 @@ static bool _mongocrypt_fle1_marking_to_ciphertext(_mongocrypt_key_broker_t *kb, goto fail; } - _mongocrypt_buffer_from_iter(&plaintext, &marking->v_iter); + _mongocrypt_buffer_from_iter(&plaintext, &marking->u.fle1.v_iter); ciphertext->data.len = fle1->get_ciphertext_len(plaintext.len, status); if (ciphertext->data.len == 0) { goto fail; @@ -1944,7 +2140,7 @@ static bool _mongocrypt_fle1_marking_to_ciphertext(_mongocrypt_key_broker_t *kb, ciphertext->data.owned = true; BSON_ASSERT(kb->crypt); - switch (marking->algorithm) { + switch (marking->u.fle1.algorithm) { case MONGOCRYPT_ENCRYPTION_ALGORITHM_DETERMINISTIC: /* Use deterministic encryption. */ _mongocrypt_buffer_resize(&iv, MONGOCRYPT_IV_LEN); @@ -2019,11 +2215,11 @@ bool _mongocrypt_marking_to_ciphertext(void *ctx, switch (marking->type) { case MONGOCRYPT_MARKING_FLE2_ENCRYPTION: - switch (marking->fle2.algorithm) { + switch (marking->u.fle2.algorithm) { case MONGOCRYPT_FLE2_ALGORITHM_UNINDEXED: return _mongocrypt_fle2_placeholder_to_FLE2UnindexedEncryptedValue(kb, marking, ciphertext, status); case MONGOCRYPT_FLE2_ALGORITHM_RANGE: - switch (marking->fle2.type) { + switch (marking->u.fle2.type) { case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT: return _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForRange(kb, marking, @@ -2031,18 +2227,18 @@ bool _mongocrypt_marking_to_ciphertext(void *ctx, status); case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND: return _mongocrypt_fle2_placeholder_to_find_ciphertextForRange(kb, marking, ciphertext, status); - default: CLIENT_ERR("unexpected fle2 type: %d", (int)marking->fle2.type); return false; + default: CLIENT_ERR("unexpected fle2 type: %d", (int)marking->u.fle2.type); return false; } case MONGOCRYPT_FLE2_ALGORITHM_EQUALITY: - switch (marking->fle2.type) { + switch (marking->u.fle2.type) { case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT: return _mongocrypt_fle2_placeholder_to_insert_update_ciphertext(kb, marking, ciphertext, status); case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND: return _mongocrypt_fle2_placeholder_to_find_ciphertext(kb, marking, ciphertext, status); - default: CLIENT_ERR("unexpected fle2 type: %d", (int)marking->fle2.type); return false; + default: CLIENT_ERR("unexpected fle2 type: %d", (int)marking->u.fle2.type); return false; } case MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH: - switch (marking->fle2.type) { + switch (marking->u.fle2.type) { case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT: return _mongocrypt_fle2_placeholder_to_insert_update_ciphertextForTextSearch(kb, marking, @@ -2050,9 +2246,9 @@ bool _mongocrypt_marking_to_ciphertext(void *ctx, status); case MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND: return _mongocrypt_fle2_placeholder_to_find_ciphertextForTextSearch(kb, marking, ciphertext, status); - default: CLIENT_ERR("unexpected fle2 type: %d", (int)marking->fle2.type); return false; + default: CLIENT_ERR("unexpected fle2 type: %d", (int)marking->u.fle2.type); return false; } - default: CLIENT_ERR("unexpected algorithm: %d", (int)marking->algorithm); return false; + default: CLIENT_ERR("unexpected algorithm: %d", (int)marking->u.fle1.algorithm); return false; } case MONGOCRYPT_MARKING_FLE1_BY_ID: case MONGOCRYPT_MARKING_FLE1_BY_ALTNAME: diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts-private.h b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts-private.h index d76f2fd..99de4e5 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts-private.h @@ -118,8 +118,6 @@ typedef struct { bool use_need_mongo_collinfo_with_db_state; bool bypass_query_analysis; - // Use the Queryable Encryption Range V2 protocol. - bool use_range_v2; } _mongocrypt_opts_t; void _mongocrypt_opts_kms_providers_cleanup(_mongocrypt_opts_kms_providers_t *kms_providers); diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts.c index 7f82362..43d6c49 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts.c @@ -35,7 +35,6 @@ void _mongocrypt_opts_kms_providers_init(_mongocrypt_opts_kms_providers_t *kms_p void _mongocrypt_opts_init(_mongocrypt_opts_t *opts) { BSON_ASSERT_PARAM(opts); memset(opts, 0, sizeof(*opts)); - opts->use_range_v2 = true; _mongocrypt_opts_kms_providers_init(&opts->kms_providers); } diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-private.h b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-private.h index 0ac9f8a..4785e7e 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-private.h +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-private.h @@ -39,7 +39,7 @@ #define CLIENT_ERR_W_CODE(code, ...) _mongocrypt_set_error(status, MONGOCRYPT_STATUS_ERROR_CLIENT, code, __VA_ARGS__) -#define CLIENT_ERR(fmt, ...) CLIENT_ERR_W_CODE(MONGOCRYPT_GENERIC_ERROR_CODE, fmt, ##__VA_ARGS__) +#define CLIENT_ERR(...) CLIENT_ERR_W_CODE(MONGOCRYPT_GENERIC_ERROR_CODE, __VA_ARGS__) #define KMS_ERR_W_CODE(code, ...) _mongocrypt_set_error(status, MONGOCRYPT_STATUS_ERROR_KMS, code, __VA_ARGS__) diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-util.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-util.c index 1abdc6f..880eea0 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt-util.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt-util.c @@ -33,6 +33,7 @@ #endif #include "mc-check-conversions-private.h" +#include "mongocrypt-dll-private.h" #include "mongocrypt-private.h" // CLIENT_ERR #include "mongocrypt-util-private.h" @@ -62,7 +63,7 @@ current_module_result current_module_path(void) { int ret_error = 0; #ifdef _WIN32 DWORD acc_size = 512; - while (!ret_str.data && !ret_error) { + while (!ret_str.raw.data && !ret_error) { // Loop until we allocate a large enough buffer or get an error wchar_t *path = calloc(acc_size + 1, sizeof(wchar_t)); SetLastError(0); @@ -84,7 +85,9 @@ current_module_result current_module_path(void) { // Darwin/BSD/glibc define extensions for finding dynamic library info from // the address of a symbol. Dl_info info = {0}; + MC_BEGIN_CAST_FUNCTION_TYPE_STRICT_IGNORE int rc = dladdr((const void *)current_module_path, &info); + MC_END_CAST_FUNCTION_TYPE_STRICT_IGNORE if (rc == 0) { // Failed to resolve the symbol ret_error = ENOENT; diff --git a/ext/libmongocrypt/libmongocrypt/src/mongocrypt.c b/ext/libmongocrypt/libmongocrypt/src/mongocrypt.c index 6e3ae05..7f6df75 100644 --- a/ext/libmongocrypt/libmongocrypt/src/mongocrypt.c +++ b/ext/libmongocrypt/libmongocrypt/src/mongocrypt.c @@ -28,6 +28,7 @@ #include "mongocrypt-cache-private.h" #include "mongocrypt-config.h" #include "mongocrypt-crypto-private.h" +#include "mongocrypt-dll-private.h" #include "mongocrypt-log-private.h" #include "mongocrypt-mutex-private.h" #include "mongocrypt-opts-private.h" @@ -136,7 +137,7 @@ mongocrypt_t *mongocrypt_new(void) { } #define ASSERT_MONGOCRYPT_PARAM_UNINIT(crypt) \ - { \ + if (1) { \ const mongocrypt_t *_crypt = (crypt); \ BSON_ASSERT_PARAM(_crypt); \ if (_crypt->initialized) { \ @@ -144,7 +145,8 @@ mongocrypt_t *mongocrypt_new(void) { CLIENT_ERR("options cannot be set after initialization"); \ return false; \ } \ - } + } else \ + ((void)0) bool mongocrypt_setopt_use_range_v2(mongocrypt_t *crypt) { ASSERT_MONGOCRYPT_PARAM_UNINIT(crypt); @@ -391,14 +393,16 @@ static _loaded_csfle _try_load_csfle(const char *filepath, mongocrypt_status_t * // Try to open the dynamic lib mcr_dll lib = mcr_dll_open(filepath); // Check for errors, which are represented by strings - if (lib.error_string.data) { + if (lib.error_string.raw.data) { // Error opening candidate _mongocrypt_log(log, MONGOCRYPT_LOG_LEVEL_WARNING, - "Error while opening candidate for CSFLE dynamic library [%s]: %s", + "Error while opening candidate for crypt_shared dynamic library [%s]: %s", filepath, - lib.error_string.data); - CLIENT_ERR("Error while opening candidate for CSFLE dynamic library [%s]: %s", filepath, lib.error_string.data); + lib.error_string.raw.data); + CLIENT_ERR("Error while opening candidate for crypt_shared dynamic library [%s]: %s", + filepath, + lib.error_string.raw.data); // Free resources, which will include the error string mcr_dll_close(lib); // Bad: @@ -406,7 +410,7 @@ static _loaded_csfle _try_load_csfle(const char *filepath, mongocrypt_status_t * } // Successfully opened DLL - _mongocrypt_log(log, MONGOCRYPT_LOG_LEVEL_TRACE, "Loading CSFLE dynamic library [%s]", filepath); + _mongocrypt_log(log, MONGOCRYPT_LOG_LEVEL_TRACE, "Loading crypt_shared dynamic library [%s]", filepath); // Construct the library vtable _mongo_crypt_v1_vtable vtable = {.okay = true}; @@ -414,12 +418,14 @@ static _loaded_csfle _try_load_csfle(const char *filepath, mongocrypt_status_t * { \ /* Symbol names are qualified by the lib name and version: */ \ const char *symname = "mongo_crypt_v1_" #Name; \ - vtable.Name = mcr_dll_sym(lib, symname); \ + MC_BEGIN_CAST_FUNCTION_TYPE_STRICT_IGNORE \ + vtable.Name = (RetType(*)(__VA_ARGS__))mcr_dll_sym(lib, symname); \ + MC_END_CAST_FUNCTION_TYPE_STRICT_IGNORE \ if (vtable.Name == NULL) { \ /* The requested symbol is not present */ \ _mongocrypt_log(log, \ MONGOCRYPT_LOG_LEVEL_ERROR, \ - "Missing required symbol '%s' from CSFLE dynamic library [%s]", \ + "Missing required symbol '%s' from crypt_shared dynamic library [%s]", \ symname, \ filepath); \ /* Mark the vtable as broken, but keep trying to load more symbols to \ @@ -431,17 +437,27 @@ static _loaded_csfle _try_load_csfle(const char *filepath, mongocrypt_status_t * #undef X_FUNC if (!vtable.okay) { + // A common mistake is to pass the path to libmongocrypt instead of than crypt_shared. + // Check if the library has a libmongocrypt symbol. + if (mcr_dll_sym(lib, "mongocrypt_version")) { + CLIENT_ERR("Tried to load crypt_shared dynamic library at path [%s] but detected libmongocrypt", filepath); + mcr_dll_close(lib); + return (_loaded_csfle){.okay = false}; + } mcr_dll_close(lib); _mongocrypt_log(log, MONGOCRYPT_LOG_LEVEL_ERROR, - "One or more required symbols are missing from CSFLE dynamic library " + "One or more required symbols are missing from crypt_shared dynamic library " "[%s], so this dynamic library will not be used.", filepath); + CLIENT_ERR("One or more required symbols are missing from crypt_shared dynamic library " + "[%s], so this dynamic library will not be used.", + filepath); return (_loaded_csfle){.okay = false}; } // Success! - _mongocrypt_log(log, MONGOCRYPT_LOG_LEVEL_INFO, "Opened CSFLE dynamic library [%s]", filepath); + _mongocrypt_log(log, MONGOCRYPT_LOG_LEVEL_INFO, "Opened crypt_shared dynamic library [%s]", filepath); return (_loaded_csfle){.okay = true, .lib = lib, .vtable = vtable}; } @@ -462,7 +478,7 @@ static bool _try_replace_dollar_origin(mstr *filepath, _mongocrypt_log_t *log) { return true; } // Check that the next char is a path separator or end-of-string: - char peek = filepath->data[dollar_origin.len]; + char peek = filepath->raw.data[dollar_origin.len]; if (peek != 0 && !mpath_is_sep(peek, MPATH_NATIVE)) { // Not a single path element return true; @@ -475,9 +491,9 @@ static bool _try_replace_dollar_origin(mstr *filepath, _mongocrypt_log_t *log) { _mongocrypt_log(log, MONGOCRYPT_LOG_LEVEL_WARNING, "Error while loading the executable module path for " - "substitution of $ORIGIN in CSFLE search path [%s]: %s", - filepath->data, - error.data); + "substitution of $ORIGIN in crypt_shared search path [%s]: %s", + filepath->raw.data, + error.raw.data); mstr_free(error); return false; } @@ -493,7 +509,7 @@ static _loaded_csfle _try_find_csfle(mongocrypt_t *crypt) { BSON_ASSERT_PARAM(crypt); - if (crypt->opts.crypt_shared_lib_override_path.data) { + if (crypt->opts.crypt_shared_lib_override_path.raw.data) { // If an override path was specified, skip the library searching behavior csfle_cand_filepath = mstr_copy(crypt->opts.crypt_shared_lib_override_path.view); if (_try_replace_dollar_origin(&csfle_cand_filepath, &crypt->log)) { @@ -501,7 +517,7 @@ static _loaded_csfle _try_find_csfle(mongocrypt_t *crypt) { // Do not allow a plain filename to go through, as that will cause the // DLL load to search the system. mstr_assign(&csfle_cand_filepath, mpath_absolute(csfle_cand_filepath.view, MPATH_NATIVE)); - candidate_csfle = _try_load_csfle(csfle_cand_filepath.data, crypt->status, &crypt->log); + candidate_csfle = _try_load_csfle(csfle_cand_filepath.raw.data, crypt->status, &crypt->log); } } else { // No override path was specified, so try to find it on the provided @@ -523,7 +539,7 @@ static _loaded_csfle _try_find_csfle(mongocrypt_t *crypt) { } } // Try to load the file: - candidate_csfle = _try_load_csfle(csfle_cand_filepath.data, NULL /* status */, &crypt->log); + candidate_csfle = _try_load_csfle(csfle_cand_filepath.raw.data, NULL /* status */, &crypt->log); if (candidate_csfle.okay) { // Stop searching: break; @@ -548,13 +564,13 @@ typedef struct csfle_global_lib_state { mongo_crypt_v1_lib *csfle_lib; } csfle_global_lib_state; -csfle_global_lib_state g_csfle_state; +static csfle_global_lib_state g_csfle_state; static void init_csfle_state(void) { _mongocrypt_mutex_init(&g_csfle_state.mtx); } -mlib_once_flag g_csfle_init_flag = MLIB_ONCE_INITIALIZER; +static mlib_once_flag g_csfle_init_flag = MLIB_ONCE_INITIALIZER; /** * @brief Verify that `found` refers to the same library that is globally loaded @@ -586,12 +602,12 @@ static bool _validate_csfle_singleton(mongocrypt_t *crypt, _loaded_csfle found) // Path to the existing loaded csfle: mcr_dll_path_result existing_path_ = mcr_dll_path(g_csfle_state.dll); - assert(existing_path_.path.data && "Failed to get path to already-loaded csfle library"); + assert(existing_path_.path.raw.data && "Failed to get path to already-loaded csfle library"); mstr_view existing_path = existing_path_.path.view; bool okay = true; if (!found.okay) { // There is one loaded, but we failed to find that same library. Error: - CLIENT_ERR("An existing CSFLE library is loaded by the application at " + CLIENT_ERR("An existing crypt_shared library is loaded by the application at " "[%s], but the current call to mongocrypt_init() failed to " "find that same library.", existing_path.data); @@ -599,17 +615,17 @@ static bool _validate_csfle_singleton(mongocrypt_t *crypt, _loaded_csfle found) } else { // Get the path to what we found: mcr_dll_path_result found_path = mcr_dll_path(found.lib); - assert(found_path.path.data + assert(found_path.path.raw.data && "Failed to get the dynamic library filepath of the library that " "was loaded for csfle"); if (!mstr_eq(found_path.path.view, existing_path)) { // Our find-result should only ever find the existing same library. // Error: - CLIENT_ERR("An existing CSFLE library is loaded by the application at [%s], " + CLIENT_ERR("An existing crypt_shared library is loaded by the application at [%s], " "but the current call to mongocrypt_init() attempted to load a " - "second CSFLE library from [%s]. This is not allowed.", + "second crypt_shared library from [%s]. This is not allowed.", existing_path.data, - found_path.path.data); + found_path.path.raw.data); okay = false; } mstr_free(found_path.path); @@ -784,7 +800,7 @@ static bool _csfle_replace_or_take_validate_singleton(mongocrypt_t *crypt, _load have_csfle = true; break; case LIB_CREATE_FAILED: - if (!message.data) { + if (!message.raw.data) { // We failed to obtain a message about the failure _mongocrypt_set_error(crypt->status, MONGOCRYPT_STATUS_ERROR_CRYPT_SHARED, @@ -796,7 +812,7 @@ static bool _csfle_replace_or_take_validate_singleton(mongocrypt_t *crypt, _load MONGOCRYPT_STATUS_ERROR_CRYPT_SHARED, MONGOCRYPT_GENERIC_ERROR_CODE, "csfle lib_create() failed: %s [Error %d, code %d]", - message.data, + message.raw.data, err, code); } @@ -823,7 +839,7 @@ static bool _wants_csfle(mongocrypt_t *c) { if (c->opts.bypass_query_analysis) { return false; } - return c->opts.n_crypt_shared_lib_search_paths != 0 || c->opts.crypt_shared_lib_override_path.data != NULL; + return c->opts.n_crypt_shared_lib_search_paths != 0 || c->opts.crypt_shared_lib_override_path.raw.data != NULL; } /** @@ -849,11 +865,11 @@ static bool _try_enable_csfle(mongocrypt_t *crypt) { // If a crypt_shared override path was specified, but we did not succeed in // loading crypt_shared, that is a hard-error. - if (crypt->opts.crypt_shared_lib_override_path.data && !found.okay) { + if (crypt->opts.crypt_shared_lib_override_path.raw.data && !found.okay) { // Wrap error with additional information. CLIENT_ERR("A crypt_shared override path was specified [%s], but we failed to open a dynamic " "library at that location. Load error: [%s]", - crypt->opts.crypt_shared_lib_override_path.data, + crypt->opts.crypt_shared_lib_override_path.raw.data, mongocrypt_status_message(crypt->status, NULL /* len */)); return false; } diff --git a/ext/libmongocrypt/libmongocrypt/src/os_posix/os_dll.c b/ext/libmongocrypt/libmongocrypt/src/os_posix/os_dll.c index 09a2062..eb68c22 100644 --- a/ext/libmongocrypt/libmongocrypt/src/os_posix/os_dll.c +++ b/ext/libmongocrypt/libmongocrypt/src/os_posix/os_dll.c @@ -43,6 +43,8 @@ mcr_dll mcr_dll_open(const char *filepath) { } } +void mcr_dll_close_handle(mcr_dll); // -Wmissing-prototypes: not for external use despite external linkage. + void mcr_dll_close_handle(mcr_dll dll) { if (dll._native_handle) { dlclose(dll._native_handle); diff --git a/ext/libmongocrypt/libmongocrypt/src/os_posix/os_mutex.c b/ext/libmongocrypt/libmongocrypt/src/os_posix/os_mutex.c index a286150..3353a15 100644 --- a/ext/libmongocrypt/libmongocrypt/src/os_posix/os_mutex.c +++ b/ext/libmongocrypt/libmongocrypt/src/os_posix/os_mutex.c @@ -46,4 +46,4 @@ void _mongocrypt_mutex_unlock(mongocrypt_mutex_t *mutex) { } } -#endif /* _WIN32 */ \ No newline at end of file +#endif /* _WIN32 */ diff --git a/ext/libmongocrypt/libmongocrypt/src/os_win/os_dll.c b/ext/libmongocrypt/libmongocrypt/src/os_win/os_dll.c index e6e4f1b..6e9c916 100644 --- a/ext/libmongocrypt/libmongocrypt/src/os_win/os_dll.c +++ b/ext/libmongocrypt/libmongocrypt/src/os_win/os_dll.c @@ -36,6 +36,8 @@ mcr_dll mcr_dll_open(const char *filepath_) { return (mcr_dll){.error_string = NULL, ._native_handle = lib}; } +void mcr_dll_close_handle(mcr_dll); // -Wmissing-prototypes: not for external use despite external linkage. + void mcr_dll_close_handle(mcr_dll dll) { if (dll._native_handle) { FreeLibrary(dll._native_handle); @@ -50,7 +52,7 @@ mcr_dll_path_result mcr_dll_path(mcr_dll dll) { mstr ret_str = MSTR_NULL; int ret_error = 0; DWORD acc_size = 512; - while (!ret_str.data && !ret_error) { + while (!ret_str.raw.data && !ret_error) { // Loop until we allocate a large enough buffer or get an error wchar_t *path = calloc((size_t)acc_size + 1u, sizeof(wchar_t)); SetLastError(0); diff --git a/ext/libmongocrypt/libmongocrypt/src/os_win/os_mutex.c b/ext/libmongocrypt/libmongocrypt/src/os_win/os_mutex.c index dc7be36..31eb790 100644 --- a/ext/libmongocrypt/libmongocrypt/src/os_win/os_mutex.c +++ b/ext/libmongocrypt/libmongocrypt/src/os_win/os_mutex.c @@ -34,4 +34,4 @@ void _mongocrypt_mutex_unlock(mongocrypt_mutex_t *mutex) { LeaveCriticalSection(mutex); } -#endif /* _WIN32 */ \ No newline at end of file +#endif /* _WIN32 */ diff --git a/ext/libmongocrypt/libmongocrypt/src/unicode/case-fold-map.c b/ext/libmongocrypt/libmongocrypt/src/unicode/case-fold-map.c index 67549f6..b0ec96c 100644 --- a/ext/libmongocrypt/libmongocrypt/src/unicode/case-fold-map.c +++ b/ext/libmongocrypt/libmongocrypt/src/unicode/case-fold-map.c @@ -1431,4 +1431,4 @@ bson_unichar_t unicode_codepoint_to_lower(bson_unichar_t codepoint) { case 0x1e921: return 0x1e943; default: return codepoint; } -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/src/unicode/diacritic-fold-map.c b/ext/libmongocrypt/libmongocrypt/src/unicode/diacritic-fold-map.c index e78ca26..d055369 100644 --- a/ext/libmongocrypt/libmongocrypt/src/unicode/diacritic-fold-map.c +++ b/ext/libmongocrypt/libmongocrypt/src/unicode/diacritic-fold-map.c @@ -2881,4 +2881,4 @@ bson_unichar_t unicode_codepoint_remove_diacritics(bson_unichar_t codepoint) { case 0x2fa1d: return 0x2a600; default: return codepoint; } -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/src/unicode/fold.c b/ext/libmongocrypt/libmongocrypt/src/unicode/fold.c index 2239108..572dad0 100644 --- a/ext/libmongocrypt/libmongocrypt/src/unicode/fold.c +++ b/ext/libmongocrypt/libmongocrypt/src/unicode/fold.c @@ -136,4 +136,4 @@ bool unicode_fold(const char *str, *output_it = '\0'; *out_len = (size_t)(output_it - *out_str); return true; -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/test/crypt_shared-stub.cpp b/ext/libmongocrypt/libmongocrypt/test/crypt_shared-stub.cpp index 037d75f..59175b3 100644 --- a/ext/libmongocrypt/libmongocrypt/test/crypt_shared-stub.cpp +++ b/ext/libmongocrypt/libmongocrypt/test/crypt_shared-stub.cpp @@ -7,12 +7,6 @@ * libmongocrypt. */ -#ifdef _WIN32 -#define EXPORT_API __declspec(dllexport) -#else -#define EXPORT_API __attribute__((visibility("default"))) -#endif - #define MONGO_CRYPT_SUPPORT_COMPILING #include @@ -22,14 +16,6 @@ #include #include -#ifdef _WIN32 -#define MONGO_API_CALL __cdecl -#define MONGO_API_EXPORT __declspec(dllexport) -#else -#define MONGO_API_CALL [[]] -#define MONGO_API_EXPORT __attribute__((used, visibility("default"))) -#endif - struct mongo_crypt_v1_status {}; typedef mongo_crypt_v1_status status_t; diff --git a/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-payload.json deleted file mode 100644 index e2f16d3..0000000 --- a/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-payload.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "cleanupStructuredEncryptionData": "test", - "cleanupTokens": { - "rangeField": { - "$binary": { - "base64": "27J6DZqcjkRzZ3lWEsxH7CsQHr4CZirrGmuPS8ZkRO0=", - "subType": "00" - } - }, - "nested.notindexed": { - "$binary": { - "base64": "27J6DZqcjkRzZ3lWEsxH7CsQHr4CZirrGmuPS8ZkRO0=", - "subType": "00" - } - }, - "nested.encrypted": { - "$binary": { - "base64": "SWO8WEoZ2r2Kx/muQKb7+COizy85nIIUFiHh4K9kcvA=", - "subType": "00" - } - }, - "encrypted": { - "$binary": { - "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", - "subType": "00" - } - } - } -} \ No newline at end of file diff --git a/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-field-config-map.json b/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-field-config-map.json index ef03753..58ffe8f 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-field-config-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-field-config-map.json @@ -49,7 +49,12 @@ } }, "path": "rangeField", - "bsonType": "int" + "bsonType": "int", + "queries": { + "queryType": "range", + "contention": 0, + "sparsity": 1 + } } ] } diff --git a/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-payload.json deleted file mode 100644 index 7093253..0000000 --- a/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-payload.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compactStructuredEncryptionData": "test", - "compactionTokens": { - "rangeField": { - "$binary": { - "base64": "27J6DZqcjkRzZ3lWEsxH7CsQHr4CZirrGmuPS8ZkRO0=", - "subType": "00" - } - }, - "nested.notindexed": { - "$binary": { - "base64": "27J6DZqcjkRzZ3lWEsxH7CsQHr4CZirrGmuPS8ZkRO0=", - "subType": "00" - } - }, - "nested.encrypted": { - "$binary": { - "base64": "SWO8WEoZ2r2Kx/muQKb7+COizy85nIIUFiHh4K9kcvA=", - "subType": "00" - } - }, - "encrypted": { - "$binary": { - "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", - "subType": "00" - } - } - } -} \ No newline at end of file diff --git a/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2EqualityIndexedValueV2.json b/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2EqualityIndexedValueV2.json deleted file mode 100644 index b7a5c3c..0000000 --- a/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2EqualityIndexedValueV2.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "v": { - "$binary": { - "base64": "DqvN76sSNJh2EjQSNFZ4kBICl42VcDwOxUhPxqcSx/Yv98vhrHX+qFwE6J7jRL/Q4isKrBTfN/An79R2UiP85lOnPTrUN1CKi0YQpCdGZbieFNMUBJ6g1u/ZgcIHxT+MQQ8BwYT+YidACALF18V76cnTnsgBjaju29a643JQjPoNdakFwQl4Xwlr+77e35ztQRHN2Do2J+7pc5569xBNbUU2IbTCvQ/jtngwNbaP7CSWb9WQRqjs2vId+FPlmNsShbrevAXFGSG/JY00t3TJpHfyburvBfEMZapT3H3q8U3o/w==", - "subType": "06" - } - } -} diff --git a/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayload-with-edges.json b/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayload-RangeV1.json similarity index 100% rename from ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayload-with-edges.json rename to ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayload-RangeV1.json diff --git a/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayload-with-edges-V2.json b/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayloadV2-RangeV1.json similarity index 100% rename from ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayload-with-edges-V2.json rename to ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayloadV2-RangeV1.json diff --git a/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayloadV2-RangeV2.json b/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayloadV2-RangeV2.json new file mode 100644 index 0000000..ee5f52c --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayloadV2-RangeV2.json @@ -0,0 +1,8 @@ +{ + "v": { + "$binary": { + "base64": "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", + "subType": "06" + } + } +} diff --git a/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2RangeIndexedValueV2.json b/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2RangeIndexedValueV2.json deleted file mode 100644 index 6ac5a4e..0000000 --- a/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2RangeIndexedValueV2.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "v": { - "$binary": { - "base64": "D6vN76sSNJh2EjQSNFZ4kBIQCG6OwBqJxG7szTWZFLKfOC7z0LmkmdzQyat5Sz+Rw24mknu3Vz4rY15o+ZGQVy8W2M5rcGWAocB4uoVhVIt8D2fzqpAVSNmt3UtiAd/868IC02MBhgoSDG/KCY3aZQfB0qy2t4O5r2xaVA2IuOZFrDFfd6CPsJZKAZTwPgHaPoURYiLopIapJ+zc++69eV8HwVTWOLhPFOkkxrLlaDIIPbbE/m5SzueUIA5gcISX4PKKo4EiaxRkanYa8Ai/PM9i2OkSHj5zvJwISGiBWddP49F53F90FqyYc37a+IYPRRVyHdMj0mMeH/vQwxP9ZXZD1yrHc8N6gGQgiHKOVZ1jTko8mJvsFvpAJG8ZiHo3Pe3bAwIOvcj5MOup/BqQNh6OoT2T6PHSwdZKJUA92NBdK/TqvfWWjwSYzrfUxyumDb24E0M4ae+f2/kSEPhGMI8KVZtNKoWIT53Ac0RQ5rwaLEggveM9cLpQqnXvi9X5OL/YSQ+vNaM9H+uHiIKlw3bBPLCLzmOmZzddu4mbltqXOFPiRS2Ob7xlHI1RGbgqeuFKD94ddjSsb3ucKwrrdDVWQJOKn95PPZ8MfjQ3VR5lSdgcUsa+q7SwB1J1k0i5/avhrolqpCipg79k1nnUbvzIDCcd974hvDP21UZ7tx4yniHYKcp2Djw/uW/M6Kowm/NBzJjc8dcNAlpxkcjeZGtsFte0HN4nvKyHmkYbkycvJsN1sM/lPAhTC2zkBnfaAEyp+EU49By2xQlnVbPGum0nzoud5xpI1DUyqw6zRos45iXfSIiGSzZtpGHYcJdbyy1Mn+SDH3rYMZ4yGg3Vr37cT0enszHCoSzwA09HLF0LRDiIlZexwu2cIPMzMdpOh3OPwqx5rgQE77W+FnhTXlQHaD1plphBLixyvEd3Sl+4KxDrQfnfIj8OTGnzX9wUD30N3jzbabEJEGtostuJAUdkJgikDCx3vJ4ZRvYYLoF9sDFOqCugvvt6xnH/yAHgoPWxCyEE6kF135rtT0zDZ6w6JC/HLMRDuONivd1pGkDgN6Bdb7zHF/aM1k9pRXpHHi1BQOmFs7Bl0EaSTcnGG09Zdutu1Fu5hcqIjbmsuH9r8ZDy8LQh8grPsY6yly6kocAJXxQyCFVBYDk4XekWe/6kDQ==", - "subType": "06" - } - } -} diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double-precision/encrypted-payload-v2.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double-precision/encrypted-payload-v2.json index 1350b24..ddd191f 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double-precision/encrypted-payload-v2.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double-precision/encrypted-payload-v2.json @@ -5,7 +5,7 @@ "age": { "$gte": { "$binary": { - "base64": "DV0FAAADcGF5bG9hZAAZBQAABGcABQUAAAMwAH0AAAAFZAAgAAAAAA5O5YOmDnNEzt4VzOdPJoBsorBvi4P38NSXFCQXBT7lBXMAIAAAAAAlCbJrLprhv7PZAWfpe1J77kmxxrTm5d+VIAzQ1t0f9wVsACAAAAAAJsEPn/IWj5o4yK+N8amVX9KXnsELZG2J1c6Wa2AfBE4AAzEAfQAAAAVkACAAAAAAwVdX7uREzGJG5YAlsRvkOq5eddbRwIMXoUyBxtTOWyMFcwAgAAAAAH7tQpElOGJxNW3nBA/KvOwRjEttzL4Yj7QxAKdseG83BWwAIAAAAAD3pf9mr2hOP/do52J6tCm1L6EW8dcAnjl1AX56PsqCrwADMgB9AAAABWQAIAAAAAB/r0rye8dC3m4mih9d9oBcoQ6Zz99MQLXO5RvpPQ0CxAVzACAAAAAAyAOYAbhDJ52goQxGqSffPOA68Z5ST6MHehKnzrW4NxgFbAAgAAAAABKOFQ4VoYzcavMdAgvpAc9SMLWpJAI/XabuetDojHI3AAMzAH0AAAAFZAAgAAAAAO2Hv6Qd4XbjLmDbLe2/dufbhh+Bc1myy7VrNWQswguHBXMAIAAAAACskbeGL2j0dhv3JUYGLto/8kBwO/CS6CSy2Fz01Qd/oAVsACAAAAAAQD5HxofvNYPA/WXGFJBJ7Aqn4TTxvNEpsZX7QIi8NQEAAzQAfQAAAAVkACAAAAAAtTHP+RbNcKHQQitmLFjax5jU3lSvUFioevRqvngmVrgFcwAgAAAAAJ1FzPG89m3duUQlzzhr10u2bHkrcVrXSqTdRTQRwbuIBWwAIAAAAACDwj7HWLNQncRny0bvqljLDfvtYmGov28d2B/JEHf9sAADNQB9AAAABWQAIAAAAACx7BgZhTiIgBbhrGj1nd8jicXeBh2kUEYz4icmc9ujpAVzACAAAAAAWAUKWWlejF5rygbpZmfnmFlKKi605/AAgxC6jhE+MdgFbAAgAAAAABaV7W7xzxS0nb1Ai7Cfelb3p8bNwTf2fgT/PmQghd9GAAM2AH0AAAAFZAAgAAAAAEyLWJxrA6BmuzegYLP4kUmvxoT1dvr7RttUcJ9+VL81BXMAIAAAAAAUA36oeKJKKyAvckEDg3qz6JDJmyWJzL/PXzUYhrJMUQVsACAAAAAADjxtljJ8f/mlqv2w/jCWJo1UmAzwqtcgQhiqkWBiOQoAAzcAfQAAAAVkACAAAAAAxwM1EBD2yYprO6DgSL/hf7nNswGChKMzNRrdcVAX0QEFcwAgAAAAAPq9JZtWNg4/ZGHjkzpMQx0mwyp0WQQE8lp0l33dC1dzBWwAIAAAAAC42oIAFJNPW5m2erwYVSZPmhQoKD7nxjvqZNuj+lFrhAADOAB9AAAABWQAIAAAAADgeS5YwHbBJYHjnE9rdIFOXCWa4MZgksnq9BCKEBNCQgVzACAAAAAA0ShFMpOeEFx3gMLQEIMhvlkYQJ6DXk/ryqYFXSt0oMAFbAAgAAAAAA4vTg5+jjmTJUB+xkO8YEnaA7fwOph35M9WSK26hQ3nAAM5AH0AAAAFZAAgAAAAAKOQKnHWdirTeER0VaLHcH9Gam5QOhil1vpk11GqLVYsBXMAIAAAAACvxg5olIv89aG/3AhBg4yw2ZJqPMYppPJ8eY1dCIlbIAVsACAAAAAAYmeB3mfKkJlkTw9gbIl2aHKs9G+jxagWBwjubQOomhAAABJjbQAAAAAAAAAAAAAQcGF5bG9hZElkAAAAAAAQZmlyc3RPcGVyYXRvcgACAAAAEHNlY29uZE9wZXJhdG9yAAQAAAAA", + "base64": "DZEFAAADcGF5bG9hZAAZBQAABGcABQUAAAMwAH0AAAAFZAAgAAAAAA5O5YOmDnNEzt4VzOdPJoBsorBvi4P38NSXFCQXBT7lBXMAIAAAAAAlCbJrLprhv7PZAWfpe1J77kmxxrTm5d+VIAzQ1t0f9wVsACAAAAAAJsEPn/IWj5o4yK+N8amVX9KXnsELZG2J1c6Wa2AfBE4AAzEAfQAAAAVkACAAAAAAwVdX7uREzGJG5YAlsRvkOq5eddbRwIMXoUyBxtTOWyMFcwAgAAAAAH7tQpElOGJxNW3nBA/KvOwRjEttzL4Yj7QxAKdseG83BWwAIAAAAAD3pf9mr2hOP/do52J6tCm1L6EW8dcAnjl1AX56PsqCrwADMgB9AAAABWQAIAAAAAB/r0rye8dC3m4mih9d9oBcoQ6Zz99MQLXO5RvpPQ0CxAVzACAAAAAAyAOYAbhDJ52goQxGqSffPOA68Z5ST6MHehKnzrW4NxgFbAAgAAAAABKOFQ4VoYzcavMdAgvpAc9SMLWpJAI/XabuetDojHI3AAMzAH0AAAAFZAAgAAAAAO2Hv6Qd4XbjLmDbLe2/dufbhh+Bc1myy7VrNWQswguHBXMAIAAAAACskbeGL2j0dhv3JUYGLto/8kBwO/CS6CSy2Fz01Qd/oAVsACAAAAAAQD5HxofvNYPA/WXGFJBJ7Aqn4TTxvNEpsZX7QIi8NQEAAzQAfQAAAAVkACAAAAAAtTHP+RbNcKHQQitmLFjax5jU3lSvUFioevRqvngmVrgFcwAgAAAAAJ1FzPG89m3duUQlzzhr10u2bHkrcVrXSqTdRTQRwbuIBWwAIAAAAACDwj7HWLNQncRny0bvqljLDfvtYmGov28d2B/JEHf9sAADNQB9AAAABWQAIAAAAACx7BgZhTiIgBbhrGj1nd8jicXeBh2kUEYz4icmc9ujpAVzACAAAAAAWAUKWWlejF5rygbpZmfnmFlKKi605/AAgxC6jhE+MdgFbAAgAAAAABaV7W7xzxS0nb1Ai7Cfelb3p8bNwTf2fgT/PmQghd9GAAM2AH0AAAAFZAAgAAAAAEyLWJxrA6BmuzegYLP4kUmvxoT1dvr7RttUcJ9+VL81BXMAIAAAAAAUA36oeKJKKyAvckEDg3qz6JDJmyWJzL/PXzUYhrJMUQVsACAAAAAADjxtljJ8f/mlqv2w/jCWJo1UmAzwqtcgQhiqkWBiOQoAAzcAfQAAAAVkACAAAAAAxwM1EBD2yYprO6DgSL/hf7nNswGChKMzNRrdcVAX0QEFcwAgAAAAAPq9JZtWNg4/ZGHjkzpMQx0mwyp0WQQE8lp0l33dC1dzBWwAIAAAAAC42oIAFJNPW5m2erwYVSZPmhQoKD7nxjvqZNuj+lFrhAADOAB9AAAABWQAIAAAAADgeS5YwHbBJYHjnE9rdIFOXCWa4MZgksnq9BCKEBNCQgVzACAAAAAA0ShFMpOeEFx3gMLQEIMhvlkYQJ6DXk/ryqYFXSt0oMAFbAAgAAAAAA4vTg5+jjmTJUB+xkO8YEnaA7fwOph35M9WSK26hQ3nAAM5AH0AAAAFZAAgAAAAAKOQKnHWdirTeER0VaLHcH9Gam5QOhil1vpk11GqLVYsBXMAIAAAAACvxg5olIv89aG/3AhBg4yw2ZJqPMYppPJ8eY1dCIlbIAVsACAAAAAAYmeB3mfKkJlkTw9gbIl2aHKs9G+jxagWBwjubQOomhAAABJjbQAAAAAAAAAAAAAQcGF5bG9hZElkAAAAAAAQZmlyc3RPcGVyYXRvcgACAAAAEHNlY29uZE9wZXJhdG9yAAQAAAASc3AAAQAAAAAAAAAQcG4AAgAAABB0ZgAGAAAAAW1uAAAAAAAAAAAAAW14AAAAAAAAAGlAAA==", "subType": "06" } } diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double/encrypted-payload-v2.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double/encrypted-payload-v2.json index 6052484..38e6cf1 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double/encrypted-payload-v2.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double/encrypted-payload-v2.json @@ -5,7 +5,7 @@ "age": { "$gte": { "$binary": { - "base64": "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", + "base64": "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///////vfwA=", "subType": "06" } } diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-openinterval/encrypted-payload-v2.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-openinterval/encrypted-payload-v2.json index 8c14e2b..9987ce8 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-openinterval/encrypted-payload-v2.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-openinterval/encrypted-payload-v2.json @@ -5,7 +5,7 @@ "age": { "$gte": { "$binary": { - "base64": "DckDAAADcGF5bG9hZACZAwAABGcAhQMAAAMwAH0AAAAFZAAgAAAAAInd0noBhIiJMv8QTjcfgRqnnVhxRJRRACLfvgT+CTR/BXMAIAAAAADm0EjqF/T4EmR6Dw6NaPLrL0OuzS4AFvm90czFluAAygVsACAAAAAA5MXcYWjYlzhPFUDebBEa17B5z2bupmaW9uCdtLjc7RkAAzEAfQAAAAVkACAAAAAA7lkNtT6RLw91aJ07K/blwlFs5wi9pQjqUXDcaCTxe98FcwAgAAAAAPwySffuLQihmF70Ot93KtaUMNU8KpmA+niyPRcvarNMBWwAIAAAAACDv6fJXXwRqwZH3O2kO+hdeLZ36U6bMZSui8kv0PsPtAADMgB9AAAABWQAIAAAAACmksDgWv8fh8j4HvZ2U+eC/2+PvEsGhl1YIr04t8MEyQVzACAAAAAA42J2JBPJI5iRZbKCaLoDKJkz6sEYtwRqbXWCQFnROhAFbAAgAAAAAGwVrD6ZZFYm74a74FBUKMJj/KlQWtfEZGTAM8jKcm1pAAMzAH0AAAAFZAAgAAAAAEpcX7iBiGknOl/okkdqJbUlcVEAgVwNnusmHGfcnWiyBXMAIAAAAABt4YtHuLEMj8mq3Sm7x9LlPoLn44VwwYXzsy9O+CY7mQVsACAAAAAAbNDaUHpCmMR2TkqbORXHmTGu/H7arZvIQUdaQmow0uAAAzQAfQAAAAVkACAAAAAAiNNHQVRYZQZIyyzCQ2/QGRA1NJK2PkJ+nonrNMR8M+kFcwAgAAAAAFjXVHdBrcFBymh2M52BuuY8s54hG4YmNrLlQsDOpt0+BWwAIAAAAAB1W6tFAJaHupslrT7ec9vJ0Cn2aEmUsrndCqYkOFIGNAADNQB9AAAABWQAIAAAAABZunJQk5/sMjTmxIeZpwTF010+V434ybhEM5MCLZXvHgVzACAAAAAAzg+BvL6K2ym0OFtQU9TUrDaJd2fMgY9Z8hp1QJnDwF4FbAAgAAAAAGltO/ynzGg3yrA79Hvf2rXclgHFKCfY1V1E4C45GncxAAM2AH0AAAAFZAAgAAAAAEKk7WGoX0IXnKUDtmjVP3J8cOIatQEPrEoyH2APyETuBXMAIAAAAAAOQ2aEYoMGhGhkY0E1hPctbPmpdQ/A2ZKJ82Gv6Ec4agVsACAAAAAA0ELd3kjmsgfzWoMWR+RL3vCIlu7NEE6+GLkWN3FoM5AAABJjbQAAAAAAAAAAAAAQcGF5bG9hZElkAAAAAAAQZmlyc3RPcGVyYXRvcgACAAAAAA==", + "base64": "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", "subType": "06" } } diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32/encrypted-payload-v2.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32/encrypted-payload-v2.json index 796f336..cbf1d91 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32/encrypted-payload-v2.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32/encrypted-payload-v2.json @@ -5,7 +5,7 @@ "age": { "$gte": { "$binary": { - "base64": "Dd0BAAADcGF5bG9hZACZAQAABGcAhQEAAAMwAH0AAAAFZAAgAAAAAInd0noBhIiJMv8QTjcfgRqnnVhxRJRRACLfvgT+CTR/BXMAIAAAAADm0EjqF/T4EmR6Dw6NaPLrL0OuzS4AFvm90czFluAAygVsACAAAAAA5MXcYWjYlzhPFUDebBEa17B5z2bupmaW9uCdtLjc7RkAAzEAfQAAAAVkACAAAAAA7lkNtT6RLw91aJ07K/blwlFs5wi9pQjqUXDcaCTxe98FcwAgAAAAAPwySffuLQihmF70Ot93KtaUMNU8KpmA+niyPRcvarNMBWwAIAAAAACDv6fJXXwRqwZH3O2kO+hdeLZ36U6bMZSui8kv0PsPtAADMgB9AAAABWQAIAAAAACcMWVTbZC4ox5VdjWeYKLgf4oBjpPlbTTAkucm9JPK0wVzACAAAAAA3tIww4ZTytkxFsUKyJbc3zwQ2w7DhkOqaNvX9g8pi3gFbAAgAAAAAGs9XR3Q1JpxV+HPW8P2GvCuCBF5bGZ8Kl1zHqzZcd5/AAASY20ABAAAAAAAAAAAEHBheWxvYWRJZAAAAAAAEGZpcnN0T3BlcmF0b3IAAgAAABBzZWNvbmRPcGVyYXRvcgAEAAAAAA==", + "base64": "DYECAAADcGF5bG9hZAAZAgAABGcABQIAAAMwAH0AAAAFZAAgAAAAAInd0noBhIiJMv8QTjcfgRqnnVhxRJRRACLfvgT+CTR/BXMAIAAAAADm0EjqF/T4EmR6Dw6NaPLrL0OuzS4AFvm90czFluAAygVsACAAAAAA5MXcYWjYlzhPFUDebBEa17B5z2bupmaW9uCdtLjc7RkAAzEAfQAAAAVkACAAAAAALyvwdd//Hc4qzpSaMFwsLHWOHVnvmw554fbJ47tYpY0FcwAgAAAAAG8rFusBCnyJnbwXJ+8aQ1WM+XBbFCF1rUmcXAZxQWkkBWwAIAAAAACN9YgQN69DpjbYlqV5j+d3Wxw0i4Xyv3a4l8MBSS7qAQADMgB9AAAABWQAIAAAAADLNQvw103YajKpjkNf6J2NdUtiwHFqSefCh5ZWTFHn5gVzACAAAAAAEhDT0LHoNKXVVHkV/TK03iRGiWnHip/oRoYSFvsAeM0FbAAgAAAAADyzWOWBxsAJkQm0lUsW+iHa+ecwl3xr1GAoKxnQQ8XZAAMzAH0AAAAFZAAgAAAAAJwxZVNtkLijHlV2NZ5gouB/igGOk+VtNMCS5yb0k8rTBXMAIAAAAADe0jDDhlPK2TEWxQrIltzfPBDbDsOGQ6po29f2DymLeAVsACAAAAAAaz1dHdDUmnFX4c9bw/Ya8K4IEXlsZnwqXXMerNlx3n8AABJjbQAEAAAAAAAAAAAQcGF5bG9hZElkAAAAAAAQZmlyc3RPcGVyYXRvcgACAAAAEHNlY29uZE9wZXJhdG9yAAQAAAASc3AAAQAAAAAAAAAQdGYABgAAABBtbgAAAAAAEG14AMgAAAAA", "subType": "06" } } diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-field-map.json index ba84729..ab988b4 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "date", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-payload.json index 903ab0c..8e1ace8 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/encrypted-payload.json @@ -3,13 +3,15 @@ "filter": { "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "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", + "subType": "06" } } }, "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -25,7 +27,7 @@ "path": "encrypted", "bsonType": "date", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/mongocryptd-reply.json index 0aa9bf6..9ba8638 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date-v2/mongocryptd-reply.json @@ -31,7 +31,7 @@ "path": "encrypted", "bsonType": "date", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-field-map.json index 2aab29c..ccda259 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-payload.json index 73920ae..638e2a1 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/encrypted-payload.json @@ -3,13 +3,15 @@ "filter": { "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "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", + "subType": "06" } } }, "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -25,7 +27,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/mongocryptd-reply.json index 2ed2487..58d13cd 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision-v2/mongocryptd-reply.json @@ -31,7 +31,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, @@ -55,4 +55,4 @@ } }, "hasEncryptedPlaceholders": true -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-field-map.json index 2715ab7..d513a30 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-payload.json index e2e5329..509ce5e 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/encrypted-payload.json @@ -3,13 +3,15 @@ "filter": { "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "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", + "subType": "06" } } }, "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -25,7 +27,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/mongocryptd-reply.json index 206c36e..8c6ce71 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-v2/mongocryptd-reply.json @@ -31,7 +31,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/encrypted-payload.json index 40d3fdc..e43bccb 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision-v2/encrypted-payload.json @@ -3,13 +3,15 @@ "filter": { "encrypted": { "$binary": { - "base64": "DUkDAAADcGF5bG9hZAAZAwAABGcABQMAAAMwAH0AAAAFZAAgAAAAAKfR876j77BmHaWxFf7Px/B695Rn7JAN3upnEpaEqFT+BXMAIAAAAACXqoD16/Q8tNDRR7gP222DxV0SBOSZ4bqsxYILo8a/0wVsACAAAAAA1y7ThR8e87l/kWKzGJThtIrT+i+4I690g9vJeevhk3cAAzEAfQAAAAVkACAAAAAAlpFiajzOojYERTN1LCni1VGk+ZVax/J2Rg3dQeHpMy4FcwAgAAAAAB4PqYOdB4uVsL2LSxWATz5EfrL573g4lDS0nQ+9uVVKBWwAIAAAAABaniO+t61sMSyoQzM/9YtOfA6InAK1+sKIHqbyT7IQygADMgB9AAAABWQAIAAAAAAGWed/HKDT8MkY4RMK+T/F8N9qFjiRfkfp3whoMtqjtwVzACAAAAAAjjy5yZSsBjTwwUXkSpx37XqtMBW93s4a3OwVV7PEVB8FbAAgAAAAAPpRnrDZN/ksgf+tK0r3UNmjdr3yT0e5ZSVYbnxkzYR5AAMzAH0AAAAFZAAgAAAAAFH9l9GGA1I52atJV5jNUf1lx8jBjoEoVoME97v5GFJiBXMAIAAAAAC1qH3Kd78Dr9NGbw7y9D/XYBwv5h1LLO8la5OU7g8UkQVsACAAAAAArZ6atJCYrVfHB8dSNPOFf6nnDADBMJcIEj8ljPvxHp8AAzQAfQAAAAVkACAAAAAAO1tUQja12SujAQx2RpwPbDRjdPc5+Ls8foeYDqw/Rz8FcwAgAAAAAO4FJE6dkcD42BQ8fx3QudYWIOwzZtjxvOMLX56VKwjKBWwAIAAAAABHQbab64A2haSeSv816sVwb58QJXE0izRyptjW39T/QwADNQB9AAAABWQAIAAAAAAId1qXjFZYpDxWI/YS4/n5iKlbeqJgkhe+Vt0zxMclqQVzACAAAAAALEJEZsKnlY9oBhNN6K2+j7ayMw7enQ1N4YEkIvBNsCoFbAAgAAAAANxh2kRNkQHGgUXfFc5mM1ngQ9hpsvdXkytZPGHVjm2XAAASY20AAAAAAAAAAAAAEHBheWxvYWRJZADSBAAAEGZpcnN0T3BlcmF0b3IAAQAAAAA=", - "subType": "6" + "base64": "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", + "subType": "06" } } }, "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -32,9 +34,15 @@ "sparsity": { "$numberInt": "1" }, - "min": 0.0, - "max": 200.0, - "precision": 2 + "min": { + "$numberDouble": "0.0" + }, + "max": { + "$numberDouble": "200.0" + }, + "precision": { + "$numberInt": "2" + } } } ] diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-field-map.json index f8ae79f..12e9d3c 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "double", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-payload.json index a72dfac..0eeffd3 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/encrypted-payload.json @@ -3,13 +3,15 @@ "filter": { "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "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", + "subType": "06" } } }, "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -25,7 +27,7 @@ "path": "encrypted", "bsonType": "double", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/mongocryptd-reply.json index 88ce91f..3914bd6 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-v2/mongocryptd-reply.json @@ -31,7 +31,7 @@ "path": "encrypted", "bsonType": "double", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-field-map.json index 336446a..dc7bd33 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "int", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-payload.json index c28ed3e..2401b9f 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/encrypted-payload.json @@ -3,13 +3,15 @@ "filter": { "encrypted": { "$binary": { - "base64": "DckEAAADcGF5bG9hZACZBAAABGcAhQQAAAMwAH0AAAAFZAAgAAAAAKfR876j77BmHaWxFf7Px/B695Rn7JAN3upnEpaEqFT+BXMAIAAAAACXqoD16/Q8tNDRR7gP222DxV0SBOSZ4bqsxYILo8a/0wVsACAAAAAA1y7ThR8e87l/kWKzGJThtIrT+i+4I690g9vJeevhk3cAAzEAfQAAAAVkACAAAAAAlpFiajzOojYERTN1LCni1VGk+ZVax/J2Rg3dQeHpMy4FcwAgAAAAAB4PqYOdB4uVsL2LSxWATz5EfrL573g4lDS0nQ+9uVVKBWwAIAAAAABaniO+t61sMSyoQzM/9YtOfA6InAK1+sKIHqbyT7IQygADMgB9AAAABWQAIAAAAACEoDdR4neyFrwxEjf97csBWYgbGT2GqTlMff0Iww8S3wVzACAAAAAAO5caRM9/ghnb+v1iiAJSMEWFEURCoJ+/krcDaFXpJA8FbAAgAAAAAMfjmtr9XtUe1aJn7L3CjvFZGOHk5ey84zUEC+go+hgUAAMzAH0AAAAFZAAgAAAAACFSn9LbHIGoJEDxQm+l/VhB1Qp2sDHEDDH/n/c8F8n8BXMAIAAAAACBO4bhRYkAW8TOvy65UHl7YNTK+4vge++76cn1G8/dugVsACAAAAAAzG6xXvdYOA8Myyt5WXWt0BWkQNQQtmstxsv5gCZsd54AAzQAfQAAAAVkACAAAAAAGj22/+aFr+8l9CLnrDZ5NhzCgz++msotwjPmSF9OM+gFcwAgAAAAAC9cqJy///jAYzdKgtwFSx75wY+WX47DOOpPRbkb78OPBWwAIAAAAAAGFIMLMvvz+5jqPPxU4J6K0zt8Au0G+ZQeqAioWidVjAADNQB9AAAABWQAIAAAAADbZ5AD/5OvYukqwD1ouIm1JCicqneF8Irq6sPhgRe20wVzACAAAAAAdP03rg0E4wfRAUdu6SaaQOZi4JxoX9bUAFENSuB38wQFbAAgAAAAAHA7IE4pXO053jFajvK//gEl99NHzxtkM2HbOlkgHox5AAM2AH0AAAAFZAAgAAAAACSbt5cVtVjP7BGAWK09HRCwAyV9It3zsFV0xaSVTkCYBXMAIAAAAAB2oDy5xJX9PzwQxDkT/mZcL4L8MEH2iAQkbFRJX8uDnwVsACAAAAAA9gBAm/VjmIxxyxjC3WYtk5garVKwbEaKA4ehcrTrV0AAAzcAfQAAAAVkACAAAAAAPLjGwQ+DBcHE6XSH+knrIFTqq1zCgbltUvFW7wQwib0FcwAgAAAAAOfj/lP3YxmHoZBYlp60ZOnxx38JpMeougcNBUoWQfl0BWwAIAAAAACEzswX85ONfNBaAkc8gU2uGDfsAFrSy7k24snonwgmhwADOAB9AAAABWQAIAAAAADAg4r1xbwXaXEYn9Xc0gZ/ZTDqKRye52R4+M9yw1JoMwVzACAAAAAAPgpORYCcoS+SKCMf2IC1b7sHYFG0LtmWJmTlogsl81YFbAAgAAAAAL44mfvmJUV2pYwYEVRBEpTxcvc2tcu/1wYEmsS50ybtAAASY20AAAAAAAAAAAAAEHBheWxvYWRJZADSBAAAEGZpcnN0T3BlcmF0b3IAAQAAAAA=", - "subType": "6" + "base64": "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", + "subType": "06" } } }, "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -25,7 +27,7 @@ "path": "encrypted", "bsonType": "int", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/mongocryptd-reply.json index af388f5..4a53836 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32-v2/mongocryptd-reply.json @@ -31,7 +31,7 @@ "path": "encrypted", "bsonType": "int", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-field-map.json index 64964c1..d093f41 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "long", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-payload.json index d35ddce..e755ab5 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/encrypted-payload.json @@ -3,13 +3,15 @@ "filter": { "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "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", + "subType": "06" } } }, "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -25,7 +27,7 @@ "path": "encrypted", "bsonType": "long", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/mongocryptd-reply.json index 9fe3446..58a9442 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64-v2/mongocryptd-reply.json @@ -31,7 +31,7 @@ "path": "encrypted", "bsonType": "int", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double-precision/encrypted-payload-v2.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double-precision/encrypted-payload-v2.json index d47ce22..d51f579 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double-precision/encrypted-payload-v2.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double-precision/encrypted-payload-v2.json @@ -1,7 +1,7 @@ { "v": { "$binary": { - "base64": "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", + "base64": "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", "subType": "06" } } diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double/encrypted-payload-v2.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double/encrypted-payload-v2.json index f25c8b5..08152d1 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double/encrypted-payload-v2.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double/encrypted-payload-v2.json @@ -1,7 +1,7 @@ { "v": { "$binary": { - "base64": "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", + "base64": "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", "subType": "06" } } diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32/encrypted-payload-v2.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32/encrypted-payload-v2.json index 8cb495a..ee5f52c 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32/encrypted-payload-v2.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32/encrypted-payload-v2.json @@ -1,7 +1,7 @@ { "v": { "$binary": { - "base64": "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", + "base64": "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", "subType": "06" } } diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/sparsity-2/encrypted-payload-v2.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/sparsity-2/encrypted-payload-v2.json index 8e52120..14ec3ba 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/sparsity-2/encrypted-payload-v2.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/sparsity-2/encrypted-payload-v2.json @@ -1,7 +1,7 @@ { "v": { "$binary": { - "base64": "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", + "base64": "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", "subType": "06" } } diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-field-map.json index ba84729..ab988b4 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "date", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-payload.json index d12ed4a..4827555 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/encrypted-payload.json @@ -5,14 +5,16 @@ "plainText": "sample", "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "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", + "subType": "06" } } } ], "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -28,7 +30,7 @@ "path": "encrypted", "bsonType": "date", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/mongocryptd-reply.json index 79cb6bc..bdca3e9 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date-v2/mongocryptd-reply.json @@ -34,7 +34,7 @@ "path": "encrypted", "bsonType": "long", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-field-map.json index 2aab29c..ccda259 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-payload.json index e96bc2a..edab8fb 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/encrypted-payload.json @@ -5,14 +5,16 @@ "plainText": "sample", "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "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", + "subType": "06" } } } ], "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -28,7 +30,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/mongocryptd-reply.json index 5f1139a..a76a485 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision-v2/mongocryptd-reply.json @@ -34,7 +34,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-field-map.json index 2715ab7..d513a30 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-payload.json index 48c5dd8..f25954c 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/encrypted-payload.json @@ -5,14 +5,16 @@ "plainText": "sample", "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "Cx9bAAAFZAAgAAAAACm81dguhQYS2gXLYGq5LY+H4WZdCysG+w/KCoqSuJM6BXMAIAAAAAAuPz1M22vcGxotLCha9vNMtNmIvF/wy0ifpMBYySaOnAVwADEAAAAA/L++3P7CrwPgNWztsng9dPMqNKG2HNKzjP4gvOwaNKWN9yqtQWilakb9rSiJkRlnigV1ABAAAAAEEjRWeBI0mHYSNBI0VniQEhB0ABMAAAAFdgBgAAAAAKvN76sSNJh2EjQSNFZ4kBIpl7Zd8lZwByxzgM4ee0M2NyiFGc7qTVUpLqldpckaEJFSMARROf87iyzUtNC8mx8mDNT/8tEYDKVxmbUptKQsQlpmQYdIa4i9EavZkhX4MgVlACAAAAAA65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+wFbAAgAAAAADj7Omh6bLAHeEmNfcVOH9qag6YFLwoH+MAvczX88brGEmsAAAAAAAAAAAAEZwBwWQAAAzAAtgAAAAVkACAAAAAAHv1Kggg4HRk87/EfqcM5J5rX4zbLvP6jeOVnNI8UBk4FcwAgAAAAAFqLA/0uSzDg8LIvPOug86qXZNEoKjiUX84t9MGLQQbTBWwAIAAAAABu95kvBzeFxZWtk9reo4z3SVSXlyl7lhh39J2ZFmaXtgVwADEAAAAAe7War6mtpkT7ZmBpDJ5OF6nQOuqfRZ40/kC9ltpclDWeeDXYlCGt8iPeqWJkxeEjpAADMQC2AAAABWQAIAAAAACiBBRp9+nBf6zGm3P+iNX/+qxAhZgjpiT/wAfIB+fBlwVzACAAAAAAGvFzxqNcUf/5mzvjhfl4FXWmBC9115ljiO4/OfybKNcFbAAgAAAAAFPldhq6oMSWLPZsbmpP/CTBSAl8ENr5LKwXTr0sFhaaBXAAMQAAAACTPd0q33ZUxvYa8/rU0xT3ujS9MuxMgCo5nN4/rcb+Fm+WoLLsQNogCymXQTkOO6amAAMyALYAAAAFZAAgAAAAAMLqxgfxpqpIZCXPU/BP9Aa+trIw5Jb4gtCCj+Hq9jKhBXMAIAAAAACzwU5bcDhLrTgjTWm+LhdFtqQDnmyY0VpqrYUNU+XTPwVsACAAAAAAahS0ITnR/CVFjnjldmxewoig3Ie37/a5SrXPEVoTdaMFcAAxAAAAALkzu9uKHgfIXAulSuL7J40IoDcYiELO5biGs8ANutCShSnK2IhKnD2YjN/gohDA2wUAAzMAtgAAAAVkACAAAAAAj35V54bLw3Ve5g7vxqkTl9b/5ib/OaZj/YeDvBqAWmIFcwAgAAAAAOKsHSmQj+PbeRvAsLiG9+NFYWUZ14elW4rW9z/8xn00BWwAIAAAAAAIqn++rZcjHaS6pHl6fsMADVlsIDcRGTcVoBMbgI+VgwVwADEAAAAAqvI2A9XiWrwRdre2hms1TEPgIfcUOqtVv8ginHWjFK3c62dzCQPGoLcQMmn8FMgSDwADNAC2AAAABWQAIAAAAAAN5I2e3xYLxYSq+FhblqKHpB0oqiHbR0YI5rrBxZMdfQVzACAAAAAAxr9S9sBNudmr/1nRilpY+8dM1K4EvSZkoi+BbD0yC6AFbAAgAAAAAKbJf3yBr2aSt5klNTJiXVhrudBp8PlB7AkTz4s3FkgaBXAAMQAAAACpdxa9BRUZMTiKuurc0iyatd3akmXbO4TRDly78RAG1czOOEWGFQNOL/BAzRMJjq8EAAM1ALYAAAAFZAAgAAAAABlcNxBmuS2hFWIJzBPsMJy4LEW3olVlaLt6nmaJVyfsBXMAIAAAAAB5TRJWqyTFf3nDWgDB48uHsognMsVtFvpUw8HE9DJOlAVsACAAAAAAWVyPN5uCYDiUGyxbLaidgE4B4zX9QeUGou77FkD+Z0UFcAAxAAAAAIsM6mbVPSEBA+500vSNjff7urzbU5elg0rrSYYCWx44YDuT33pLuPE8XlX0nSf9EtIAAzYAtgAAAAVkACAAAAAAc73ceC4qclF8S2xEoX6SddtUcRkxPW+19IOYLg+CuFgFcwAgAAAAAMksxZenj1R8iJdtk6njxaUwwfc9xyqnlFGNxzUgyRSjBWwAIAAAAABa8jZ3UaKoOkq4XvyoDiDhJhBwAM9LM+h78XS/iVreQgVwADEAAAAAE/k15ENCui2MADpkZfc7B9BUC+cg0jmGTLeovWYuxvVNJynI/iGlwCZbpuPsXj4aDQADNwC2AAAABWQAIAAAAAAodxdPjLC4+6ZZD7OaTkciX+UeCmJitbFPcMwaksYSnAVzACAAAAAARdlMAhx4lVCEfSL4WFGzNx1SmVWG+3xlkvZDhaDYUooFbAAgAAAAAGbWrQMqntewa5GKpXE1zshRh1L4UUFFlA0C8uFo+D5bBXAAMQAAAAAD2jMujocEl/3HHwCSfBxAAx0Lmc1rHDopXB5N0fiNs4L13B0XOVsh+vsHpe89sUkAAAM4ALYAAAAFZAAgAAAAAK9Xq4/YwveWV924scqECfrnfg0n9lQa080awMrpn7q5BXMAIAAAAACYVAY0MWD0n+qad4lvz3tyfEuCH6mEpeyTnntg7VQ+AwVsACAAAAAAdmmEYKaXaPNnnIjyPbvZCjISYQ1FNf1hp4s5NQQ2Z+wFcAAxAAAAAOKqgUdWmzlLE8lx8toqNocNE2xmdronqiYVkCNqniQ6AieYSrKhxMT0b6U5PDvrynAAAzkAtgAAAAVkACAAAAAAZeRexLKIZr9xAz/3KM39Ag3tYPPHM+LMWP+042DR7TkFcwAgAAAAAA8SOQVl+rClpfdMKluNxIF5/4CAFMANtGmgSMF1b8wmBWwAIAAAAAA+U8kRTlU7mHEDYsQAITwK9evW8KUVzt+o7/X+H3GOwAVwADEAAAAAKoaH3IZNNWbxSseLnIjNs7aH63jSc2Z2igJ9iDbokBBWwBXLoIkiBZDOyPsYtdnO6QADMTAAtgAAAAVkACAAAAAApSZFnhxKcKm8eJ3fDiKw5bbL+pCGJnkLYqVznm+ba44FcwAgAAAAACtvFb0SqinyubFQ7AE65djO6RmJcQD6HP6mSJ5+07w+BWwAIAAAAAC6PqRi7DdeTxlu8MwDJze/klq97g4guBxANryB9LjViAVwADEAAAAAlPhSXNlz7b3Wlq2ctZSzoeGEE31maQ7A7QVLRoyORbcX/o2yFkiMbAuYGsHYDgDqggADMTEAtgAAAAVkACAAAAAAnf/gzk5ojKBw593K6XFy59q42fQ2T6Ct8ikmfQ5eSccFcwAgAAAAAEz232H0bZq3rASMCZ1u8TJhefVoT0ml3ZGhHSU6rC4CBWwAIAAAAADJYGhBuFWexLngkOX2udm1Y9E2jBRKEtolYRb9OCBz1QVwADEAAAAAliblWdOjMk6oXl7snwS1nZqBfb/+exB6WdPeVeAfr+4GDK/N05uGBBQDd8SQSJ78awADMTIAtgAAAAVkACAAAAAAXlG5rsH7yxfo6TfODWdsHyY0bgFP9fVkk2aDgiZ7X3QFcwAgAAAAAGOAa2FCGtrPff5UYqMnEyYStMvfmV41+Y6a98trN4u4BWwAIAAAAABPaMD0oAfz1Ju4Ce0LsI6fOs2On6k7Hvsi7TGR2V27NAVwADEAAAAANQzBLml5K/E/LJkx+UKjiMVHWL9SvtXgWc/JGkqW2b+s72QjrFxb8eJdwh4/vN2NxQADMTMAtgAAAAVkACAAAAAAaXNHiUhVSnMX80fSNIr5FUMNLHODFrgchlpoVEXlqxQFcwAgAAAAAGYWpR1Hlol8Bo4T4aQahIZYBR3NFu3gTFh+j/udsdvfBWwAIAAAAAAyFM/grf9P+RmQi9GKjVz/5syQBPO2TKazPaNVb+liCwVwADEAAAAALINXVkHJak2lFpJ1mcpY8gBVv5UPuKxgh3g8PVx0ZUJr0vhL9/yFf3WQmlC8yvDPWAADMTQAtgAAAAVkACAAAAAAJq7/n8YJ9xnOHtqajuBcz2A4fjhy4Q3iQ59K4mJ7OVcFcwAgAAAAAHBGZrWDHH9HBy1RHDJB9wJFRzr4Ms2eJrqhCGLPySxhBWwAIAAAAACXL1OOB3sDo96tLJjyY5uzuKSSiYX/CYnwkYVGoDAF9wVwADEAAAAAxmd0fLYu53FJwN3ocadTvWsoHjJFf0FrELs/3ObjAX7pAxDaZ36j4L3mp6jliHVX+QADMTUAtgAAAAVkACAAAAAAes665K87Dz+1+ceUddKET4abafqArW9DG5eH3J8BlbcFcwAgAAAAAOO8b0NP2sgYaytSGAAe4cdbjhWKShNatwUJwC+/trO4BWwAIAAAAADNYULFWd7hlHIdPXpFzzH+ZHdItbkKs1xqNd8jDimS4gVwADEAAAAA92w2DZyi+u7XMAlo0kfGtucYZDmPg69tEthC6MKmTqYBJYqozVsoXUqRzhTirlEMigADMTYAtgAAAAVkACAAAAAAGXS8C6K3OrIYy+7jd32Qxsiv9XSFc5I0R3ys4ms/fAkFcwAgAAAAAIdQnV+9PJkai9BEqJ2b57WlA3vxZPuvRCHuRjGt0mnlBWwAIAAAAACez4qSGpxvW/6jDSTPcbVJbgYbe9n+pz7jI072n/WfaQVwADEAAAAAVLw3EperEpf8RAuC+118FGvE9KWg9DXg1Rk+eryKmCv28BtvQRvXs0IITpJ+IkWMVQADMTcAtgAAAAVkACAAAAAALm7PAlvWeCTIyVK2nVznfiSTSpPn6h1mASmxpwAgPI8FcwAgAAAAAMy4kkRr9XK3zoT/il3ZrccSBKMdRP9EXEqSR+FWHrhCBWwAIAAAAACjQq+RJsE/47YcUf2zUdkJ8sZem9EW6qGakLY0fQxb5QVwADEAAAAACGQfS2teKjyfxuuSeajmryNDx13knvte3DqFWmBbqZIi4fzhLHFPFB83mBIMFh+xYAADMTgAtgAAAAVkACAAAAAABLFY6YZcR5VB6fhKwp87wKu3EJJVzznvTEXIL51P/LkFcwAgAAAAAGg8gUbKZRM3ga/rF178Ej2Gma3OjXHE6AIetpyaMfDVBWwAIAAAAABno6rPPW5/BeqvK5+LPn5xt/o9aZzr7iZns/dojZiQHwVwADEAAAAADDKyhbATm81xMT3YCUhLeUmhhK0hBN0JoB5qXzPxormu4t1Yam4TlWPfJ4E8JGTOUgADMTkAtgAAAAVkACAAAAAAcUvsciiEsnqdtWwfso7mEyf6l8Duy32bMfNdAG7PPxQFcwAgAAAAANnxg5+hqiRQbznIVrnYUbMCOlHhr6fXfZVhCLs78HcjBWwAIAAAAACGEnvIxBNc0eqQDxt0yipXNwR3IZbJxqt7u+25QYcNLgVwADEAAAAAdiJmbXDln8RqyABuWbQUgVy/L9+EWPFjW9WTGPLx9E/XaQ7eikzcuCFf7on9J+F+TwADMjAAtgAAAAVkACAAAAAA+gcdJwpMRpPDJAe8RTzqR9byq4pSbPw/YOfi1vXfGQQFcwAgAAAAAFyYwFI/5A1DsrWZrMwarGxO8TBYYeAPt6ilUevD1n/VBWwAIAAAAABlMZsqMI5mKRhbMd1BmDrShlp1V/Ess82VY8t2X2zKjQVwADEAAAAANOWiq0tylNklgYV0239KHr0pLxsHtQI8pE5roxwtaEZ51LY0JHk8Vnz9LrsXlfGxOwADMjEAtgAAAAVkACAAAAAAEyHSjPgJJWHxmQ8T9kzQN/fTrPHIb/Grne/8o0soGM0FcwAgAAAAAMrJ3+hMQ8ZTGeCLG7B5hWD8DknaIPFJqngXDRoNoaWGBWwAIAAAAACKAfbEyEwav6SjmURSEwNvQvgXy0Q9bjyTdYMn+lGQywVwADEAAAAA5xteQkB5VtJkFsdEuD8+U5Ci3bYbEUcc0aAt/2V+nxrR2cIiY8k1VS4HEBVv+9PewwADMjIAtgAAAAVkACAAAAAARcySm8yUPNZeafteoHAX0+TSkyjVal/5Pyk7m4MtfYUFcwAgAAAAAE0O1xw/LCAXTrq+2YDKQWy4hB+yFCDhjiLTnwmAr0z/BWwAIAAAAADTN1RjxpwQo5DchkVPcnGkwNbClXqQEujl8sVOjhFB1QVwADEAAAAAb54Z1HgW9LsWyhA2nAJpiB/kCEz7MhXGXb2Hdg9dR+4juPCOqvsY8lmRsLs7PbP48gADMjMAtgAAAAVkACAAAAAAEyUya9M9junIdvrKEKNcz8cXJ/joBp6COsIyELFytFgFcwAgAAAAAMs2iEN/SfZhj9janXGS2JYljYTJYnDfJFk9sgBRenmJBWwAIAAAAACuJKqqjf2xnDwAmviBp7ceQdYAu4g4Bmdzzjptv0KNLAVwADEAAAAAFdL37T2SjsopAbfBCnx0huXtF7TlO+NOjsD6qCHpQjm82+9+hckGGYjWah8kSPd6DAADMjQAtgAAAAVkACAAAAAAhvYxi/JANcF3PpeCBQN5WFTbBSKo7jVI5KE/VX1LQ6sFcwAgAAAAADelKafNWGPE7YkxHb6WJy/LB3PdH/gfIQLZb0z7UpzxBWwAIAAAAAB/AMnSOCj+fU1okCbPvh03i4DyQhn6kg0EO9C1GPyjwgVwADEAAAAAabOklTKw7i6xeXzYoQwhNuIVXzXfAXBJV+C7czE4aQMv/4vpjbhszVgjomt7Z8SqkQADMjUAtgAAAAVkACAAAAAAC3VxrFwM2s3w2FxdX2r7u0jWfwDzXDdzBXcsg73Bky8FcwAgAAAAAPCwS4WmLaXS9+1PVL5eWaaQ7fpF8vap7GdcUpM1GrORBWwAIAAAAAC1gI2XXG/5D4PlNSqmGIgy6OcJ+bLvSqNxJlAJ4JGEYAVwADEAAAAAd1V2e7TfAKs2rmdlM5mts1GHEjMca7OeDh2n5xM93z3455zifTByJbGQEq31L+l8dgADMjYAtgAAAAVkACAAAAAAFFvnLYbuMhmFbdJo57/mfxfuL4IB3EY0RX664pPQ62EFcwAgAAAAAHZMsNQ84vTYsX8lcBTZ2j3Ubmt7vDA3RCIhHe3X6/HGBWwAIAAAAAAI+r9HXOzLPaRJ71Rk7K78XPDeR+DVxW/v4xoUJvWH1QVwADEAAAAAhF93EEO8shCG6TLAuX5ZFtd8F1Ec28N9wODrJpD1GKTf6jlkFfdxnRUwxbil3BpsJwADMjcAtgAAAAVkACAAAAAAio/KKj9eAXNOsQKlVUbzkYtloWyKFT1x/XMV3Apjc4oFcwAgAAAAAJJ8bbyK0s8eC4xr10r3RPzrWCpvYJQGIcgkthfVHpHIBWwAIAAAAAAFbx2IgyiGt6vCNxzOevZ19dv5wjbVNHm1zH3ISeh/gQVwADEAAAAAPdkc45Su0E80gbtUpUB8zwwjv93vTJUaM/g8Dlua5G7AuJLWh9kR8zyFEKQJHVf4OwADMjgAtgAAAAVkACAAAAAAqgVbYjPHH43lDnrqCZ8t4QZhorb3pSZl54axc+gj01YFcwAgAAAAAMxH41EFwqQMtd8wYddndFgjFJ1DK6RAqQOCmbRnVbaGBWwAIAAAAAAin0/3ZMo5HikTsA1ca9fDEmGNOCzX8l2lhx6c4psz2QVwADEAAAAADTGsZMF6NDbE3u792TQtLlryMBiaRU2ai+m0U7vqRdlFQVuFBsFCkxql3IF50zjXxgADMjkAtgAAAAVkACAAAAAAfJy2MxtWjWQjju5WWmPZjvWgZhFuAZI6RxlxUy9KGjQFcwAgAAAAALiN1uRaAJfmSMUoNjqH7Z2ZlZx5U9BgEvdTBzr7riXaBWwAIAAAAAAfYwW0TZkcj+fM/xbqxeefkTuxL/vVN1QcOkRnV4Xi7gVwADEAAAAAQ7TKNn7FE+9Df5ZCMngeCxgiSwGGV+VPav/5VhqxaTLS2XSnA1yJ0875arU43miPmQADMzAAtgAAAAVkACAAAAAAHbm4GQmJ6rnLsXNqoVGjtlJnW15FWDo67Go+lBTSuscFcwAgAAAAAAlFkykDl4lAC6LLKEUHDBazUjOTW5gSXp9MTJzzH3s/BWwAIAAAAAAYbH8rGdHlwBFrrVV0Ns/OXYisFGVkCXPxM7H7fte8pAVwADEAAAAAruZJC2/buFJbwInc6f21Ll32RKyNDej4RRyOiC63oZhfqx8dwY+MF8COLtB2kOxCgwADMzEAtgAAAAVkACAAAAAA3TQQfngK+iTCDF/VOQPVQ1QapOABUEy9xh1yik39BAkFcwAgAAAAADXhswcgFD09oOfsGhNE4ZSXwNAp4ZNjGi8wp7qUgQSMBWwAIAAAAACFm//8ycxAiImo43SFyna01jip/ihJDe9Ae0hsmA3/zwVwADEAAAAAu0cPhIVEh8eE3QjQCJeUm4g3Yd62eNqRB2vU4ZlDbAlg0TqtXom/Bmt3RBZFJBWnbQADMzIAtgAAAAVkACAAAAAA2omd4GwqQZvDRx8+79eOznfR3oAkN6HeolzFxGL6eJAFcwAgAAAAAKbirsCe4EVDYDftfrfuGO1XWzn1p/dhyXMMymJUrrsqBWwAIAAAAADaP6Wt/9cxWbuTkXgZMiDMMD9y/79WE2TGNDMvqzs1WQVwADEAAAAAJT82q07AURr26T0nk+DyuaGa8MhgbqIeH+ebjugczRPcjsuIhZI0BQB0bGfFJii23gADMzMAtgAAAAVkACAAAAAAHMSO7pJAxBXrOZC14RQpKx/ephfDcsyOw7p/gSF9RJsFcwAgAAAAAAZMshh8N+H69W2+nnbxZc0Dh8iHNQ6nkR1yHVwqdbC7BWwAIAAAAAAgbyAhVqY8K+fuo7m4/3wlbR8tu1ozwZHlr9Id1YVKLAVwADEAAAAABQMNOJIzPqMORv73VRBd2fA/uVoam28mhPnRMJaQgM61g2a40sgUyyw1vUm5Ux6aPgADMzQAtgAAAAVkACAAAAAAZeC1NLNLC5+6ybplk5LfZ88L8nZo16bTAdLDdd77aLEFcwAgAAAAAKsC2qTJP9a7aoSuVSH+5Ru2rBlMxA3/7eYu+/9gvEL0BWwAIAAAAABi5ED5SOSwddk+cLEF695tAJCMrcg+EjE/tswbQRNikgVwADEAAAAAFFSObroMlZCJAA+yMiJCC5uNahaEQ8NaIRpFkInnrKyZFABZae/VIiWhCT4JoUKp2gADMzUAtgAAAAVkACAAAAAAa7yoFzx7ivJdbdWswvVY5gWIvMSx0QUFfa3HLWBYf7UFcwAgAAAAAHFD6Leo9wNToX8j4K+eim4Na2AqJMQw5t36xsxpk6w9BWwAIAAAAABynrJTipWxP7q+3s9POJa0KqEKZS7oogV3UYzuO6zkfwVwADEAAAAAegGa22z3mJ//CYPOf4mt0f7UCG5ogbn3Wx6uMh2tlc9n/UhdijbROLbFTeEbj70lGgADMzYAtgAAAAVkACAAAAAA0iTVUiE4uBCw9y7bseV4cU4ahCHb6ZEglbAv14i0WMcFcwAgAAAAAJ5Tgpr/U+2voqTcmpF3eqE+uWE/s3eLsqNdudvwO70MBWwAIAAAAADzcEnL6IT6LccSLYIJw5Jq5EOLl3XnvqC6e6eRp85DGQVwADEAAAAAe8P1v181QLWJd/jqPoMDzTA80HMDsph7e4EgcYQ3fYbKo2f/rxjt8fBOCUMnv+yiwAADMzcAtgAAAAVkACAAAAAACbA/xUXrIuo9W5vt8Z1KlBeofBBmWHjZyUmzNY8LaOoFcwAgAAAAAFCFp0lHPhrMxItLjRPv4ioLkhBFNpGg7S1X7cbPM1DEBWwAIAAAAACMkUyLfiuiOezEkgtVjTOxMQ/C7s1hgzbCtUVWAQJ4QwVwADEAAAAAMfh0yVrwidxjCLd6AbeRhC3b9n4kyU09xps5cLTYZKQyT1S4tBVvKkYAQkzld5hkIAADMzgAtgAAAAVkACAAAAAA8xLtqV5mqEuxJf0Z62ZELWnuYl2Xjn5wTZQQlAvQSV4FcwAgAAAAAEE8WO03WzNXt5cI/nH/+Hy+TAk/rFvnYZp2tgX3DpYXBWwAIAAAAAAAY2+NbQRSmJsEwzT6A0SGzWB7JSbbLGS2FZ3ueVhnYQVwADEAAAAA33sPOsCJ/3iXVTwzDzHAzEEhGLcaVzlsVjk6zrs48SZq1/V4udEI82jToguOxfOs3wADMzkAtgAAAAVkACAAAAAAathkD6mmM3Ucjx4ANURY3OdLMRfj/lMwRRSZuRcWAt0FcwAgAAAAABNpbSVYGggb0tRD5WpTCNPfq4tRAZA/nsyzIy0RsVM8BWwAIAAAAADHrlIuX7H/ryM40DU6UD5CnDPmHYfyb2VSeh/pzXtmgQVwADEAAAAAgk/6PalD++JLi3fBRXd8r9He3h9wfKE9SybMAIGGy7HZe/28NHXTR5KcPZ/sNmscfgADNDAAtgAAAAVkACAAAAAAVljiTiqnN5/AmxaH0uaZhSz/COxyS1vU6urQct31Cb0FcwAgAAAAANCJp9g86En0OOLiVgyiJ3LnNUPDiqNsLhifJhWsuNvkBWwAIAAAAAA9QB9LSbFrrVWQN/L+dbh40SngimQoMgwB4RtG6gpLKAVwADEAAAAAWwtz0prBVDY1Fxjc09XnoAdWDzPiy39uXpONBd0T1gLR8mfE9Xk23snZf0UgG1y/CAADNDEAtgAAAAVkACAAAAAAao++Bs+xPLO17LeTGXhMW7IzBsrTn9daAhNsDpHb7NIFcwAgAAAAAD5YL7hA0vMPDyNZXiHMzsQA7nA8U7yljwqQCWRjnNRKBWwAIAAAAAArH3x7KkTVJpGuHKgQ+Z6g9VxFjK9WfnfLnCUFP55k5wVwADEAAAAAHAVqSf+JHHF1yKZa9rMTEd9iL5zsvbkO5asr0ma0+HZo1fqxx8XuCDsUnc8GUHXMagADNDIAtgAAAAVkACAAAAAAheOgHdLaUJAdLP0+N61HJr7QOarHMRJxnpQURXPnpnEFcwAgAAAAAKyqdxuehCAfVW0qbLJd719f2hAZNkBxKpwewzzujo+LBWwAIAAAAADp7QQHhkH6nL3E50cnLcUgfTXbDekoP216e9CEX5kZeAVwADEAAAAAUNp7ufkjWPq6RQ3N4VhEmG9XgHx1WLOIgfg7+w25OQ/JBGj6V6voLLnZt1BglHrNcgADNDMAtgAAAAVkACAAAAAASZyQhJAHSH3mZott36C5LGbta/+fZDh3yWAJqqeIUwwFcwAgAAAAAOI+UnX3C+5amHNqSNnxTnZW90v7WdhIHgAYq7p/DtSyBWwAIAAAAAD+P1v5VlAPvheCVELcZidSZovBo54Knk7Fa3sl80CWcAVwADEAAAAAXXMoJunNXrkUp6tOBucYPp6QYw6CGtGFw6h243mFPkgwzmEVAwIr+2g3y4ZbaY6JLgADNDQAtgAAAAVkACAAAAAA2X9aQvgs7lQy0gP5aDjzpiBpq5rH7KuxhEQO1dPWeA4FcwAgAAAAAKrp/pdrg3xiGs6C8A/2NJTIp32T4wPCyN5MhtlbyLgRBWwAIAAAAACkkkO70rbyzqOO7XMCqcsBASPGXIwc4+e0mq9rc+BD6wVwADEAAAAArumNNLrXuVKJjvwFrZDBAE+0YpCLzCvGgDlUPqUVgpbIr6fyb8k6D60anGMANoX6/AADNDUAtgAAAAVkACAAAAAA7ICu/+TayxQMgStNgQDdLcYMnfAOvJ7DyahEl3X0u1AFcwAgAAAAAKsQI1isLnqymW+Ioke2Ms2eAszJGN5w0HMdVuUyo6DEBWwAIAAAAACeCREvt1856DUnn5fuE6yo5KDwaZq6jFXQCM9N6K3bEAVwADEAAAAApCG7V0V9fvrRE7U4UdHZ77AyTB2s0J9KFE1SlkvG/yJqDBPuaIev5Tm1ZkxDKks0vQADNDYAtgAAAAVkACAAAAAAnKfKO4lQf9I694oRIS5KD/C/5bMqAc0ID/cOjYo9a0EFcwAgAAAAAOrymtXlN8oI5923BbVdjadLBUE+S3U3pRFgfmqmpYP5BWwAIAAAAACgPmLbjBJEWKrc/13dCj0i6GMxsF8WZpJVGf7PWCPGzQVwADEAAAAAoewqaqQ92rXTYUjEdP+V0AGzQXrRSxmrdA6VUe6dhswdFJCtpqapn2a4ukQBj3ObzQADNDcAtgAAAAVkACAAAAAAt6Ma+U5PqtFiECWJttZVBmDoak4z/BqoAc/EQBBi1bIFcwAgAAAAAF7Q3MLa1rBfWMSPG0zs5RefPtfmkgfbTCMD05AN06gABWwAIAAAAACjvS7DyGKARmDiSijxc7eimGO5qqZ6xniMC8W6Kn2VZQVwADEAAAAAj+YZxlHCGET+NXTkdrntaUlCM0RQaokTPwdiYaH39tullnZMf3/0QWb8ArQqDNzrTgADNDgAtgAAAAVkACAAAAAAHnekwMTF7Cf6d4LL0+fmwF8mvUSz7lY/CMaR8Ue1Fm8FcwAgAAAAANgJNjr4Flx8yRn971dJJhkK2H2xPFcrwxMJnieA7qcVBWwAIAAAAAAotvhpiM8dtovs6+0h/EVo1RX7SZdCp3fL6dotSVJIagVwADEAAAAA8naJV6CMlGHNz2ZcyhXlXK3zCcMJ9V3wBvRqoK+RyKZXz+UYbgiz2hTqwjLNNpjX0gADNDkAtgAAAAVkACAAAAAAV8Eo2SERldnP84wskU4B2s6+O46URcd9TBajDzRnOZcFcwAgAAAAAJGUJ0cToB2u9meDXhgj8wzkyt+g4BQT8alylh/PquzCBWwAIAAAAACvoyI1QcrjCt++SaDkLblbCa0mSNSwvkn78PLO8PbUUgVwADEAAAAAgPu1ktLkczLEDYWX9D1AgzGRfwt4kDqZzOPcrf9VEJiWvZ2+gIHriOo+DfdoMmkUQAADNTAAtgAAAAVkACAAAAAAFgYfkMVjkOKH2I9LfxLXocgVSwGJuZKkacnVTMwZKToFcwAgAAAAAFo/c+ZxtaA/+dG28HmSikf4ETIH1E3n+ehSSL3vXGMNBWwAIAAAAACj85M7KSid7Qzw4/hZaL8i0aaKXJ2St9VYSB6cSq8QVgVwADEAAAAAjnw+FwTtj8QnxQ940WwJXtenrlqBpevnFzldjNjdbPdCEervjpAXRyJ0D2T7aa0XqAADNTEAtgAAAAVkACAAAAAAE7ePWPxVFcvH2wwNtucFsS/KMQvBgoFAFDisoFRYcyEFcwAgAAAAAI4r7SX548gjMFuhQqms82N2WymvtnN6EkjluZx7zL32BWwAIAAAAAB8mw/RVgj3+df7HC+eELuiUFuuio/Js2yK26nE5End+wVwADEAAAAADvNXgZnkf++epaw810NU9+q7SFFIXyVxN6QOFuNBAKMqO2EQ+IZ0DqROFw96GSzs5gADNTIAtgAAAAVkACAAAAAAwCxOYz1NKoGZHp4qHrVq9v+3QmyoZkO+44a/uVIFI3sFcwAgAAAAAI7aO77woBZy8gMWRTNH4UhW+bHmDz6czEq+beqz03aXBWwAIAAAAACPA/FlSQqWXM+oQSFQgROCKdTBlGz1Y8AVwxR4hijdFQVwADEAAAAARLanlMPIQ65AUOg0Flf1+iBanhK/D+CZDXkSxBadjhxmtfCqUeXvuvjh60uPMlCEDgADNTMAtgAAAAVkACAAAAAACxEOgKjKVviLizw03DV2+19BOVauCQnIHeXCs6o1M88FcwAgAAAAAMig5mSsc9gN9AbWFsz16vYjXdt7Oz5wo3vNz3rWtcbQBWwAIAAAAABvnd5BKURjyg8HoiZZslVP8zo+eagaKZWNCa56BDL2aQVwADEAAAAAqLHVkLtbqDtoDYNW3O0ru7u6WLaoo5nF3hYl8jmoPmw8DdvWqjQKmEHSdD2OSrNqYQADNTQAtgAAAAVkACAAAAAABXylfkQmlOnzeLgsDjUmtY11pf2HeCw2J5NYL2+Dl6AFcwAgAAAAALgFwT1PjEpZejQ3B8wY8/90LLaXLS2ZP2HDmoUssrM6BWwAIAAAAAAPgx1b5dGMdkLEhksBMTlKI2pEprqV9qdIVRXdc+DDKgVwADEAAAAAN3/V/sZHPKuJejxy41JVBxge3JraOWd2ZsQPdVSAHiQffzwHOIsXrU7qAkHOIYeUiwADNTUAtgAAAAVkACAAAAAAUubxf1hn5VaET4TKigL+R/S60FWDwnT2DJTj1s9qf5YFcwAgAAAAADNw9vOFGnYszYbw8cmj5VKNnh4NrbEllAIYxC9mdXAEBWwAIAAAAABQycJroBpAmZZPI4V/iQoROxCJUm6JTugWDKFyB/GwVgVwADEAAAAA6rGKqO05mjOBOVxC176SOTnQU6Re53+c/OuVdzMmq6Z9iRERCWb/vVEby4U45PuOrQADNTYAtgAAAAVkACAAAAAA6MdU56D7BHB+l2lQpneMtXb/z4bx+D5KQbR3HCJNGR8FcwAgAAAAAA+HjgGa9Oh4ZKq/J20Q2sef38DlSnXTDPfNqK0oppAdBWwAIAAAAAD2wsiEWh4THy/4xxnVeQ9EUAjD8/o02EESbjndKo7ZYAVwADEAAAAAXV3SZ0PUQhlpn5cfLAv0/fQRGMTqMfjXY/qRLj3/rInGh/lcuIalj11VvlJPbYz6kQADNTcAtgAAAAVkACAAAAAA+1wDUDcfegJYHTjWm1JmxHmAyBfkgmAUezHmWFfWwFwFcwAgAAAAANYytE+WEoNFZeUcJccZLQn/SoRaQZrfBl1SUjwdj0WCBWwAIAAAAACVUZUMSxfpM9QtnBYDTwWkCUvcM1iBzw5vpMb/28czdAVwADEAAAAAnaaTfVbNZCIIlxPQS535XVerneEcS6NXNbynKV/f7lk1hS3guPukbZDzX/xaspf7QwADNTgAtgAAAAVkACAAAAAAB+u1yi002XD8Q1ZtlxvpgXDhNNr9LLCkGE/t+ef/jmEFcwAgAAAAAFUDL1YRmiVgP+7Pbt+ruQEqFAMgcbHeI3clp5bKmYzQBWwAIAAAAAAEQ2ZRgjTVNx7mRIDIMBkntLSjH1P6DbRPWFDVtoSkQgVwADEAAAAA7cXKvQzEZmQxnYXW9JQqfyh9hcsvdEKhSCAX+ssOnryFN8rdH3eTT62UUh+wOzlt3gADNTkAtgAAAAVkACAAAAAABeBGBe+CL7g4PnUG3rVbXsQvqbC87Gtv2+BsaLO9AHcFcwAgAAAAAAaCEsSpIF6he9zZ1xj6DwMWmzN3n3bhcz7nMNxXo9w3BWwAIAAAAABWVEke4ISQQA70TOEBGTlNoedeqW/43q0L9FyGQn/pOAVwADEAAAAA9FJ3dLjd8ep3ySMYbwK9xUJ5anrXsSMdVP1Qj1/Wu4M4NqZhaBe/9NtM4ZWq0Nm1CAADNjAAtgAAAAVkACAAAAAAKK4EjDnlV6FIOB7saSFoFiw7g6ANotp3LWWIiEtp4hEFcwAgAAAAAP8SqHqBeusEURk0+Ssm6inTRXAJNM3dMZia+GvZhgtkBWwAIAAAAABruD7+1A6yl1kANLCmSPoIJJiEUmg//6YZs1gvXoBS1wVwADEAAAAA4drghEA3aj8yMKzuqr3M8NpWVcl+H/N/t2uU0NNFipH6/1uC8yt6oGpNG9hdTOLBlAADNjEAtgAAAAVkACAAAAAAd5PCIwMgds3oVKyIONqo3mH97+fz0w/isXa17xp2h7UFcwAgAAAAACw+sxOiy1mu3Mdj+OnvlXL79zI+EETxKE63O3k1FX9qBWwAIAAAAADVvFPdKaCbaBX0LvFd3Ka5Dmu5VY5Gjbi0crz5eiqtywVwADEAAAAAuE2BtMJrQMDj0QYbHMxND/+Rgx+ILN5BWwxxcjDvILdgG4+Emg8eOW6iBEFiUs1gFwADNjIAtgAAAAVkACAAAAAADr9aMiV0jmQlz1iTr0wQejc4nC8PxO+3re04grqnmgwFcwAgAAAAAP/KpIuSpoJSsF1VLkjUBUf75mbuCbw6nB/mHwQSByWzBWwAIAAAAAD5rJNPm6rE+kh1jtLgX+RXTrMguMUpDDignC5gANFYxgVwADEAAAAACtB+JUEHcZQ+68HUyZT2JX3qev+FiDXFMIi61Y3YBZf4jn1bEPkXghEMEhpz62I3PwADNjMAtgAAAAVkACAAAAAATclzZLE+bERz8JuMcHVLlKFFQYLAMJLdkSMDTHw7o+kFcwAgAAAAAOucHXR5AlYBPgslr1FJMXGR/SeRI4FDfH4iHz3j6JDgBWwAIAAAAAD6pN1KTXva6w+BQrmP6gKB+ech/bViCESgihVyJkdszAVwADEAAAAAAD3ALu4u+jZjZAjePCHMWJXLNlvdFmaoHo/3zqmmyQyGID0dHUB7a3djnhOFXTmToAADNjQAtgAAAAVkACAAAAAA1sq+fwmCiA2fQPspzdvqgI7f632VDSz5vWAm9KjxsyYFcwAgAAAAAE3Hba5X2rrq10iZ7qvsc1kC/kew2W8LyciFateP8tF8BWwAIAAAAAAfDe2xVegMVNZQLT47dQypFaIHFL7Q+hdtjlXvbn5FbAVwADEAAAAAA0ifFMMBHkaPKFCEPfuTi/IWLlg95SKUtx0FNQWTsMyYOqI/ep0aMRAXzT0DG3itlQADNjUAtgAAAAVkACAAAAAAuXOeQcu9noiVG9ryzs//MkZ2Q2wEhySSEKekEYqm5DMFcwAgAAAAACdZquJYJkAJLATfEiEJr0g8QNdCCF/p7y3vccNr1UwpBWwAIAAAAACW2Hctu4Gps+T8esFrk17BVD9RkjS17aXCjUIVvQl+sAVwADEAAAAAyvJLVubY8MsDakIB9cCYI193mFCYLKH6zvziQIXOGBu8jNy6eF8D9NC49XRL7c2VeQADNjYAtgAAAAVkACAAAAAA+l7FNPa48sKFFBQYYOi95N6FXxfGO49MbKkWZyrwBTQFcwAgAAAAAOWixg7y7WJ/VHrVdeaTcwOJE603kKZ4+dddJCo1ClpzBWwAIAAAAAC5SrcNfTcOLySUN0krstzDiHIRIWaMk/FiCJDiQ87C3AVwADEAAAAAd59ufOlU4gRupOJOkUbtqqah7pgI/kevS4xjEtBDQkg/zIvi6casJq3sBhsyswn4hAADNjcAtgAAAAVkACAAAAAAOiu9vsMg+OkZNfxbxKRldNNFGF7NcU/4xsOifvp+PaIFcwAgAAAAAFCSKH8787XSwC9akucfCzIvrm0lJ0JMBVjV6HFqUdMEBWwAIAAAAADfwmHmdChC9doygTAhLolV1IBijvlroJA2+DcOvNHblgVwADEAAAAA1zF2oX6THDuIL/zDPC5cYhgyDHQjYsnIFydUGR5oVBKoouJuRkLXXkXgu2biBu1RBwADNjgAtgAAAAVkACAAAAAAZx7VF3MPOPRziPLz9nLks6+gwjeTX2vUgWN/F77s8qcFcwAgAAAAAAaj0KSFBshMnrRX3NgPjlGfNJIEAMLfg6bCOAUn4QdbBWwAIAAAAACsmLhfW/4Ve+tSAqQfJC/pOmKQO4utELy0chXaBk00ZwVwADEAAAAAh1/HKSRZwgjTdqGeZ9PzaAFomh35O7uxBPPudD1GvORdfgrYZlp45/uUfhZu+MLktAADNjkAtgAAAAVkACAAAAAAxS4EUkBX1YHPVn51JFdhd5DU+epjTp0mwxvOXBAZqjUFcwAgAAAAADpeJg2WZo4nhyL/+9/tafq3zZQFLn86lyZilx+DYrsZBWwAIAAAAAC4Z7RZMnNzf3QxrBSTC8AipSwuxGlraMckmHJ2ivyyCQVwADEAAAAAN9hx/avuq67NS1BCWNRCwlUjcop6coljuO69dgGlmYVql2K0ZYWcCsLz+RCQjZjf0QADNzAAtgAAAAVkACAAAAAAj1dM8oEWlytUW6/7YXcdn7mgpfLWfrlESzEIvSZbN0IFcwAgAAAAAOlOcPAHzIsFFvUVBtr9vzqgx+tDpsFNv/Febtz8+JHBBWwAIAAAAABuKSsMP8bCf32yf54CO3fBE/uUEjTv6K0t732WcssqYgVwADEAAAAA/q5+nnuHImX7i5B6sX6WUQW2B/OeemHKvBqyU75rxVXzX3NrPD7VIKhZZpnF+ZGP2gADNzEAtgAAAAVkACAAAAAA34EUbtZOeUXxzu3L2NHu8gGfrd1+jS3h8RVn5Au+OKEFcwAgAAAAAO3hj8t9fSyVeA9IqoZRLUyHhVz8HB8aVkvcEO5fAntJBWwAIAAAAAAFpeJcC4vkuMAK33mF6PfXiH5lhjZR5yVGrPFoQ/So5wVwADEAAAAAqvOoid/VfqWyiBnKSf0Zsv16OmXZYUKfe93O9O/XSa2siM+oCI/bwciRIG0iGAPq5QADNzIAtgAAAAVkACAAAAAAldC9qJ9WZBLM2C3XbABfXv3dgJVOGF5sGrszzDT6r+oFcwAgAAAAANrAD/OdCo+ojnnyw+cuPn/5cGdY5LPg00/SJhimm0zUBWwAIAAAAAC1iWBW2hoA1/6KHExiEdPNBsyKzrh79w+m2R4ZvkQy4gVwADEAAAAAwHyJYakJ1naylXod5z0nYzhD4/0A5RtExnpkpK1GjoaAhLCzdixPXtxE1wHMj1uXwwADNzMAtgAAAAVkACAAAAAAAXG2IbGuaB6c/imf03BlWeSaaeGv3Ot8xEOGtEn8XKAFcwAgAAAAAAlHvcsDsXeBDJhUot5o5nMFRVBn1iVqgXKqMGeFM43VBWwAIAAAAAA1qDEga2v1tYPUPT/F3AQPMxmiA/o4dW63a80cA2jGQwVwADEAAAAAFd4J685qatsvykI0c0EBNJjhFMEGJhV+YYPY3I3tW4WNtbK7xYlEBtD3dqeef6688AADNzQAtgAAAAVkACAAAAAAzyPLqdjmyCTg8EezTf7leeEX49wr5IuTICg0qusAG/gFcwAgAAAAANgroB26S3q9BKIv0x10yx0FNeZCBqQ8mdHu7HVeMRnwBWwAIAAAAACBb/VFFntakSZcw305Fb4oRJZ5UohrElK4Ag/VHRawWgVwADEAAAAA+nSl6+5pjh1VFfGUhKzSFgLCWuOzUYYI2HhU49wOKL6/HrnfpxubbRLjbpCe/aFzsAADNzUAtgAAAAVkACAAAAAAXCcCM5Qq71nJb+LTIo4CtEbXLPMtlGqyPDDuvWLdIhIFcwAgAAAAAFD6bs7UiiHV+JCvWlvuZh1yC9oqUe7BdeYAsRASm+XcBWwAIAAAAACgCzl0w14hC0H7zAj4Vp5dJ+3XdqEtTPs+cnWaPO5jbQVwADEAAAAA28nqqRT0lh4ait0UvYt8MTs7yaSAjj46nXMgfGPoXPNKY7CFpYvi4oDQbH9nZuIQJwADNzYAtgAAAAVkACAAAAAAxk9Y2osGntAHuIjN8Gbe7sIhu8eYPyMQP9QtsaTQ3PQFcwAgAAAAAFc/y7fmTRgTIxG1cYwRJQUpdzQ6Odn4B26Hlys9Mj4tBWwAIAAAAAAx9GEyZk9lE9g7IgibF3LPjahGECCX5XQTVgZ0BK2h8wVwADEAAAAAtaLUOUgImDp5QWEzyVsKGWUlnPV7TyqEa9DY7Cj/E8cuw9Zlyw/xpfRUnwhLTA25aQADNzcAtgAAAAVkACAAAAAAEs3uyc6tO2wTQugWhJnP14BffOA3QqQUMOUvk2UAnqAFcwAgAAAAAHCwgWFp2WUeK6nH9bp9tYpe+H+sORHotCW6IwKyKEYZBWwAIAAAAABdi4VgiOA+1vcYItFeZbq1XR2zcMcf7kuknAU1tQem4QVwADEAAAAAhtOQQ/N57940BQJCoekwTdx/cD8ahAuPAqOQY+sRMgn+JyE179bmgpZ3m1TTQUOzWgADNzgAtgAAAAVkACAAAAAAmBUSm9tv6vheJLue8Y6lnmhJ8UTvMplR1WGRNFS6lr0FcwAgAAAAADuHUbrPF8rsvWuo9GAwFGb5E1/yu344qoUCxoxl+b4yBWwAIAAAAAAUIG++9dE4E+iRk9bJMcYjfViyvUEBIcDeFOGIBDvxwwVwADEAAAAADvl5S7ClDi3JEcZpvo24CW+mzz9+u2I85FmhxOyJpGJlWX6KgAA6UpiSwoMprAstRQADNzkAtgAAAAVkACAAAAAAfxGWh4M7T+gAi6BKcqxnGwF7Sk9ivpc9aajyaGsSCSAFcwAgAAAAAKoSvUWi2aZZ9wxzJgpNrfOUcP5uqPTcBQ0kN0hnjCrRBWwAIAAAAAAC0NeP3Gs0uiO+g8n5lPB5P5P9Hs35MGcfywm9H+5Y6AVwADEAAAAAHcWuC915d/gvaJrVhT5i473SSykAOwLSEOnHGEjJHqqTqx1zgl70N8QxuUW4fotKIAADODAAtgAAAAVkACAAAAAATlvhfXQb9ppGDKORyhHd86bU19SoE2rZNn3Q0AxQVPwFcwAgAAAAAI819CkjEqOc1tSB2en0dZ1vK4/yAYoSb3+fcJCqUqf9BWwAIAAAAABtGrFR76Sqk4GLtDJkpcxQ6AWdh7cALeV8rRzlxJHaSAVwADEAAAAA/SsoD5nsgy19AQwV6ajFqohd+xn8O/bEObjenAda2nmQe/LEd5eJqCQP5j8kZZPqzgADODEAtgAAAAVkACAAAAAAvEXuOCo7cIz64P+5PFP/+jDve0X1jwtsoPAHWq9Yir4FcwAgAAAAAFttuQzKono1P0RCXq8ZDrky+1bO/36B5qVZXorsCXPxBWwAIAAAAAAs5bIwn9ETTZ/9kq43rl3/FT/hrpkvY45imw8FJSLIHgVwADEAAAAAKeqgPGKeQvN37Qk3BaJGXKEuIlELDsb33iy3kEdqthFCvHtbyN6VzSsVDUG2Pf9KMQADODIAtgAAAAVkACAAAAAAAFKMTMtg01mZCGUApP5b7Frq5XRSy3Ub/akAtGdW+IIFcwAgAAAAAPVJlEhw/9KWA3jO9UOckkiwJW3RFd1PFdJzqPnjHiFUBWwAIAAAAACV0IUVha1YxH6jh5wg6mRdwPOyguRoLyNB+cIbNPJ6zAVwADEAAAAAz0hAGxbP5w/CWR/T3K6Zdrkbw+R+jEWKlqBKpBokW60Kqt7CVF9muyodBNtPc37SaQADODMAtgAAAAVkACAAAAAAr2G+nMQJegf/TzU+OUdGc3L6oigVrY+Mt+3fW4r+PlMFcwAgAAAAAO4Mq7kg7QRsfsXWVaQFikpMLqcplxHK1xzwqwflD6bjBWwAIAAAAABaKqCGmMi4KO2SU7kvJT4vW9C90OKLWIEFjzuCS/toBQVwADEAAAAA/PvwCOf8g+ihTJRYrvZZAWJD6LyhK24Jg1SJ802gOc2zrl5a8stfRElE6pmII5vstwADODQAtgAAAAVkACAAAAAAomx5sA7qdP1tVkf/CEx/Gx0btuNEJDO5r5hYGS1uY7IFcwAgAAAAAB+5SGXGvE7pdtJaKjpZwJp7tS48+PC30sFx+1mfDlUDBWwAIAAAAABeMT1mIiUK4iU+NCQ5bFGqjrezlVVFnFkvuW46roMmuQVwADEAAAAABtm20dhwZP/QsY7V3Vqhtndd9D78g8Fbvl7i8wUEG956LlPCNJPuJmyaSMxeqDDHfAADODUAtgAAAAVkACAAAAAAth8+izW3o5w3kpKzx7+bm8SqHhUaKPxghWKTHjznsrYFcwAgAAAAAFffzKrPfe8f9ZvmG39uLM2wAgu1UcRBBzz7eSYhXBFJBWwAIAAAAAAQ497cxozpDJVki4/6B1ubs5/Ygva7y++Uouu4xpmojAVwADEAAAAAebUyqPjX4JUqeFNkIFT9zWcrQ7O29QrZwoPzdwyNvWSugCwX2/Im71/JcHsNyBDmagADODYAtgAAAAVkACAAAAAAHnENcGmBOBpLw+grAYI+VK86D8LTDuQPSyosHQdOIOsFcwAgAAAAACdh/dwxuz71twmO5scOjNgWvJEjPJfXgviWTNW7AXIfBWwAIAAAAABmD1mTLHQwEetv1mmtYEKqu/TyMfeuvqn6LnGAguR3AwVwADEAAAAAgXP0iQCZOXt+lznhB3cOyKzYtyTWm9T3Z9vMq4C5uAwmFgQ09xG1LN3zRhOie2mauQADODcAtgAAAAVkACAAAAAAduYpX2r0xThs7TeSVRyOt5HkFyjVNyLg2Vdufp4n3VcFcwAgAAAAAKEz0QrxKIjQ6RQxz4v30ZhXzoJWx9HeisrMOgYfHmTKBWwAIAAAAAA16hHvBICbQAQ3n5QU/9DaWj2tbH7PGP7KapBE6DohqwVwADEAAAAAlZHGJJ5iW3t/9SnM0pJGiqP1KfMoG1khWRftut7QXTqcPPL9qEE0Hed4+BkYEOF9EQADODgAtgAAAAVkACAAAAAA5uyBeZVB3I0K/Pg1H0HkkT782YCzUdYfx6Cdpt0xqTkFcwAgAAAAANUbrL1DKYKnUYZOZG5lXXeX0QOQ/6S22ZEHOHwdCiSfBWwAIAAAAAAAZ9L8sqMldlz75KJX01wa1MdegDhofjJqfAiA0gsriwVwADEAAAAAzkwz0CCnaRX/S2x7CbjZXCud7bFS3bfhEkVt7uvAt2SnFDM0G5znjNDvWRXiCEk6tAADODkAtgAAAAVkACAAAAAAP+TR367xbcr3moPbC1LrMhVqn1xqptmjQPzLEbWxsZgFcwAgAAAAAC45if+I99NNrtfM6leKo+t00KhI8s3Nyop+hnEVT5/CBWwAIAAAAADT8URrdKR8/jDzfiUQfwMfTW3nxUwmOcps4Qmgz5xplQVwADEAAAAAqR2OD9KNXS0xB3qvDG4+FawpDkxBEJZEVamI8yEB8Ze/8vLIhcr3byu7E52YH2ppTwADOTAAtgAAAAVkACAAAAAAzYA4Zj2dVagmGG/h6xf+rSyEr7WyUl0fwIktZDROez0FcwAgAAAAAHNrEtv4JATXayzmbVooB7i83wE5U2RYSWO/JGt1YpF+BWwAIAAAAADDITxhkknItgQJwLnAvutlWOPYxhayipvhOkj/3Hq7TwVwADEAAAAA9qnxOyDDuRa9BJnrzVoIn+RN9zKViv5TdplUoAkBjRWFImRTG6CNIhZ5Tgz1rN1KJAADOTEAtgAAAAVkACAAAAAAw44xIRftC0TnPi1MuWA/o+T9ARZEF6tRfpmvV3Cu46cFcwAgAAAAALsPk9dRkFbMmg/Ds0/zLiet5t4hp5kNK68Dj9idsVmUBWwAIAAAAABYn0fDPDMbcehfT41tJNtPDDN5u4lhUQ/if3p4PhH0zgVwADEAAAAAAkt3xr/CiwAO2MDgQUzP2kjltOfREZlGUYyfGWXhVV089npzZj6rXcmK5JYQAbEJcQADOTIAtgAAAAVkACAAAAAALcO4JWzhy9IRWS6hpveSB4yA/xE6SOv7p9JjxqJ5ewQFcwAgAAAAAFrjQkU3uUHB8fNhQYTmXr0RkaucIWLTacT8rnpJDAPQBWwAIAAAAAC8RP17eK6mqchLgk5Pzuy9S/zhHFVzn9NOlmBCmp56+QVwADEAAAAAone7ayX+8KATToiHFMflIlcd9DH9X7DRFdQ8AZeQoaHsoqjiQ2oTh1aBa37Gz7vQ4QADOTMAtgAAAAVkACAAAAAAbbEkaX2MGwX89hfmGnDly/xg5YexUWPzrRJCmAJiMXUFcwAgAAAAAJu5b6rDQ/5lVfKuHhufrFP1plUXgvbNeBEdSo1rlktiBWwAIAAAAABrSu+uo4QUc5axWiOZMaYis+OoTML2eHNRtEy7SOKk+wVwADEAAAAAoBhrVe7ffxRz7kwEC7Pm5MPaBWTJEstQVlDULF612J1GtahuKYQeVuP6kbEqCDhezQADOTQAtgAAAAVkACAAAAAAN0O5zd//aYzPOYwq8QYZHzRdJ2uhRG5i8esuXaxuA/8FcwAgAAAAAP7Ji2Zi3OWOZgsWZJ7MLgs0u73KjBC8UVA3Sgycy4HmBWwAIAAAAAB4GNNbYKxvsE8UwvO0FGLjlxDTxHliReMPJlShJmvuRQVwADEAAAAA8wAuMUZAXGmi1IKs4QrDd80Dx/pGUzwnsMX3CLSLW381P9UZiWjIiDMgWwHujWChpwADOTUAtgAAAAVkACAAAAAAYdgWmhYmif6rSHZ//Im5C5DWULork0L/5y+bnZAFijwFcwAgAAAAAIaptX6CjszKkNpYeTSN89tcDylnuHzS/MrmXy88l4H5BWwAIAAAAADQ0crOTQRVyLU1BQS7uUj0tAquleg/I6pEc5H5ntL1NgVwADEAAAAACjoXct2uQw/3hh2yOGWiZPewg4ecUnmxNbd/D92HgMxB6xKcS7hEe8fAL8hlkITl+AADOTYAtgAAAAVkACAAAAAAegNnLc4MxL8/fwNnMThEZeDfQc6eVUdpHo49NPEfTbwFcwAgAAAAAJx89W7hKAIhHuwASs8FXljKyX+qdUdbT5QYQmG93/G4BWwAIAAAAAByCJT2VOszNUkx2/wnQwhFsFRHLYnxMQAVOHGKkEM9ogVwADEAAAAAda8OOijtYDLlkU9ouL+C87DRGAtGZVSEyFldn3ys4yaUHx6MgyJMmrIDzxbJXR0XuwADOTcAtgAAAAVkACAAAAAAiO20jowXBHW+lWMtVq8GlkkWDvn71JnCQ76raUfGjJEFcwAgAAAAAASTo9X8s4XbOxfPkmTGjJq3Ukq9/ErKoNM0NmgaOOmPBWwAIAAAAAAG08cKyZPtDWjLTTSl9ASNKo4F7MwWAHYPkkHODkHtCgVwADEAAAAAJkBY45KbELBSIw92spUQtpuBZcXnRx1s7wk1N3WkmiVLb7MhLLpiNBJuA/QHMFCaBAADOTgAtgAAAAVkACAAAAAA9mFP1cFLScbLN6lqg7OOlCdag/VVyq6fvPNl+euCve0FcwAgAAAAABb1Wjz8UxSQFz/vArL/IbMp1P+HHRwKDLbCcqReaOgNBWwAIAAAAAB7VICdOmgzKM5QPH8jY3XgGo8dCS8y8e+KGaOb9N3CqgVwADEAAAAAdG2/Hb9K2rXJBqXoYypm7F+jEE8af3Rb4fsow+cyjy+4v6Dsq3sAllJmmuY5NnuVXQADOTkAtgAAAAVkACAAAAAA7HrNt9jv4irM77uZnWn/dXehbJiBXdkB3cPdIiJXFZ0FcwAgAAAAABULBU+X4tgY508tskrWxdA0pAR+K7Ih6l4kOejDa1TdBWwAIAAAAACjsPvDFfg0t+NslniVOKr5BQ2CPr+T2/pDL951ZQHFNwVwADEAAAAAFLnT5pM9IVZgtzp199ceLx3qoCuVskrRa91njbp+3S5nIfgNmSSCBLF3lXF6eyEsrwADMTAwALYAAAAFZAAgAAAAAMce0iNChW2gdqAFeOMKTI/JSF7v1fTIswi8mh+x0pXsBXMAIAAAAAAXuyF/uoiRQjXhS8hWTWFx67wtM0q1NDIz4zoU8DF5KgVsACAAAAAAzisTNUvFpc28dV9yS5tpUQ6XCR1WBBoo+NuwLo5lxF8FcAAxAAAAACUtkLTxPZKWKFxbEgXEORsyp3gEc9NHy2BsFq7l4H0TGFc3UAZol02p1Qihw4UxLzUAAzEwMQC2AAAABWQAIAAAAAAPh+NIeRXJHD+I09A2hztm3eAnsPxrLGsJMloXlDjfQwVzACAAAAAAQzC0DTUZSw8BiI+3R8Obx659ZtyDr7pPlhJz7kRhJGgFbAAgAAAAAHn27uOIvPP/1ihOkU84j96M+SdQ7S/wkYHva/mIdZqxBXAAMQAAAAANhRB/wFondkpv+C0BhYfvK2bZtHzBBVvXAAlEXWIRiBVcG2OrE3wJeFzlBR/QEM96AAMxMDIAtgAAAAVkACAAAAAAx6Ev6ilwmpT7RU7QdVqXDeoF35q+lwORK2V7uXIZ5m8FcwAgAAAAAEajmscfDcsExWknLP9OjEnyNvhvCNylLJkpabxTQvXcBWwAIAAAAAAHYd1VyPWj6LLZ6QQV/l4xnAcPqSPx89nVdyR/VbrZ8gVwADEAAAAAB+GxYA8OBu5992JayqSbSvuWEQs7bgRB5WuLNw6s2XaFUjkkBpYqpz16tYk/pYBo7wADMTAzALYAAAAFZAAgAAAAACV43IbGVp9qKF7SxuCDZ9Hs1VkqWbOM1AODRlaDkEDaBXMAIAAAAADZBkOB5PSGYIoOPYPrUxSlUHgpz9uaNgTChthGUGnxGgVsACAAAAAARQWv9ACJIlV1ZCr1OTrwo8dgqJdq8zXJZzJGqEDKq64FcAAxAAAAABxU4xz9OYykC56I9j3tr8KdwU3MAfO0ajkbLwPxcz+ZT9cGr65abrkCjHaDrVAbqs4AAzEwNAC2AAAABWQAIAAAAABQfXa3FNemSi3kj8sLJdjCCjmzFWax1pdX8QCtZKp/lwVzACAAAAAAryd2LjCOfmHERDsXjsfFq/0P7V9dA2yVg0Ykr+6NgYAFbAAgAAAAAPhhpEp7wr3gE/EyHQs0lAXWOVTZX24nrmQTxa9/cQXfBXAAMQAAAACGEYjfZm/OPlqwxdnaE2eS14FVTQe1Tn2oaIWRBVunzif5TsWzUwQvLNrxsF3UBHRvAAMxMDUAtgAAAAVkACAAAAAAZ+CKRmHj3F5D7HaRPwXhRhNePRULn9d62AMiSZ1JPrIFcwAgAAAAANeLGlCLb6Sn0iW6g5q/Kn4L71WF/SLvwz3brj0hnXHQBWwAIAAAAAANuN/lD3YyKnl6IOyv9pEc55by8NIlBgVXQHOnP1vdGwVwADEAAAAA1MbVVc9J3bC7uC++RwLnWKg96YrAYU0kG0g9Drho9Pp88oNcSmfMjSr9ufKQXT4DJQADMTA2ALYAAAAFZAAgAAAAAHqnXSNUFkWPeKZ5bFEtySDjCw59mXtIt8KZqxZFVl4GBXMAIAAAAAAHx3kv84ye4DzkFhfFLxDSnTlB16S6ZVh1JHYfN7kLdAVsACAAAAAAD+vki1ifi/nvuo9O1OreFcvuqd5AJV3px0zEXRqNVVIFcAAxAAAAAJ3I0eiJbRk40/Q/KS1hOtW3BEPr3yEPgxo4AJeK9zdEGT59oojQy+BSkJzFEE+LCqoAAzEwNwC2AAAABWQAIAAAAAAY4zJta5fX2Tqr7gzZ3QARXVVlK19CPJCfwkrMU/lZXgVzACAAAAAA5oB/PZ21vgYKvptg1uZo2eXIqP2DWDEAtzartIQXcWsFbAAgAAAAAEJczcCVzaezemle264SSgYC/fhQBp6XMpnTeW8yyHRsBXAAMQAAAAD0IgH+DiGy8H50sjNgOsdcQQKC8Mh+hu4bkH/8DnYcx+iIqBCtOFnRK7RwpYngYmErAAMxMDgAtgAAAAVkACAAAAAA7ANuRx2jJIucZGmDTv1btFiJHDcUlljLIzanROdo4fEFcwAgAAAAAFQFLSKNyEYSsvtzHqbYMbNMGM+wJoiNjT2xYR9rooA0BWwAIAAAAABMtd5VrVPS4BJKz5SFEc87n03Z6zpEcss03+g5F3AVUQVwADEAAAAAkeuZI+XYnuzjhp0aau36/FVefNrk/+h/6bydqnFyFNE5oa2nBazz2iYCWNJMTGc0DwADMTA5ALYAAAAFZAAgAAAAAAPibWFsPWAvXr5AgxpkeEZpVMkMUEz7N2Oc5jlHJJBWBXMAIAAAAABy+Hv6hqUXk+IarH3rk1dj7kILAQoombrxskMWEB80HQVsACAAAAAAtTTXDVngFHbYcfQw0w3WBXxplJlUV4vGlcEgeDDOMq8FcAAxAAAAAAy7M3x9gjze5Mp679wRE2brTNx9RQ7MFmZKrlJROBtAZbjGffZJrfVyl8oXc5nzzgAAAzExMAC2AAAABWQAIAAAAAAVGmrXV/jcZR7agxNXTZPBNrHGOWMfN0jOVUWfGw2sPAVzACAAAAAAA2/miUiZwHucaHSHTdB8FRaE9uxcH19OfY4tFcGqyDIFbAAgAAAAAAhxtIx2PmwwBJDo3621iSonkw1v74PdvJw7trjWvOerBXAAMQAAAADHTAJI2hASMc8DpqcxJGEZh7foFLy+w7AAG5igNZU8Vm8tQz3SNHput9Wq5VpHkXppAAMxMTEAtgAAAAVkACAAAAAAxBiqySsPkuapaDZDvfQfFLBOzjHC5h7Sg4MyQ5ROoxAFcwAgAAAAAFcxaN3aDhFuUlpD6zeuhRLTEaGs3OZ/wU5LeGvZP5GFBWwAIAAAAABpkeQlD/KHHWTmKcxyW758CKbe7xBLGtwF33nZfPGufQVwADEAAAAAYvc68jEzkEsnVixX+TrUDmHil55CNdoULn13/Mfdh4sYpTCocftbGsipImD0QVCwegADMTEyALYAAAAFZAAgAAAAACxNfjf436+QGolaPz7XS28P8hUFRtY6YJAfqk3Pf1KCBXMAIAAAAADM2rJLmPshEfWbm3K4To8EOjwUUn2hlfps2Rjiay0PvgVsACAAAAAAJaeKOzSY9zjqnnTinIap2xIPjd0zt1jd9sbtp721MnUFcAAxAAAAAO/CDlhXsCFPuPSdl6I18GZEjoJfdzixw8mFxrnlYwWgBRHHXxmMCq7GNY+H4tvmchIAAzExMwC2AAAABWQAIAAAAACIDrnH9vERI5PChxSa0qrwW28jHpy3buQpqWfumfJRogVzACAAAAAAq7yp1LUuGriunoC7e8+OSx0POi22x296OZPu95R9DvMFbAAgAAAAAMgs1n9pJZO/f4qlN1Rj1rIlK+rJuy27qYnTv6sZr2LaBXAAMQAAAABassHul5tKdvRaqXQi9uMmLJhJtITMejl7xgXyhBMAJo0tbj/n4WgpA7rZz51SDMicAAMxMTQAtgAAAAVkACAAAAAA4ZCAM2RJqe1ICafnC1/7puyTJPRhximzjegsToLbbDsFcwAgAAAAAHlbGPI07xbgR5uMSshE4zN6GayzNMd/z7FuqFzWY6VHBWwAIAAAAABeReoJfq2O5D7CRBmp52NW6HdJjbojwuMUX9AfnlGymAVwADEAAAAARCq8g6oxOp94nLoGujCyr5V20n+hZDtkcUj6J/Xdddyr3kTEph/HLgAaOoqt6vHK/wADMTE1ALYAAAAFZAAgAAAAAFc2dP2QlM+bSFMF6RkUYrvwL+fRUhucIJfmcunjzWkPBXMAIAAAAACPvTIEvmnxSzBRitwiDYOjPO2DW5g67t4sBv3e/LHTmwVsACAAAAAAoKcayqwwpfBH07phKyw63240ZuSjVeSEI0WexLy/OhwFcAAxAAAAAEo5pUxBWLB1Rz8T/DfYwoXLoI4YXh7lDnDPgZtQjT+W/mKwaUo85O9k5zsSd8lRCacAAzExNgC2AAAABWQAIAAAAAAsBnjB5uPJp2n9BK8C8tbXM+QcxTCJM/JEQbIH76OdXAVzACAAAAAA1c1hdNQfdfF5sYYxItQF/eHg99xJ/KJeYnBwDhtZWf8FbAAgAAAAAJ8mFbhGXrrYtlMor0Fq73IrG9/1LRihwJ77PjwHVuF/BXAAMQAAAABNDH5hxZTdHX4B8G6Q3saNBiuWKMb8bzv/uE+c2Gg1Yv3g1Li1oOtX4UPBxYhOTfbmAAMxMTcAtgAAAAVkACAAAAAAJxXeoVDaOAGwopuwJOPxqkgyJMGvh6rly12jJ8DSbVAFcwAgAAAAAJP8Idu4PGsysU5UwksYt0Dg8velsH9RgQQU8r3gMMFJBWwAIAAAAAD4KDZLmeYvTbtax1cj+sus/ENxmxvkASe01rwVfM8wtwVwADEAAAAAoCHCVNNTqAQ/MA0kJ/p1do+iOUeGHBPvZBo9DdCFmQSvJ2GTdjhixLVxHP9joHjVTgADMTE4ALYAAAAFZAAgAAAAAHcrdO5ANRwtjS4Gvs/7sYlPhu/OVSyA8DQT0uNaMZ70BXMAIAAAAACq3RuoMnUKbjIMjI900Me2V5P231pk5ZEMu72PivuDDQVsACAAAAAA0LJSLlIVCcoL4ZV3HhYOYGbSbwAvWHswlvaQAShZjTYFcAAxAAAAAHk8IMGgJrspOIKTH5Ew/0L1ItNdlyLiRT67r4IF2g7YmCND5AOJqBxMlIkLFueZ0rMAAzExOQC2AAAABWQAIAAAAAAKWvkcygSCpKZEtKhwSfTiUdf7VCkBCllkxcrV6CrNGQVzACAAAAAAhKVqvO/JGwS2KyqoCp4Pm8Qfe5ITgMB/04CRC7+u18YFbAAgAAAAACkB3Mz0ZFYytbyqwZneriey76eq+uatwXevMlOZ33lSBXAAMQAAAAAbvxM3sQUI4lgJ3aZL/O+9nX1pFDG+LGUWJ/EtQ71VTMJY1YKCYjVAgWTjgs8Jzf7AAAMxMjAAtgAAAAVkACAAAAAA5jB0UTFR0WzjZmhzWywPQIhacjBXbUY7ZrWkyaUhEcYFcwAgAAAAAFU/PCqOLr1ywT03gVJL/cSLLPVy0bYFWY1hz+Tw5ruSBWwAIAAAAACqvDzfjUGvr2RS4QCNqs3A5TLB9sR8+UfpUQzahsqjjgVwADEAAAAA3Us3IPBp9bOET4GQ5g0UBGYuKO7ZwX15NYbdtQKqWhSfOpCiHlQKZzld98dw0aeNJAADMTIxALYAAAAFZAAgAAAAAOCngelbX7QKsseFwdvQU/WDrGxo+c+ApIBUrHapVcyLBXMAIAAAAADDlGsaSEXNZJqlmyFwlxgRolJsNCa3nnXLq6Kg++un+gVsACAAAAAA4sVA48x45lTl9JEUMXgzWpxqW4qFQAtAE4SR0tgN39cFcAAxAAAAAPhdQ0ryj4Ito9A5uzzVCtCSUehwkIHrPZiEenQ31bWaZgrLGYgrTkBC8oJvZPT6T8cAAzEyMgC2AAAABWQAIAAAAAAXjwmaT3kRxJKg5RKGEwAKRM+K2xQECTqfQIOLG+rrZwVzACAAAAAAue51dQfCgeuWXwc4veJ5AzfX+MpEvWlTJkjYhhV0CmwFbAAgAAAAAE8J3g3jDvVo/9cEsNgpYd7/8zEPJSrhNIaOmK0t2ljHBXAAMQAAAADYt+vXPy6dCkelXiStqka6Yv8Gdfika5dOv8ug35n6fKEH35lGOZ28wNvT3uEzf2YsAAASc3AAAQAAAAAAAAAQdGYABgAAABNtbgD/////Y46NN8CHrb4J7f/fE214AP////9jjo03wIetvgnt/18A", + "subType": "06" } } } ], "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -28,7 +30,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/mongocryptd-reply.json index 0e98fd4..8cab527 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-v2/mongocryptd-reply.json @@ -34,7 +34,7 @@ "path": "encrypted", "bsonType": "decimal", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/encrypted-payload.json index e4f3bb3..056fb08 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision-v2/encrypted-payload.json @@ -5,14 +5,16 @@ "plainText": "sample", "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "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", + "subType": "06" } } } ], "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -35,9 +37,15 @@ "sparsity": { "$numberInt": "1" }, - "min": 0.0, - "max": 200.0, - "precision": 2 + "min": { + "$numberDouble": "0.0" + }, + "max": { + "$numberDouble": "200.0" + }, + "precision": { + "$numberInt": "2" + } } } ] diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-field-map.json index f8ae79f..12e9d3c 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "double", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-payload.json index 23dbb35..aecdcc2 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/encrypted-payload.json @@ -5,14 +5,16 @@ "plainText": "sample", "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "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", + "subType": "06" } } } ], "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -28,7 +30,7 @@ "path": "encrypted", "bsonType": "double", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/mongocryptd-reply.json index 2ec2fc4..61d03d8 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-v2/mongocryptd-reply.json @@ -34,7 +34,7 @@ "path": "encrypted", "bsonType": "long", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-field-map.json index 336446a..dc7bd33 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "int", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-payload.json index c6d791e..e8fb207 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/encrypted-payload.json @@ -5,8 +5,8 @@ "plainText": "sample", "encrypted": { "$binary": { - "base64": "C0MRAAAFZAAgAAAAAAYUuQ9Y1Ie7prKiZXHw9WYEhXcFQdSn7mmkPHFKGAEqBXMAIAAAAACJiCpdKff5FC0BawKHW+wWtxyoXymVQItTooswHY2SMQVwADAAAAAAnfKX2WSr3o8S2zaag8gMImdCNfErp8BkxXFlb1aNkPcwyDuSLm7gIXzlP992WjKFBXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAEAAAAAV2AFAAAAAAq83vqxI0mHYSNBI0VniQEtG3g+8K9ns3yzddqS3RKsq6kgPgWw9BNVlehfV8GQOeTSKt8AtDMc632S93dm6vPNlcIk99BOVkiWr4waIbeDEFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsBWwAIAAAAACU7foxpUtVEMVbrGsj7RROTJB0V9IIQE+RmDywXO5MlhJrAAAAAAAAAAAABGcA4Q8AAAMwALUAAAAFZAAgAAAAAEXyPll8pDgONFsvw5VnzyCe0TNwEePYnQZeRFNW0fTqBXMAIAAAAADNAYCK38aHlQp6Vb784Eip1hnuvLCHL+EKg/cqOkSFfQVsACAAAAAA6QK+s92A82PEceXdQwfnu4Ru+VN+cHdIixK/EuNIQDcFcAAwAAAAAPTG+RBbMcNo1xxYOPFqmone18YO/x8SWFkyTUiX0Xgfqd1Qo5oRFyX8rJrHzGewFQADMQC1AAAABWQAIAAAAABT+uzCz7yxp7uN3+z202vxQ5NOV985A80zAqx86317iAVzACAAAAAAotJPQKqQGOGUkMWaWW9GlbqGpHdx8Y9mSX7tBhUz8YMFbAAgAAAAAA6eOZwxxhUyuExW2kjHcKJmNCrEPFQ9vS9YbrzP67TgBXAAMAAAAADg+kmPVJiTy4fFva2PljnBkThUAW7++JysbP0WaOb8+JHrgtW8YvKFt9Jl5WWTnnwAAzIAtQAAAAVkACAAAAAAgKjFyf0to2WQz0CThhMOSD3GZxb1zVbqwqK4zD9dvzkFcwAgAAAAABvLBwRuj7zQwVQ0aB3sEJ6ddgm8X7DBedKPxp1WrhSNBWwAIAAAAADXLtOFHx7zuX+RYrMYlOG0itP6L7gjr3SD28l56+GTdwVwADAAAAAAh/iVo21MDF6a43aBUOdvoXYzst7LMHA3ZtMXwUnxSR7ewUUIR0GcL7rdT1gnA0ExAAMzALUAAAAFZAAgAAAAABa91Qu2KZFQjidDvZdxtbiJgcgk5T81y3pdlHtXY0xcBXMAIAAAAAB+3EKOsVfcR0d87sZwagcu2biF+eZ6Fb7+fhIR2BSaCwVsACAAAAAARwealJh30VkdUvqpNoPSBdU6HuZqhWfrsGKkxSrZYX0FcAAwAAAAAMfekKz3qTMgEkc9mWWzoSt2BiSVFe1rku7ROF416pJfXeIDTSHhD5FuGMZ92BxlZgADNAC1AAAABWQAIAAAAABS+Gh2HP/JqcLgHAcXD3EoZy6le+JhXsej9M79huqmTQVzACAAAAAAC7ZbXoh9DvoT/wkFefSgsjxOABZW23Vwq0GJMlLtW6MFbAAgAAAAAP41Kdnpj6XQ3/D6IO7/EpHRStFFeMXKm9ABRnMeW8xxBXAAMAAAAAB+Sue8KNb+hdz1T3bphunDgyPK941mPBVsWZNUQMOwWhd+m6GjK7IDppJVk2nAY3IAAzUAtQAAAAVkACAAAAAAHaJxlVl/PbBGutD/bEBlT59WT//18IMxCXRS+rBe4xIFcwAgAAAAALwzXOpJWE+paqUfhOVy2fvLO/rjW+w2jF5fgEi2cps3BWwAIAAAAAAdWR7td8s9KkhnyXNcgSIaygRclVLxCBAw9QADJqiFSgVwADAAAAAAvx9IM6acqD8WYRJIbL+bwlRlRDp+ypeEbFxfFMEibYeEKYpEjnZWi0hmdnvtw7f8AAM2ALUAAAAFZAAgAAAAAJiezAizo5OYttRYE9ywvbfKDaGxX6hP/4B1CvWoKxX4BXMAIAAAAACYJbdQKs0dHVK3A5308Q21fYD6htM3arFOPa0OFWHFpQVsACAAAAAAIHYXP8RLcCboUmHN3+OlnEw1DxaLSnbTB9PdF228fFAFcAAwAAAAAOrrGqfH+Bu8pTCDouxkQ9rqjQB7Nz59n+e7BBTgxcr+1dksN/LhAitmq/eYLbmz1AADNwC1AAAABWQAIAAAAAAurr5Hc1qtwzXHy6p3Qqo5g9Y2pxS3P68Z8JrDk5XEFAVzACAAAAAArOwPN+XapA+LMq57JwNq7o1lufkPXv9RC6JT4IkFRKAFbAAgAAAAAJe0bDhUH1sZldnDGWn0xMa1CQuN6cgv/i/6XqnpPS39BXAAMAAAAACGqw8nQqUhaPzapc2jAuhPgily3jOhiv3KwAewdA7g8PwQvz6/CYr7hbsPCkOSj1YAAzgAtQAAAAVkACAAAAAA4ZMiLagfridRRfmhKbzkDw5T5V0S5kyhqfBvZn5dPlYFcwAgAAAAANo9G7ZRhNvttdgY6+vg49XT1TXWf5UE6DAFlX/AP82RBWwAIAAAAACHR4WfBFBn/Zv0d5gD1QJv1LAe7z5dfOKsdcEJaup2rgVwADAAAAAAXEyApIKBa7i/jiq5ISOwAZ5nz/mGNzMIAR7iPFbRm4ZyvnTmjq0H+QRxX+5pRNX+AAM5ALUAAAAFZAAgAAAAAKFKEINemcMfzCAv6lVctfqI87n9eRwDJUg1LA8kdYwQBXMAIAAAAABo00sYyBR3ZxuRjiXM98saXonlBzYiXgf3RANye7jRZQVsACAAAAAAOc0fTpxuPV6594K1O8wQ6J/qI/v9RVCDqbS78HrFlL0FcAAwAAAAAGZ8Ofypt2EEsmGPX+tv0vK1RsoklEPqysHOCzVkC5eTaFo2BGF1jW1foVXyEgM6wwADMTAAtQAAAAVkACAAAAAA77eZlXzbyV2AuHBIv0fs9K+YmW/tau8HIcAAAZKh/gsFcwAgAAAAAP8QuelZ/eX9I2hQ0/RLffyQoinkTVX7dn30T/cU9eHVBWwAIAAAAAAQL6NCvBkhQ9ulCrwaNULOgv7Uhfp3ZhsiTHSOF5GySgVwADAAAAAAywVUAlvbNYt/O2UYAGpmK9a6stKLgomIXxkltf1ODslE8Vg1E7GfPFnHTV+vQ+5uAAMxMQC1AAAABWQAIAAAAAAT7TqEEUeXh/sIdAUYaPZlm5PdZkQypOPgLNQzZ7096gVzACAAAAAAgiUZG8G1kJpdPg5YUxcX7dULyPO4kV7eZHlGkz9Pjs4FbAAgAAAAAIFEk9LC+wpdnt+iy3OTuzvc/W/4y7GWyhLN8YIFWpBZBXAAMAAAAAD4jIxUQRn5M+M3aEB8y8gSBrT6kg4v+UWYl7w/qP0f8suEDXkLzT+pxBCxh9XPuXkAAzEyALUAAAAFZAAgAAAAAK8IiTdn87RqrKys7Cb7BKa82lkWwwkFcGFIgEEuJPnYBXMAIAAAAAD11EA7J1kxw2jXI2H1c/slLVwDgQQEP3nA3e3o1nyk1QVsACAAAAAA5X1X8OUn8xyl999HEkY+2A3kiBF5kxbmGM88ILnB+HwFcAAwAAAAAGP4YMNi53E9IIpG+l3YkPhVzzLtjgFEJsCuRMXornEHZl5FyhbW8UOv2eS5uxnIgwADMTMAtQAAAAVkACAAAAAAYonfmvtTfQxtQFAi91yBxBbswbwptiV03g8J2tBFFxEFcwAgAAAAALDCYyJfAe8PsETOEGB8OPgvQBqPJKH9CG3PjaLmiCRsBWwAIAAAAAAFybb61uzRVIYWf2sO9bK+G4hFUN6lF2gi81rpNG/fOQVwADAAAAAA6aYUKtKtyeVQ0H3zIgHQTJZ5aOq/kO8Lrj6wdAQCBErHW6mmR53rbTVd7CyhrhbtAAMxNAC1AAAABWQAIAAAAABgs1xx8vizcMwcMKE2md7mKzsHVF9ZSly0Vs7+vYlMAwVzACAAAAAA851TQ7C+nWkW6MBZa3ucoVUnFxdMyhXDdlmKF47UMHYFbAAgAAAAAHVsIUd93Jho+eG8Sc6Z81BkhBFWqHENLCPv0io1d2WaBXAAMAAAAADaAPXQlyrss/msgXPCjTYcC90vokkHmnlMAVTDc23S9zM+P8EHJgEukCIvxL6SDNYAAzE1ALUAAAAFZAAgAAAAAEumusJlA1iuUJrW2KS2QWaAtWKoSfYITPYZh8KjMQzEBXMAIAAAAAAj2X8l6KLHNOvaadrafChrFonWgd76J/QAmu2+JqnLeAVsACAAAAAAiwhaLuXgveHtqUVzYyfKD5BDUQgxncPXmT+yr4G9pggFcAAwAAAAABSzLqHq6xOFAbc/3u0wFKh+vxpCRNiQEbT70ZdOsXZQRO58mBkdZs4aE0l6p4rCTwADMTYAtQAAAAVkACAAAAAA1Ku1CHxyb/5hm7F8Rmkp65NcNjmhdVyEDnS9yG7+4wEFcwAgAAAAAFWEoIw58HH0Pd+7+C7XpWYV5Y2UVWjzyqWe9hIOkKecBWwAIAAAAACZ6gTTH4KLa9AbPN1bpzpJUgwFZ6DvBQALNpo1C36D9gVwADAAAAAAnExNzeUxsfG5DkUfyGtMuLoWKL4ttO08W9y5R1d6IsveevV2heg6gtjf7hNnNdOKAAMxNwC1AAAABWQAIAAAAAAIz6wOrQqBXWAOmerbQckRy4fLI5AC9k5DhBJ3kHJYJgVzACAAAAAA4c2luh9MO6xSNqffZoH4SwI19i3ffdJ9iyAaGitoZxkFbAAgAAAAAI+sI8AzBUAhDs2DSTh7StO5rgbgse0idO29VwOikD69BXAAMAAAAAB5JUSR81vcY6yRkyy8dKdd96P08U2ino5bdx3m/qjFQ1eLq85mekyhTeJoHrLHIVkAAzE4ALUAAAAFZAAgAAAAAHLoTZKJZy5YVQVkXu7X72rfoGJ13twHQ8zDE3ipSb+JBXMAIAAAAAB9ddE/wdJ72pMLgyGnCb+ca3LSzAy92XcvLtnCBDmOMgVsACAAAAAAM+4NqkHv2gGmxQoteH2h4RJfrbbvEEwhvckdaalYJy8FcAAwAAAAAMtGR3nVaR9mUvg5STOnphZFMPWv1NTKcHR5/YpliLLP3aXCpkoZQbR2lnbI4AZGQQADMTkAtQAAAAVkACAAAAAA3XLraSiz1YXUer0yovv/W/54HfFhf4L2M6EjijxsIS4FcwAgAAAAAFpt+gTpi+oGzcpBmO6Rw2yWWRBw8bfljMjUQmC+nSl9BWwAIAAAAADHdvfQaJIOoYoaJuxWQLTA8S0t1SfmiJ4L+ZHSHQ9+igVwADAAAAAA3hl7R1IHGOfD4j2IT893DYQcmDKfe0q4yhzZZeqxPUgGsxoSzTBFbAWJfU1rlFA6AAMyMAC1AAAABWQAIAAAAABMvmSKiuV9tNx7pKKhKPEBb4RlXlptLoUC6XzzqwZM/wVzACAAAAAAQNp806yyelkCYf3mmkfm6CZgaegIJok0BRG3T4wihSUFbAAgAAAAAPsI3ldHLkKkInpttNugj3cAyjtn8+aYWSppd6eF4IP6BXAAMAAAAABW1Z4KH6GsfoOZZa+bdjGkA1v2GFpC/vAN6wIApEJHfiyMtXvHaJbZyYA0NqTT34wAAzIxALUAAAAFZAAgAAAAAJYJgvUdGrv/W84FtEVqOOqk3F/d9W1g2swofQJYzGWpBXMAIAAAAACCsGtwUCaNOu68ZJF9O5Oe4Xb65fP9W2veDrRGqQbhtgVsACAAAAAAhAQfZrFPepWTck9jq8vCgTXH8B1GXsOJ7gDBc6VNJE8FcAAwAAAAABmjwCYvmGFcjINULL1HMaOOH+OUNQzJbXlwSymyfII5FgbNkdj94Sm4Mk2K+At1OgAAAA==", - "subType": "6" + "base64": "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", + "subType": "06" } } } @@ -28,7 +28,7 @@ "path": "encrypted", "bsonType": "int", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/mongocryptd-reply.json index 96cfe56..85affa1 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32-v2/mongocryptd-reply.json @@ -34,7 +34,7 @@ "path": "encrypted", "bsonType": "int", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-field-map.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-field-map.json index 64964c1..d093f41 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-field-map.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-field-map.json @@ -13,7 +13,7 @@ "path": "encrypted", "bsonType": "long", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-payload.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-payload.json index 7c42ae9..f579ef7 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-payload.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/encrypted-payload.json @@ -5,14 +5,16 @@ "plainText": "sample", "encrypted": { "$binary": { - "base64": "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", - "subType": "6" + "base64": "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", + "subType": "06" } } } ], "encryptionInformation": { - "type": 1, + "type": { + "$numberInt": "1" + }, "schema": { "db.test": { "escCollection": "fle2.test.esc", @@ -28,7 +30,7 @@ "path": "encrypted", "bsonType": "long", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/mongocryptd-reply.json b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/mongocryptd-reply.json index ed460a3..7672e5d 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/mongocryptd-reply.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64-v2/mongocryptd-reply.json @@ -34,7 +34,7 @@ "path": "encrypted", "bsonType": "long", "queries": { - "queryType": "rangePreview", + "queryType": "range", "contention": { "$numberInt": "0" }, diff --git a/ext/libmongocrypt/libmongocrypt/test/data/tokens/mc.json b/ext/libmongocrypt/libmongocrypt/test/data/tokens/mc.json index 5bec1ca..8d88bd0 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/tokens/mc.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/tokens/mc.json @@ -36,10 +36,18 @@ "ServerTextSubstringToken": "dc79b64dab53c09dcbcc2c203e1ed5d88e0fed75b1e3a3a3f192ead85d762e6a", "ServerTextSuffixToken": "a69ea838e79f9c11e2d6bd54e665bf0eee4864d5e517a7c9e9fb763e1a187cbe", "ServerTextPrefixToken": "b89b65fc9274678e1fe107ff8ae485f6ba46400870f87ba08c710bd605792cfc", + "EDCTextExactDerivedFromDataToken": "a76c2da86efb5118f572180c0899a4701e574e7ca27ef972f31406cec61d96ca", + "EDCTextSubstringDerivedFromDataToken": "b30c36483986fdc61a11d84a94579e20afcb07baf042688b534d6beb957d1305", + "EDCTextSuffixDerivedFromDataToken": "d93b492c3c6b46971504bfdda134a4a887e0ccef9ce2bc450c51ce9a63c13125", + "EDCTextPrefixDerivedFromDataToken": "a452a61a74f5dbf3c321b2a9e24a9d0554e0ce192f355aa11c5489bc76e925a0", "EDCTextExactDerivedFromDataTokenAndContentionFactorToken": "5f073c558114c2ff39a56e837d64f64c68328b14ebe2f6f142304e966cb618c4", "EDCTextSubstringDerivedFromDataTokenAndContentionFactorToken": "ac333c5086216d14bcbe9996dc7c9c815625aeef47e6c08d83b348dd6bb62834", "EDCTextSuffixDerivedFromDataTokenAndContentionFactorToken": "bd9a705c59a292635101523014ae997f2f56b8ba2ab4df3573c8f2524f5a9e50", "EDCTextPrefixDerivedFromDataTokenAndContentionFactorToken": "06c4e44724305bb706e404c1caae6fff604c2b0c6809c3bcf79658ff3c93b951", + "ESCTextExactDerivedFromDataToken": "e198e94d4c07083a48bce1cb24202c7215cceee3b43b9d7c6b7114045eb2336c", + "ESCTextSubstringDerivedFromDataToken": "f3501ae0e842a204553e0b930563a69d6b260a54855bccd3c38cdf3fc5aa5de9", + "ESCTextSuffixDerivedFromDataToken": "c9b245e4f0bf009484cccac911bb82ea0eee9da782fc57325f62e60cc7cffb79", + "ESCTextPrefixDerivedFromDataToken": "7ed9d36faf86cc5e11c1ea7da839ff019e0f87949c16dfefcdafcb684aa2022b", "ESCTextExactDerivedFromDataTokenAndContentionFactorToken": "680b35d73a3f778792b8a03df267aa945cb9718ed4e6925c9da069d354032b7a", "ESCTextSubstringDerivedFromDataTokenAndContentionFactorToken": "380c456ea3c2b9d80324556931764ea22c5e097b2702e658dfe81254b1ec9688", "ESCTextSuffixDerivedFromDataTokenAndContentionFactorToken": "db3418028ec9079fe27643071d575e9f6e0607bdfee185d1380a68921ce58ff6", diff --git a/ext/libmongocrypt/libmongocrypt/test/data/tokens/server.json b/ext/libmongocrypt/libmongocrypt/test/data/tokens/server.json index 5d484de..9df3f24 100644 --- a/ext/libmongocrypt/libmongocrypt/test/data/tokens/server.json +++ b/ext/libmongocrypt/libmongocrypt/test/data/tokens/server.json @@ -36,10 +36,18 @@ "ServerTextSubstringToken": "183ff338509675d5377d09978e9becd31b197458e2c8cd45b670c672ceb6dc53", "ServerTextSuffixToken": "baf7c9392bb37607c6aa1f04163f4db8628872e7e7122e754bcd72771934ccbd", "ServerTextPrefixToken": "52387ea6942d9299a89f70a2a4d8a4209ea1dfe56e29f6c0e3182ca7818b5c9c", + "EDCTextExactDerivedFromDataToken": "6006d61e9e985ee8f6490aebf0bfd120bf7a94317646165584894da6ecbf0e97", + "EDCTextSubstringDerivedFromDataToken": "4dab3b274aa5d5e99ecbd7f139cd420f25305c9f082b25aa96f1c9fe6e2122e3", + "EDCTextSuffixDerivedFromDataToken": "997f4a0b518f6c872951b65dcf26676d3886c98502fe0a7cc4f9c5ea4f30e94b", + "EDCTextPrefixDerivedFromDataToken": "d3ebdd34bcacd11c5929a09d2a897eb7938abd4756cab805f46ff0f4affa7583", "EDCTextExactDerivedFromDataTokenAndContentionFactorToken": "3551507189d32cc7768390cdd83071deeb3055ca86c4756b16bb740024b23610", "EDCTextSubstringDerivedFromDataTokenAndContentionFactorToken": "4b52f6daf3b688971eb5819820c3468b3c79ba45fd3e86134351f9baf203e0d1", "EDCTextSuffixDerivedFromDataTokenAndContentionFactorToken": "c1f273913631a9a1b36fea884b3c8a3a141c9e21556981094ba15f262e540ac7", "EDCTextPrefixDerivedFromDataTokenAndContentionFactorToken": "a8d68ebdb0e2d31754f693c56071b0b1d225e6ec5568aff875bd4f7c48c24f66", + "ESCTextExactDerivedFromDataToken": "6d3311b3de0e32dbfe55a565327ad4b99d670474ddef52aa200fc79d76b8c7c4", + "ESCTextSubstringDerivedFromDataToken": "0e9d0f7c42658dd6894d3cbe34ffa0d39be00ba72a21ac79bc3712b25783d247", + "ESCTextSuffixDerivedFromDataToken": "a95860b4a08b39b002e5aee557268786be4e6d5a8552090dc397fbdb34374313", + "ESCTextPrefixDerivedFromDataToken": "8df7341dd42c1cee8411657afaea424bfa818a539bf0668e1c355fc2a555e11a", "ESCTextExactDerivedFromDataTokenAndContentionFactorToken": "4cd82a4883ab0a6224a24937066f94827f5107e8bb2f0fa841e10aff8d49e8e4", "ESCTextSubstringDerivedFromDataTokenAndContentionFactorToken": "94f116183f14442e335902756e5b730683cd998c683b90d04dc9e8f48684bdb2", "ESCTextSuffixDerivedFromDataTokenAndContentionFactorToken": "13390024c674c2d131771cf95af9787c8c7ef76b5d63078b3dc482cb4075a634", diff --git a/ext/libmongocrypt/libmongocrypt/test/example-state-machine.c b/ext/libmongocrypt/libmongocrypt/test/example-state-machine.c index 6ede0d8..2445121 100644 --- a/ext/libmongocrypt/libmongocrypt/test/example-state-machine.c +++ b/ext/libmongocrypt/libmongocrypt/test/example-state-machine.c @@ -133,9 +133,10 @@ static void _print_binary_as_text(mongocrypt_binary_t *binary) { #define CHECK(stmt) \ if (!stmt) { \ continue; \ - } + } else \ + ((void)0) -void _run_state_machine(mongocrypt_ctx_t *ctx, bson_t *result) { +static void _run_state_machine(mongocrypt_ctx_t *ctx, bson_t *result) { mongocrypt_binary_t *input, *output = NULL; bson_t tmp; mongocrypt_kms_ctx_t *kms; @@ -227,11 +228,10 @@ void _run_state_machine(mongocrypt_ctx_t *ctx, bson_t *result) { mongocrypt_ctx_status(ctx, status); printf("\ngot error: %s\n", mongocrypt_status_message(status, NULL)); abort(); - break; case MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS: // We don't handle KMS credentials // fallthrough - default: BSON_ASSERT(0); break; + default: BSON_ASSERT(0); } } @@ -247,7 +247,7 @@ static mongocrypt_binary_t *_iter_to_binary(bson_iter_t *iter) { return mongocrypt_binary_new_from_data(data, len); } -int main() { +int main(void) { bson_iter_t iter; bson_t result; bson_t key_doc; diff --git a/ext/libmongocrypt/libmongocrypt/test/test-dll.cpp b/ext/libmongocrypt/libmongocrypt/test/test-dll.cpp index 9ad69f5..d748a53 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-dll.cpp +++ b/ext/libmongocrypt/libmongocrypt/test/test-dll.cpp @@ -8,14 +8,20 @@ static std::string global_str; -extern "C" -#if _MSC_VER - __declspec(dllexport) +#if defined(_MSC_VER) +#define SAY_HELLO_EXPORT __declspec(dllexport) #else -__attribute__ ((visibility ("default"))) +#define SAY_HELLO_EXPORT __attribute__((visibility("default"))) #endif - int say_hello() { + +extern "C" { + +SAY_HELLO_EXPORT int say_hello(); // -Wmissing-prototypes: for testing only. + +int say_hello() { global_str = "Hello, DLL!"; std::cout << global_str << "\n"; return 42; } + +} // extern "C" diff --git a/ext/libmongocrypt/libmongocrypt/test/test-gcp-auth.c b/ext/libmongocrypt/libmongocrypt/test/test-gcp-auth.c index d1ad533..02f0d01 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-gcp-auth.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-gcp-auth.c @@ -32,7 +32,7 @@ static void _test_createdatakey_with_credentials(_mongocrypt_tester_t *tester) { crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); ctx = mongocrypt_ctx_new(crypt); - ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(kek)), ctx); + ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON_STR(kek)), ctx); ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx); ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); @@ -159,7 +159,7 @@ static void _test_createdatakey_with_accesstoken(_mongocrypt_tester_t *tester) { mongocrypt_setopt_use_need_kms_credentials_state(crypt); ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt); ctx = mongocrypt_ctx_new(crypt); - ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(kek)), ctx); + ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON_STR(kek)), ctx); ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx); ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-efc.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-efc.c index 1569613..a949cbc 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-efc.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-efc.c @@ -34,11 +34,9 @@ static void _test_efc(_mongocrypt_tester_t *tester) { _mongocrypt_buffer_copy_from_hex(&expect_keyId1, "12345678123498761234123456789012"); _mongocrypt_buffer_copy_from_hex(&expect_keyId2, "abcdefab123498761234123456789012"); - const bool use_range_v2 = false; - { _load_test_file(tester, "./test/data/efc/efc-oneField.json", &efc_bson); - ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status), status); ASSERT_CMPUINT8(efc.str_encode_version, ==, 0); ptr = efc.fields; ASSERT(ptr); @@ -50,7 +48,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-oneField-goodVersionSet.json", &efc_bson); - ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status), status); ASSERT_CMPUINT8(efc.str_encode_version, ==, 1); ptr = efc.fields; ASSERT(ptr); @@ -62,7 +60,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-extraField.json", &efc_bson); - ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status), status); ASSERT_CMPUINT8(efc.str_encode_version, ==, 0); ptr = efc.fields; ASSERT(ptr); @@ -74,7 +72,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-twoFields.json", &efc_bson); - ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status), status); ASSERT_CMPUINT8(efc.str_encode_version, ==, 0); ptr = efc.fields; ASSERT(ptr); @@ -90,7 +88,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-missingKeyId.json", &efc_bson); - ASSERT_FAILS_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), + ASSERT_FAILS_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status), status, "unable to find 'keyId' in 'field' document"); mc_EncryptedFieldConfig_cleanup(&efc); @@ -99,7 +97,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-oneField-badVersionSet.json", &efc_bson); - ASSERT_FAILS_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), + ASSERT_FAILS_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status), status, "'strEncodeVersion' of 99 is not supported"); mc_EncryptedFieldConfig_cleanup(&efc); @@ -108,7 +106,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-textSearchFields.json", &efc_bson); - ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status), status); ASSERT_CMPUINT8(efc.str_encode_version, ==, LATEST_STR_ENCODE_VERSION); ptr = efc.fields; ASSERT(ptr); @@ -126,7 +124,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-textSearchFields-goodVersionSet.json", &efc_bson); - ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status), status); ASSERT_CMPUINT8(efc.str_encode_version, ==, 1); ptr = efc.fields; ASSERT(ptr); @@ -144,7 +142,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-textSearchFields-badVersionSet.json", &efc_bson); - ASSERT_FAILS_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), + ASSERT_FAILS_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status), status, "'strEncodeVersion' of 99 is not supported"); mc_EncryptedFieldConfig_cleanup(&efc); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-encryption-placeholder.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-encryption-placeholder.c index e98fae0..1efffc4 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-encryption-placeholder.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-encryption-placeholder.c @@ -96,8 +96,7 @@ static void _test_FLE2EncryptionPlaceholder_range_parse(_mongocrypt_tester_t *te { mc_FLE2RangeInsertSpec_t spec; - ASSERT_OK_STATUS(mc_FLE2RangeInsertSpec_parse(&spec, &placeholder.v_iter, false /* use_range_v2 */, status), - status); + ASSERT_OK_STATUS(mc_FLE2RangeInsertSpec_parse(&spec, &placeholder.v_iter, status), status); ASSERT(BSON_ITER_HOLDS_INT32(&spec.v)); ASSERT_CMPINT32(bson_iter_int32(&spec.v), ==, 123456); @@ -153,8 +152,7 @@ static void _test_FLE2EncryptionPlaceholder_range_parse(_mongocrypt_tester_t *te { mc_FLE2RangeFindSpec_t spec; - ASSERT_OK_STATUS(mc_FLE2RangeFindSpec_parse(&spec, &placeholder.v_iter, false /* use_range_v2 */, status), - status); + ASSERT_OK_STATUS(mc_FLE2RangeFindSpec_parse(&spec, &placeholder.v_iter, status), status); ASSERT(spec.edgesInfo.set); @@ -225,8 +223,7 @@ static void _test_FLE2EncryptionPlaceholder_range_parse(_mongocrypt_tester_t *te { mc_FLE2RangeFindSpec_t spec; - ASSERT_OK_STATUS(mc_FLE2RangeFindSpec_parse(&spec, &placeholder.v_iter, false /* use_range_v2 */, status), - status); + ASSERT_OK_STATUS(mc_FLE2RangeFindSpec_parse(&spec, &placeholder.v_iter, status), status); ASSERT(spec.edgesInfo.set); @@ -295,8 +292,7 @@ static void _test_FLE2EncryptionPlaceholder_range_parse(_mongocrypt_tester_t *te { mc_FLE2RangeInsertSpec_t spec; - ASSERT_OK_STATUS(mc_FLE2RangeInsertSpec_parse(&spec, &placeholder.v_iter, false /* use_range_v2 */, status), - status); + ASSERT_OK_STATUS(mc_FLE2RangeInsertSpec_parse(&spec, &placeholder.v_iter, status), status); ASSERT(BSON_ITER_HOLDS_DOUBLE(&spec.v)); ASSERT_CMPDOUBLE(bson_iter_double(&spec.v), ==, 123.456); @@ -321,15 +317,17 @@ static bool _parse_text_search_spec_from_placeholder(_mongocrypt_tester_t *teste const char *spec_json_in, mc_FLE2TextSearchInsertSpec_t *spec_out, mongocrypt_status_t *status_out) { - const char *template = RAW_STRING({ - "t" : {"$numberInt" : "1"}, - "a" : {"$numberInt" : "4"}, - "ki" : {"$binary" : {"base64" : "EjRWeBI0mHYSNBI0VniQEg==", "subType" : "04"}}, - "ku" : {"$binary" : {"base64" : "q83vqxI0mHYSNBI0VniQEg==", "subType" : "04"}}, - "v" : % s, - "cm" : {"$numberLong" : "7"} - }); - bson_t *const as_bson = TMP_BSON(template, spec_json_in); +#define PLACEHOLDER_TEMPLATE \ + RAW_STRING({ \ + "t" : {"$numberInt" : "1"}, \ + "a" : {"$numberInt" : "4"}, \ + "ki" : {"$binary" : {"base64" : "EjRWeBI0mHYSNBI0VniQEg==", "subType" : "04"}}, \ + "ku" : {"$binary" : {"base64" : "q83vqxI0mHYSNBI0VniQEg==", "subType" : "04"}}, \ + "v" : MC_BSON, \ + "cm" : {"$numberLong" : "7"} \ + }) + + bson_t *const as_bson = TMP_BSONF(PLACEHOLDER_TEMPLATE, TMP_BSON_STR(spec_json_in)); mc_FLE2EncryptionPlaceholder_t placeholder; mc_FLE2EncryptionPlaceholder_init(&placeholder); @@ -355,6 +353,8 @@ static bool _parse_text_search_spec_from_placeholder(_mongocrypt_tester_t *teste mc_FLE2EncryptionPlaceholder_cleanup(&placeholder); return res; + +#undef PLACEHOLDER_TEMPLATE } static void _test_FLE2EncryptionPlaceholder_textSearch_parse(_mongocrypt_tester_t *tester) { @@ -390,17 +390,6 @@ static void _test_FLE2EncryptionPlaceholder_textSearch_parse(_mongocrypt_tester_ mongocrypt_status_destroy(status); } - // Test type=MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT without substring, suffix, or prefix specs - { - const char *input = RAW_STRING({"v" : "foobar", "casef" : false, "diacf" : true}); - mongocrypt_status_t *status = mongocrypt_status_new(); - mc_FLE2TextSearchInsertSpec_t spec; - ASSERT_FAILS_STATUS(_parse_text_search_spec_from_placeholder(tester, input, &spec, status), - status, - "Must have a substring, suffix, or prefix index specification"); - mongocrypt_status_destroy(status); - } - // Test type=MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT with lb > ub #define LB_GT_UB_TEST(Type) \ do { \ @@ -441,7 +430,7 @@ static void _test_FLE2EncryptionPlaceholder_textSearch_parse(_mongocrypt_tester_ } static void _test_FLE2EncryptionPlaceholder_parse_errors(_mongocrypt_tester_t *tester) { - bson_t *input_bson = TMP_BSON(BSON_STR({ + bson_t *input_bson = TMP_BSON_STR(BSON_STR({ "t" : {"$numberInt" : "1"}, "a" : {"$numberInt" : "1"}, "ki" : {"$binary" : {"base64" : "EjRWeBI0mHYSNBI0VniQEg==", "subType" : "04"}}, diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-equality-payload-v2.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-equality-payload-v2.c index e82e9b5..bd7e75c 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-equality-payload-v2.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-equality-payload-v2.c @@ -74,7 +74,7 @@ static void _test_FLE2FindEqualityPayloadV2_roundtrip(_mongocrypt_tester_t *test #undef TEST_FIND_EQ_PAYLOAD_HEX_V2 static void _test_FLE2FindEqualityPayloadV2_errors(_mongocrypt_tester_t *tester) { - bson_t *input_bson = TMP_BSON(BSON_STR({ + bson_t *input_bson = TMP_BSON_STR(BSON_STR({ "d" : {"$binary" : {"base64" : "AAAA", "subType" : "00"}}, "s" : {"$binary" : {"base64" : "AAAA", "subType" : "00"}}, "l" : {"$binary" : {"base64" : "AAAA", "subType" : "00"}}, diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-range-payload-v2.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-range-payload-v2.c index 79b2036..8c39ac5 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-range-payload-v2.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-range-payload-v2.c @@ -73,8 +73,7 @@ static void _test_FLE2FindRangePayloadV2_roundtrip(_mongocrypt_tester_t *tester) payload.secondOperator = expect_secondOperator; bson_init(&out_bson); - const bool use_range_v2 = false; - mc_FLE2FindRangePayloadV2_serialize(&payload, &out_bson, use_range_v2); + mc_FLE2FindRangePayloadV2_serialize(&payload, &out_bson); ASSERT_EQUAL_BSON(&in_bson, &out_bson); @@ -100,26 +99,11 @@ static void _test_FLE2FindRangePayloadV2_includes_crypto_params(_mongocrypt_test // Test crypto params from SERVER-91889 are included in "range" payload. { bson_t got = BSON_INITIALIZER; - const bool use_range_v2 = true; - ASSERT(mc_FLE2FindRangePayloadV2_serialize(&payload, &got, use_range_v2)); + ASSERT(mc_FLE2FindRangePayloadV2_serialize(&payload, &got)); _assert_match_bson(&got, TMP_BSON(BSON_STR({"sp" : 1, "pn" : 2, "tf" : 3, "mn" : 4, "mx" : 5}))); bson_destroy(&got); } - // Test crypto params from SERVER-91889 are excluded in "rangePreview" payload. - { - bson_t got = BSON_INITIALIZER; - const bool use_range_v2 = false; - ASSERT(mc_FLE2FindRangePayloadV2_serialize(&payload, &got, use_range_v2)); - _assert_match_bson(&got, TMP_BSON(BSON_STR({ - "sp" : {"$exists" : false}, - "pn" : {"$exists" : false}, - "tf" : {"$exists" : false}, - "mn" : {"$exists" : false}, - "mx" : {"$exists" : false} - }))); - bson_destroy(&got); - } mc_FLE2FindRangePayloadV2_cleanup(&payload); } diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-text-payload.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-text-payload.c new file mode 100644 index 0000000..e5801e9 --- /dev/null +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-text-payload.c @@ -0,0 +1,320 @@ +/* + * 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 + +#include "mc-fle2-find-text-payload-private.h" +#include "test-mongocrypt-assert-match-bson.h" +#include "test-mongocrypt-assert.h" +#include "test-mongocrypt.h" + +#define VALIDATE_TOKEN_SET(p, e) \ + ASSERT_CMPBUF((p)->edcDerivedToken, (e)->edcDerivedToken); \ + ASSERT_CMPBUF((p)->escDerivedToken, (e)->escDerivedToken); \ + ASSERT_CMPBUF((p)->serverDerivedFromDataToken, (e)->serverDerivedFromDataToken) + +static void _validate_parsed_payload(_mongocrypt_tester_t *tester, + mc_FLE2FindTextPayload_t *expected, + mc_FLE2FindTextPayload_t *parsed) { + ASSERT(parsed->tokenSets.exact.set == expected->tokenSets.exact.set); + ASSERT(parsed->tokenSets.substring.set == expected->tokenSets.substring.set); + ASSERT(parsed->tokenSets.suffix.set == expected->tokenSets.suffix.set); + ASSERT(parsed->tokenSets.prefix.set == expected->tokenSets.prefix.set); + ASSERT(parsed->caseFold == expected->caseFold); + ASSERT(parsed->diacriticFold == expected->diacriticFold); + ASSERT(parsed->substringSpec.set == expected->substringSpec.set); + ASSERT(parsed->suffixSpec.set == expected->suffixSpec.set); + ASSERT(parsed->prefixSpec.set == expected->prefixSpec.set); + + if (parsed->tokenSets.exact.set) { + VALIDATE_TOKEN_SET(&parsed->tokenSets.exact.value, &expected->tokenSets.exact.value); + } + if (parsed->tokenSets.substring.set) { + VALIDATE_TOKEN_SET(&parsed->tokenSets.substring.value, &expected->tokenSets.substring.value); + } + if (parsed->tokenSets.suffix.set) { + VALIDATE_TOKEN_SET(&parsed->tokenSets.suffix.value, &expected->tokenSets.suffix.value); + } + if (parsed->tokenSets.prefix.set) { + VALIDATE_TOKEN_SET(&parsed->tokenSets.prefix.value, &expected->tokenSets.prefix.value); + } + + if (parsed->substringSpec.set) { + ASSERT_CMPUINT32(parsed->substringSpec.value.lb, ==, expected->substringSpec.value.lb); + ASSERT_CMPUINT32(parsed->substringSpec.value.ub, ==, expected->substringSpec.value.ub); + ASSERT_CMPUINT32(parsed->substringSpec.value.mlen, ==, expected->substringSpec.value.mlen); + } + if (parsed->suffixSpec.set) { + ASSERT_CMPUINT32(parsed->suffixSpec.value.lb, ==, expected->suffixSpec.value.lb); + ASSERT_CMPUINT32(parsed->suffixSpec.value.ub, ==, expected->suffixSpec.value.ub); + } + if (parsed->prefixSpec.set) { + ASSERT_CMPUINT32(parsed->prefixSpec.value.lb, ==, expected->prefixSpec.value.lb); + ASSERT_CMPUINT32(parsed->prefixSpec.value.ub, ==, expected->prefixSpec.value.ub); + } +} + +#undef VALIDATE_TOKEN_SET + +static void +_do_roundtrip_test(_mongocrypt_tester_t *tester, mc_FLE2FindTextPayload_t *spec, const char *expectedFailMsg) { + mongocrypt_status_t *status = mongocrypt_status_new(); + + bson_t out_bson; + bson_init(&out_bson); + ASSERT(mc_FLE2FindTextPayload_serialize(spec, &out_bson)); + + mc_FLE2FindTextPayload_t parsed; + mc_FLE2FindTextPayload_init(&parsed); + + bool ret = mc_FLE2FindTextPayload_parse(&parsed, &out_bson, status); + if (expectedFailMsg) { + ASSERT_FAILS_STATUS(ret, status, expectedFailMsg); + } else { + ASSERT_OK_STATUS(ret, status); + _validate_parsed_payload(tester, spec, &parsed); + } + + mc_FLE2FindTextPayload_cleanup(&parsed); + bson_destroy(&out_bson); + mongocrypt_status_destroy(status); +} + +static void _do_parse_error_test(_mongocrypt_tester_t *tester, bson_t *to_parse, const char *expectedFailMsg) { + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2FindTextPayload_t parsed; + mc_FLE2FindTextPayload_init(&parsed); + bool ret = mc_FLE2FindTextPayload_parse(&parsed, to_parse, status); + ASSERT_FAILS_STATUS(ret, status, expectedFailMsg); + mc_FLE2FindTextPayload_cleanup(&parsed); + mongocrypt_status_destroy(status); +} + +static const char *k_edcToken = "280edab4190763d1f4183d383f8830773859c3a74a13161094e6fd44e7390fed"; +static const char *k_escToken = "c3c8980ed11e63ec199104bc9a0889322c9eb80d00eee0b5148dc83f7e78adb7"; +static const char *k_svrToken = "8773322a2b9e6c08886db6bc65b46ffdd64651e8a49400a9e55ff5bc550d45bf"; + +// Tests mc_FLE2FindTextPayload_serialize() works correctly, and non-error cases +// for mc_FLE2FindTextPayload_parse(). +static void _test_FLE2FindTextPayload_roundtrip(_mongocrypt_tester_t *tester) { + // Test exact token set + prefix spec present + { + mc_FLE2FindTextPayload_t payload; + mc_FLE2FindTextPayload_init(&payload); + payload.tokenSets.exact.set = true; + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.exact.value.edcDerivedToken, k_edcToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.exact.value.escDerivedToken, k_escToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.exact.value.serverDerivedFromDataToken, k_svrToken); + payload.caseFold = true; + payload.diacriticFold = false; + payload.maxContentionFactor = 43; + payload.prefixSpec.set = true; + payload.prefixSpec.value.lb = 2; + payload.prefixSpec.value.ub = 20; + _do_roundtrip_test(tester, &payload, NULL); + mc_FLE2FindTextPayload_cleanup(&payload); + } + + // Test substring token set + substring spec present + { + mc_FLE2FindTextPayload_t payload; + mc_FLE2FindTextPayload_init(&payload); + payload.tokenSets.substring.set = true; + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.substring.value.edcDerivedToken, k_edcToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.substring.value.escDerivedToken, k_escToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.substring.value.serverDerivedFromDataToken, k_svrToken); + payload.caseFold = false; + payload.diacriticFold = true; + payload.maxContentionFactor = 12; + payload.substringSpec.set = true; + payload.substringSpec.value.lb = 3; + payload.substringSpec.value.ub = 30; + payload.substringSpec.value.mlen = 300; + _do_roundtrip_test(tester, &payload, NULL); + mc_FLE2FindTextPayload_cleanup(&payload); + } + + // Test suffix token set + suffix & prefix specs present + { + mc_FLE2FindTextPayload_t payload; + mc_FLE2FindTextPayload_init(&payload); + payload.tokenSets.suffix.set = true; + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.suffix.value.edcDerivedToken, k_edcToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.suffix.value.escDerivedToken, k_escToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.suffix.value.serverDerivedFromDataToken, k_svrToken); + payload.caseFold = true; + payload.diacriticFold = true; + payload.maxContentionFactor = 21; + payload.suffixSpec.set = true; + payload.suffixSpec.value.lb = 4; + payload.suffixSpec.value.ub = 40; + payload.prefixSpec.set = true; + payload.prefixSpec.value.lb = 5; + payload.prefixSpec.value.ub = 50; + _do_roundtrip_test(tester, &payload, NULL); + mc_FLE2FindTextPayload_cleanup(&payload); + } + + // Test prefix token set + all specs present + { + mc_FLE2FindTextPayload_t payload; + mc_FLE2FindTextPayload_init(&payload); + payload.tokenSets.prefix.set = true; + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.prefix.value.edcDerivedToken, k_edcToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.prefix.value.escDerivedToken, k_escToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.prefix.value.serverDerivedFromDataToken, k_svrToken); + payload.caseFold = false; + payload.diacriticFold = false; + payload.maxContentionFactor = 55; + payload.substringSpec.set = true; + payload.substringSpec.value.lb = 3; + payload.substringSpec.value.ub = 30; + payload.substringSpec.value.mlen = 300; + payload.suffixSpec.set = true; + payload.suffixSpec.value.lb = 4; + payload.suffixSpec.value.ub = 40; + payload.prefixSpec.set = true; + payload.prefixSpec.value.lb = 5; + payload.prefixSpec.value.ub = 50; + _do_roundtrip_test(tester, &payload, NULL); + mc_FLE2FindTextPayload_cleanup(&payload); + } +} + +#define INT64_JSON "{'$numberLong': '5'}" +#define TOKEN_JSON "{'$binary': 'abcd', '$type': '0'}" +#define BADTOKEN_JSON "{'$binary': 'abcd', '$type': '2'}" +#define D_JSON "'d': " TOKEN_JSON +#define S_JSON "'s': " TOKEN_JSON +#define L_JSON "'l': " TOKEN_JSON +#define TOKENSET_JSON "{" D_JSON ", " S_JSON ", " L_JSON "}" +#define TS_JSON "'ts':{'e':" TOKENSET_JSON "}" +#define CM_JSON "'cm':" INT64_JSON +#define CF_JSON "'cf':false" +#define DF_JSON "'df':true" + +// Tests error cases for mc_FLE2FindTextPayload_parse(). +static void _test_FLE2FindTextPayload_parse_errors(_mongocrypt_tester_t *tester) { + // Test multiple optional fields present under ts is disallowed when parsing + { + mc_FLE2FindTextPayload_t payload; + mc_FLE2FindTextPayload_init(&payload); + payload.tokenSets.exact.set = true; + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.exact.value.edcDerivedToken, k_edcToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.exact.value.escDerivedToken, k_escToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.exact.value.serverDerivedFromDataToken, k_svrToken); + payload.tokenSets.suffix.set = true; + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.suffix.value.edcDerivedToken, k_edcToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.suffix.value.escDerivedToken, k_escToken); + _mongocrypt_buffer_copy_from_hex(&payload.tokenSets.suffix.value.serverDerivedFromDataToken, k_svrToken); + _do_roundtrip_test(tester, + &payload, + "Error parsing TextSearchFindTokenSets: cannot have multiple optional fields present"); + mc_FLE2FindTextPayload_cleanup(&payload); + } + // Test empty ts object is disallowed when parsing + { + mc_FLE2FindTextPayload_t payload; + mc_FLE2FindTextPayload_init(&payload); + _do_roundtrip_test(tester, + &payload, + "Error parsing TextSearchFindTokenSets: exactly one optional field is required"); + mc_FLE2FindTextPayload_cleanup(&payload); + } + + // Test missing required fields in top-level object + { + bson_t *no_ts = TMP_BSON("{%s, %s, %s}", CM_JSON, CF_JSON, DF_JSON); + bson_t *no_cm = TMP_BSON("{%s, %s, %s}", TS_JSON, CF_JSON, DF_JSON); + bson_t *no_cf = TMP_BSON("{%s, %s, %s}", TS_JSON, CM_JSON, DF_JSON); + bson_t *no_df = TMP_BSON("{%s, %s, %s}", TS_JSON, CM_JSON, CF_JSON); + _do_parse_error_test(tester, no_ts, "Missing required field 'ts'"); + _do_parse_error_test(tester, no_cm, "Missing required field 'cm'"); + _do_parse_error_test(tester, no_cf, "Missing required field 'cf'"); + _do_parse_error_test(tester, no_df, "Missing required field 'df'"); + } + + const char *all_required = TS_JSON ", " CM_JSON ", " CF_JSON ", " DF_JSON; + const char *required_no_ts = CM_JSON ", " CF_JSON ", " DF_JSON; + + // Test missing required fields in token set + { + bson_t *no_e_d = TMP_BSON("{'ts': {'e': {%s, %s}}, %s}", S_JSON, L_JSON, required_no_ts); + bson_t *no_e_s = TMP_BSON("{'ts': {'e': {%s, %s}}, %s}", D_JSON, L_JSON, required_no_ts); + bson_t *no_e_l = TMP_BSON("{'ts': {'e': {%s, %s}}, %s}", S_JSON, D_JSON, required_no_ts); + _do_parse_error_test(tester, no_e_d, "Missing required field 'd'"); + _do_parse_error_test(tester, no_e_s, "Missing required field 's'"); + _do_parse_error_test(tester, no_e_l, "Missing required field 'l'"); + } + + // Test invalid types in top-level object + { + bson_t *bad_ts = TMP_BSON("{'ts': 23, %s}", required_no_ts); + bson_t *bad_cm = TMP_BSON("{'cm': 'foo', %s, %s, %s}", TS_JSON, CF_JSON, DF_JSON); + bson_t *bad_cf = TMP_BSON("{'cf': 'foo', %s, %s, %s}", TS_JSON, CM_JSON, DF_JSON); + bson_t *bad_df = TMP_BSON("{'df': 'foo', %s, %s, %s}", TS_JSON, CF_JSON, CM_JSON); + bson_t *bad_ss = TMP_BSON("{'ss': 'foo', %s}", required_no_ts); + bson_t *bad_fs = TMP_BSON("{'fs': 'foo', %s}", required_no_ts); + bson_t *bad_ps = TMP_BSON("{'ps': 'foo', %s}", required_no_ts); + _do_parse_error_test(tester, bad_ts, "expected to be a document"); + _do_parse_error_test(tester, bad_cm, "expected to be int64"); + _do_parse_error_test(tester, bad_cf, "expected to be boolean"); + _do_parse_error_test(tester, bad_df, "expected to be boolean"); + _do_parse_error_test(tester, bad_ss, "must be an iterator to a document"); + _do_parse_error_test(tester, bad_fs, "must be an iterator to a document"); + _do_parse_error_test(tester, bad_ps, "must be an iterator to a document"); + } + + // Test invalid types in ts object + { + bson_t *bad_e = TMP_BSON("{'ts': {'e': 23}, %s}", required_no_ts); + bson_t *bad_s = TMP_BSON("{'ts': {'s': 23}, %s}", required_no_ts); + bson_t *bad_u = TMP_BSON("{'ts': {'u': 23}, %s}", required_no_ts); + bson_t *bad_p = TMP_BSON("{'ts': {'p': 23}, %s}", required_no_ts); + _do_parse_error_test(tester, bad_e, "expected to be a document"); + _do_parse_error_test(tester, bad_s, "expected to be a document"); + _do_parse_error_test(tester, bad_u, "expected to be a document"); + _do_parse_error_test(tester, bad_p, "expected to be a document"); + } + + // Test invalid types in token set + { + bson_t *bad_d = TMP_BSON("{'ts': {'e': {'d': 23, %s, %s}}, %s}", S_JSON, L_JSON, required_no_ts); + bson_t *bad_s = TMP_BSON("{'ts': {'e': {'s': 23, %s, %s}}, %s}", D_JSON, L_JSON, required_no_ts); + bson_t *bad_l = TMP_BSON("{'ts': {'e': {'l': 23, %s, %s}}, %s}", S_JSON, D_JSON, required_no_ts); + bson_t *bad_subtype = + TMP_BSON("{'ts': {'e': {'d': " BADTOKEN_JSON ", %s, %s}}, %s}", S_JSON, L_JSON, required_no_ts); + _do_parse_error_test(tester, bad_d, "expected to be bindata, got: INT32"); + _do_parse_error_test(tester, bad_s, "expected to be bindata, got: INT32"); + _do_parse_error_test(tester, bad_l, "expected to be bindata, got: INT32"); + _do_parse_error_test(tester, bad_subtype, "expected to be bindata subtype 0"); + } + + // Test unrecognized fields + { + bson_t *level1 = TMP_BSON("{'kk': 2, %s}", all_required); + bson_t *level2 = TMP_BSON("{'ts': {'oo': 2}, %s}", required_no_ts); + bson_t *level3 = TMP_BSON("{'ts': {'e': {%s, %s, %s, 'pp': 1}}, %s}", D_JSON, S_JSON, L_JSON, required_no_ts); + _do_parse_error_test(tester, level1, "Unrecognized field 'kk'"); + _do_parse_error_test(tester, level2, "Unrecognized field 'oo'"); + _do_parse_error_test(tester, level3, "Unrecognized field 'pp'"); + } +} + +void _mongocrypt_tester_install_fle2_payload_find_text(_mongocrypt_tester_t *tester) { + INSTALL_TEST(_test_FLE2FindTextPayload_roundtrip); + INSTALL_TEST(_test_FLE2FindTextPayload_parse_errors); +} diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup-v2.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup-v2.c index 6aeae4c..b18dea1 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup-v2.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup-v2.c @@ -182,26 +182,11 @@ static void _test_mc_FLE2InsertUpdatePayloadV2_includes_crypto_params(_mongocryp // Test crypto params from SERVER-91889 are included in "range" payload. { bson_t got = BSON_INITIALIZER; - const bool use_range_v2 = true; - ASSERT(mc_FLE2InsertUpdatePayloadV2_serializeForRange(&payload, &got, use_range_v2)); + ASSERT(mc_FLE2InsertUpdatePayloadV2_serializeForRange(&payload, &got)); _assert_match_bson(&got, TMP_BSON(BSON_STR({"sp" : 1, "pn" : 2, "tf" : 3, "mn" : 4, "mx" : 5}))); bson_destroy(&got); } - // Test crypto params from SERVER-91889 are excluded in "rangePreview" payload. - { - bson_t got = BSON_INITIALIZER; - const bool use_range_v2 = false; - ASSERT(mc_FLE2InsertUpdatePayloadV2_serializeForRange(&payload, &got, use_range_v2)); - _assert_match_bson(&got, TMP_BSON(BSON_STR({ - "sp" : {"$exists" : false}, - "pn" : {"$exists" : false}, - "tf" : {"$exists" : false}, - "mn" : {"$exists" : false}, - "mx" : {"$exists" : false} - }))); - bson_destroy(&got); - } mc_FLE2InsertUpdatePayloadV2_cleanup(&payload); } @@ -243,7 +228,7 @@ static void _test_mc_FLE2InsertUpdatePayloadV2_parses_crypto_params(_mongocrypt_ } static void _test_mc_FLE2InsertUpdatePayloadV2_parse_errors(_mongocrypt_tester_t *tester) { - bson_t *input_bson = TMP_BSON(BSON_STR({ + bson_t *input_bson = TMP_BSON_STR(BSON_STR({ "d" : {"$binary" : {"base64" : "AAAA", "subType" : "00"}}, // "t" : "wrong type!" })); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup.c index 9c99f60..263936d 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup.c @@ -162,7 +162,7 @@ static void test_FLE2InsertUpdatePayload_decrypt(_mongocrypt_tester_t *tester) { #undef TEST_IUP_HEX static void test_FLE2InsertUpdatePayload_parse_errors(_mongocrypt_tester_t *tester) { - bson_t *input_bson = TMP_BSON(BSON_STR({ + bson_t *input_bson = TMP_BSON_STR(BSON_STR({ "d" : {"$binary" : {"base64" : "AAAA", "subType" : "00"}}, // "t" : "wrong type!" })); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-rfds.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-rfds.c index 8c0e9b7..b7b28f5 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-rfds.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-rfds.c @@ -93,7 +93,7 @@ static void test_mc_FLE2RangeFindDriverSpec_parse(_mongocrypt_tester_t *tester) mongocrypt_status_t *status = mongocrypt_status_new(); mc_FLE2RangeFindDriverSpec_t rfds; TEST_PRINTF("running subtest: %s\n", test->desc); - bool ret = mc_FLE2RangeFindDriverSpec_parse(&rfds, TMP_BSON(test->in), status); + bool ret = mc_FLE2RangeFindDriverSpec_parse(&rfds, TMP_BSON_STR(test->in), status); if (!test->expectError) { ASSERT_OK_STATUS(ret, status); ASSERT_STREQUAL(test->expect.field, rfds.field); @@ -323,19 +323,22 @@ static void test_mc_FLE2RangeFindDriverSpec_to_placeholders(_mongocrypt_tester_t }; bson_t *range_opts_bson = - TMP_BSON("{'min': %d, 'max': %d, 'sparsity': {'$numberLong': '%d'}}", indexMin, indexMax, sparsity); + TMP_BSON("{'min': %" PRId32 ", 'max': %" PRId32 ", 'sparsity': {'$numberLong': '%" PRId64 "'}}", + indexMin, + indexMax, + sparsity); - ASSERT_OK_STATUS(mc_RangeOpts_parse(&range_opts, range_opts_bson, true /* use_range_v2 */, status), status); + ASSERT_OK_STATUS(mc_RangeOpts_parse(&range_opts, range_opts_bson, status), status); for (size_t i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { testcase_t *test = tests + i; TEST_PRINTF("running subtest: %s : %s\n", test->desc, test->in); - ASSERT_OK_STATUS(mc_FLE2RangeFindDriverSpec_parse(&spec, TMP_BSON(test->in), status), status); + ASSERT_OK_STATUS(mc_FLE2RangeFindDriverSpec_parse(&spec, TMP_BSON_STR(test->in), status), status); // Create the expected document. bson_t *expected; { - expected = TMP_BSON(test->expected); + expected = TMP_BSON_STR(test->expected); _mongocrypt_buffer_t p1 = {0}, p2 = {0}; diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-range-edge-generation.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-range-edge-generation.c index e7e5b08..00daa0f 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-range-edge-generation.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-range-edge-generation.c @@ -116,8 +116,7 @@ static void _test_getEdgesInt32(_mongocrypt_tester_t *tester) { .max = test->max, .sparsity = test->sparsity, .trimFactor = OPT_I32(test->trimFactor)}; - const bool use_range_v2 = true; - mc_edges_t *got = mc_getEdgesInt32(args, status, use_range_v2); + mc_edges_t *got = mc_getEdgesInt32(args, status); if (test->expectError != NULL) { ASSERT_OR_PRINT_MSG(NULL == got, "expected error, got success"); ASSERT_STATUS_CONTAINS(status, test->expectError); @@ -209,8 +208,7 @@ static void _test_getEdgesInt64(_mongocrypt_tester_t *tester) { .max = test->max, .sparsity = test->sparsity, .trimFactor = OPT_I32(test->trimFactor)}; - const bool use_range_v2 = true; - mc_edges_t *got = mc_getEdgesInt64(args, status, use_range_v2); + mc_edges_t *got = mc_getEdgesInt64(args, status); if (test->expectError != NULL) { ASSERT_OR_PRINT_MSG(NULL == got, "expected error, got success"); ASSERT_STATUS_CONTAINS(status, test->expectError); @@ -270,8 +268,7 @@ static void _test_getEdgesDouble(_mongocrypt_tester_t *tester) { mc_getEdgesDouble_args_t args = {.value = test->value, .sparsity = test->sparsity, .trimFactor = OPT_I32(trimFactor)}; - const bool use_range_v2 = true; - mc_edges_t *got = mc_getEdgesDouble(args, status, use_range_v2); + mc_edges_t *got = mc_getEdgesDouble(args, status); if (test->expectError != NULL) { if (NULL != got) { @@ -308,7 +305,7 @@ static void _test_getEdgesDouble(_mongocrypt_tester_t *tester) { } } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() #define MAX_DEC128_EDGES 129 typedef struct { @@ -338,8 +335,7 @@ static void _test_getEdgesDecimal128(_mongocrypt_tester_t *tester) { // .max = test->max, .sparsity = (size_t)test->sparsity, .trimFactor = OPT_I32(trimFactor)}; - const bool use_range_v2 = true; - mc_edges_t *got = mc_getEdgesDecimal128(args, status, use_range_v2); + mc_edges_t *got = mc_getEdgesDecimal128(args, status); if (test->expectError != NULL) { if (NULL != got) { @@ -492,7 +488,7 @@ void _mongocrypt_tester_install_range_edge_generation(_mongocrypt_tester_t *test INSTALL_TEST(_test_getEdgesInt32); INSTALL_TEST(_test_getEdgesInt64); INSTALL_TEST(_test_getEdgesDouble); -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() INSTALL_TEST(_test_getEdgesDecimal128); #endif INSTALL_TEST(_test_count_leading_zeros); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-range-encoding.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-range-encoding.c index ff5f57f..e85a5a9 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-range-encoding.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-range-encoding.c @@ -198,59 +198,67 @@ static void _test_RangeTest_Encode_Int64(_mongocrypt_tester_t *tester) { static void _test_canUsePrecisionModeDouble(_mongocrypt_tester_t *tester) { #define CAN_USE_PRECISION_MODE(lb, ub, prc, expected, expected_bits_out) \ - { \ + if (1) { \ uint32_t bits_out = 0; \ mongocrypt_status_t *const status = mongocrypt_status_new(); \ - TEST_PRINTF("_test_canUsePrecisionModeDecimal, min: %f, max: %f, prc: %" PRIu32, lb, ub, prc); \ + TEST_PRINTF("_test_canUsePrecisionModeDecimal, min: %f, max: %f, prc: %" PRId32, lb, ub, prc); \ bool result = mc_canUsePrecisionModeDouble(lb, ub, prc, &bits_out, status); \ ASSERT_OK_STATUS(mongocrypt_status_ok(status), status); \ ASSERT(result == expected); \ ASSERT_CMPINT32(expected_bits_out, ==, bits_out); \ mongocrypt_status_destroy(status); \ - } + } else \ + ((void)0) #define CAN_USE_PRECISION_MODE_ERRORS(lb, ub, prc, error) \ - { \ + if (1) { \ mongocrypt_status_t *const status = mongocrypt_status_new(); \ - TEST_PRINTF("_test_canUsePrecisionModeDecimal errors, min: %f, max: %f, prc: %" PRIu32, lb, ub, prc); \ + TEST_PRINTF("_test_canUsePrecisionModeDecimal errors, min: %f, max: %f, prc: %" PRId32, lb, ub, prc); \ uint32_t bits_out = 0; \ bool result = mc_canUsePrecisionModeDouble(lb, ub, prc, &bits_out, status); \ ASSERT_OR_PRINT_MSG(!result, "expected error, but got none"); \ ASSERT_STATUS_CONTAINS(status, error); \ mongocrypt_status_destroy(status); \ - } + } else \ + ((void)0) - CAN_USE_PRECISION_MODE(1.0, 16.0, 0, true, 4); - CAN_USE_PRECISION_MODE(0.0, 16.0, 0, true, 5); + CAN_USE_PRECISION_MODE(1.0, 16.0, INT32_C(0), true, 4); + CAN_USE_PRECISION_MODE(0.0, 16.0, INT32_C(0), true, 5); // 2^53 + 1 is where double starts to lose precision, so we need to ensure that we get the // correct value for max_bits out. - CAN_USE_PRECISION_MODE_ERRORS(1.0, 9007199254740992.0, 0, "Invalid upper bound for double precision. Absolute"); - CAN_USE_PRECISION_MODE_ERRORS(0.0, 9007199254740992.0, 0, "Invalid upper bound for double precision. Absolute"); + CAN_USE_PRECISION_MODE_ERRORS(1.0, + 9007199254740992.0, + INT32_C(0), + "Invalid upper bound for double precision. Absolute"); + CAN_USE_PRECISION_MODE_ERRORS(0.0, + 9007199254740992.0, + INT32_C(0), + "Invalid upper bound for double precision. Absolute"); CAN_USE_PRECISION_MODE(2.718281, 314.159265, 6, true, 29); CAN_USE_PRECISION_MODE_ERRORS(-1000000000.0, 9223372036844775424.0, - 0, + INT32_C(0), "Invalid upper bound for double precision. Absolute"); CAN_USE_PRECISION_MODE_ERRORS(2.710000, 314.150000, - 2, + INT32_C(2), "Invalid upper bound for double precision. Fractional digits"); CAN_USE_PRECISION_MODE_ERRORS(314.150000, 350.0, 2, "Invalid lower bound for double precision. Fractional digits"); CAN_USE_PRECISION_MODE_ERRORS((double)9007199254740992, INT_64_MAX_DOUBLE, - 0, + INT32_C(0), "Invalid upper bound for double precision. Absolute scaled value"); CAN_USE_PRECISION_MODE_ERRORS(-1 * INT_64_MAX_DOUBLE, 1.0, - 0, + INT32_C(0), "Invalid lower bound for double precision. Absolute scaled value"); CAN_USE_PRECISION_MODE_ERRORS(-92233720368547.0, 92233720368547.0, - 5, + INT32_C(5), "Invalid upper bound for double precision. Absolute"); #undef CAN_USE_PRECISION_MODE @@ -552,7 +560,7 @@ static void _test_RangeTest_Encode_Double(_mongocrypt_tester_t *tester) { if (test->min.set && test->max.set && test->precision.set) { TEST_PRINTF("_test_RangeTest_Encode_Double: value=%f, min=%f, max=%f, " - "precision=%" PRIu32 "\n", + "precision=%" PRId32 "\n", test->value, test->min.value, test->max.value, @@ -561,15 +569,13 @@ static void _test_RangeTest_Encode_Double(_mongocrypt_tester_t *tester) { TEST_PRINTF("_test_RangeTest_Encode_Double: value=%f\n", test->value); } - const bool use_range_v2 = !test->use_range_v1; mc_OSTType_Double got; const bool ok = mc_getTypeInfoDouble((mc_getTypeInfoDouble_args_t){.value = test->value, .min = test->min, .max = test->max, .precision = test->precision}, &got, - status, - use_range_v2); + status); if (test->expectError) { ASSERT_OR_PRINT_MSG(!ok, "expected error, but got none"); ASSERT_STATUS_CONTAINS(status, test->expectError); @@ -583,7 +589,7 @@ static void _test_RangeTest_Encode_Double(_mongocrypt_tester_t *tester) { } } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() typedef struct { mc_dec128 value; mc_optional_dec128_t min; @@ -903,15 +909,7 @@ static void _test_RangeTest_Encode_Decimal128(_mongocrypt_tester_t *tester) { } #define ASSERT_EIBB_ERROR(Val, Max, Min, Precision, Expect, Error) \ - (Decimal128Test){ \ - .value = mc_dec128_from_string(#Val), \ - .min = OPT_MC_DEC128(mc_dec128_from_string(#Min)), \ - .max = OPT_MC_DEC128(mc_dec128_from_string(#Max)), \ - .precision = OPT_I32(Precision), \ - .expect = Expect, \ - .use_range_v1 = true, \ - }, \ - (Decimal128Test) { \ + (Decimal128Test) { \ .value = mc_dec128_from_string(#Val), .min = OPT_MC_DEC128(mc_dec128_from_string(#Min)), \ .max = OPT_MC_DEC128(mc_dec128_from_string(#Max)), .precision = OPT_I32(Precision), .expectError = Error \ } @@ -996,7 +994,6 @@ static void _test_RangeTest_Encode_Decimal128(_mongocrypt_tester_t *tester) { TEST_PRINTF("_test_RangeTest_Encode_Decimal128: value=%s\n", mc_dec128_to_string(test->value).str); } mc_OSTType_Decimal128 got; - const bool use_range_v2 = !test->use_range_v1; const bool ok = mc_getTypeInfoDecimal128( (mc_getTypeInfoDecimal128_args_t){ .value = test->value, @@ -1005,8 +1002,7 @@ static void _test_RangeTest_Encode_Decimal128(_mongocrypt_tester_t *tester) { .precision = test->precision, }, &got, - status, - use_range_v2); + status); if (test->expectError) { ASSERT_OR_PRINT_MSG(!ok, "expected error, but got none"); ASSERT_STATUS_CONTAINS(status, test->expectError); @@ -1027,7 +1023,7 @@ void _mongocrypt_tester_install_range_encoding(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_RangeTest_Encode_Int64); INSTALL_TEST(_test_canUsePrecisionModeDouble); INSTALL_TEST(_test_RangeTest_Encode_Double); -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() INSTALL_TEST(_test_canUsePrecisionModeDecimal); INSTALL_TEST(_test_RangeTest_Encode_Decimal128); #endif diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-range-mincover.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-range-mincover.c index cd4d33a..131eb0b 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-range-mincover.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-range-mincover.c @@ -68,7 +68,7 @@ typedef struct { const char *expectError; } DoubleTest; -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() typedef struct { mc_dec128 lowerBound; bool includeLowerBound; @@ -95,7 +95,6 @@ static mc_mincover_t *_test_getMincover32(void *tests, size_t idx, mongocrypt_st Int32Test *test = (Int32Test *)tests + idx; - const bool use_range_v2 = true; return mc_getMincoverInt32((mc_getMincoverInt32_args_t){.lowerBound = test->lowerBound, .includeLowerBound = test->includeLowerBound, .upperBound = test->upperBound, @@ -104,14 +103,12 @@ static mc_mincover_t *_test_getMincover32(void *tests, size_t idx, mongocrypt_st .max = test->max, .sparsity = test->sparsity, .trimFactor = OPT_I32(test->trimFactor)}, - status, - use_range_v2); + status); } static mc_mincover_t *_test_getMincover64(void *tests, size_t idx, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(tests); - const bool use_range_v2 = true; const uint32_t trimFactor = 0; // At present, all test cases expect trimFactor=0. Int64Test *const test = (Int64Test *)tests + idx; @@ -123,14 +120,12 @@ static mc_mincover_t *_test_getMincover64(void *tests, size_t idx, mongocrypt_st .max = test->max, .sparsity = test->sparsity, .trimFactor = OPT_I32(trimFactor)}, - status, - use_range_v2); + status); } static mc_mincover_t *_test_getMincoverDouble_helper(void *tests, size_t idx, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(tests); - const bool use_range_v2 = true; const uint32_t trimFactor = 0; // At present, all test cases expect trimFactor=0. DoubleTest *const test = (DoubleTest *)tests + idx; @@ -144,17 +139,15 @@ static mc_mincover_t *_test_getMincoverDouble_helper(void *tests, size_t idx, mo .max = test->precision.set ? test->max : (mc_optional_double_t){0}, .precision = test->precision, .trimFactor = OPT_I32(trimFactor)}, - status, - use_range_v2); + status); } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() static mc_mincover_t *_test_getMincoverDecimal128_helper(void *tests, size_t idx, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(tests); Decimal128Test *const test = (Decimal128Test *)tests + idx; - const bool use_range_v2 = true; const uint32_t trimFactor = 0; // At present, all test cases expect trimFactor=0. return mc_getMincoverDecimal128( (mc_getMincoverDecimal128_args_t){.lowerBound = test->lowerBound, @@ -166,8 +159,7 @@ static mc_mincover_t *_test_getMincoverDecimal128_helper(void *tests, size_t idx .max = test->precision.set ? test->max : (mc_optional_dec128_t){0}, .precision = test->precision, .trimFactor = OPT_I32(trimFactor)}, - status, - use_range_v2); + status); } #endif // MONGOCRYPT_HAVE_DECIMAL128_SUPPORT @@ -202,7 +194,7 @@ static const char *_test_expectErrorDouble(void *tests, size_t idx, mongocrypt_s return test->expectError; } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() static const char *_test_expectErrorDecimal128(void *tests, size_t idx, mongocrypt_status_t *status) { BSON_ASSERT_PARAM(tests); BSON_ASSERT_PARAM(status); @@ -238,7 +230,7 @@ static const char *const *_test_expectMincoverDouble(void *tests, size_t idx) { return ((DoubleTest *)tests + idx)->expectMincoverStrings; } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() static const char *const *_test_expectMincoverDecimal128(void *tests, size_t idx) { BSON_ASSERT_PARAM(tests); return ((Decimal128Test *)tests + idx)->expectMincoverStrings; @@ -314,7 +306,7 @@ static void _test_dump_Double(void *tests, size_t idx, mc_mincover_t *got) { TEST_STDERR_PRINTF(" max=%f", test->max.value); } if (test->precision.set) { - TEST_STDERR_PRINTF(" precision=%" PRIu32, test->precision.value); + TEST_STDERR_PRINTF(" precision=%" PRId32, test->precision.value); } TEST_STDERR_PRINTF(" sparsity=%zu\n", test->sparsity); TEST_STDERR_PRINTF("mincover expected ... begin\n"); @@ -329,7 +321,7 @@ static void _test_dump_Double(void *tests, size_t idx, mc_mincover_t *got) { TEST_STDERR_PRINTF("mincover got ... end\n"); } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() static void _test_dump_Decimal128(void *tests, size_t idx, mc_mincover_t *got) { BSON_ASSERT_PARAM(tests); Decimal128Test *const test = (Decimal128Test *)tests + idx; @@ -594,7 +586,7 @@ static void _test_getMincoverDouble(_mongocrypt_tester_t *tester) { .dump = _test_dump_Double}); } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() static void _test_getMincoverDecimal128(_mongocrypt_tester_t *tester) { Decimal128Test tests[] = { #include "./data/range-min-cover/mincover_decimal128.cstruct" @@ -614,7 +606,7 @@ void _mongocrypt_tester_install_range_mincover(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_getMincoverInt32); INSTALL_TEST(_test_getMincoverInt64); INSTALL_TEST(_test_getMincoverDouble); -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() INSTALL_TEST(_test_getMincoverDecimal128); #endif } diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-rangeopts.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-rangeopts.c index 3395793..1ebb5a4 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-rangeopts.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-rangeopts.c @@ -30,7 +30,6 @@ static void test_mc_RangeOpts_parse(_mongocrypt_tester_t *tester) { int64_t expectSparsity; mc_optional_uint32_t expectPrecision; mc_optional_int32_t expectTrimFactor; - bool useRangeV2; } testcase; testcase tests[] = { @@ -62,24 +61,17 @@ static void test_mc_RangeOpts_parse(_mongocrypt_tester_t *tester) { {.desc = "Requires precision for double when only min is set", .in = RAW_STRING({"min" : 0.0, "sparsity" : {"$numberLong" : "1"}}), .expectError = "expected 'precision'"}, - // Once `use_range_v2` is default true, this test may be removed. - {.desc = "Fails when trim factor is set but Range V2 is disabled", - .in = RAW_STRING({"trimFactor" : 1, "sparsity" : {"$numberLong" : "1"}}), - .expectError = "'trimFactor' is not supported for QE range v1"}, {.desc = "Works when trim factor is set and Range V2 is enabled", .in = RAW_STRING({"trimFactor" : 1, "sparsity" : {"$numberLong" : "1"}}), - .useRangeV2 = true, .expectSparsity = 1, .expectTrimFactor = OPT_I32(1)}, {.desc = "Does not require sparsity", .in = RAW_STRING({"min" : 123, "max" : 456}), - .useRangeV2 = true, .expectSparsity = mc_FLERangeSparsityDefault, .expectMin = OPT_I32_C(123), .expectMax = OPT_I32_C(456)}, {.desc = "Errors on negative trim factor", .in = RAW_STRING({"trimFactor" : -1, "sparsity" : {"$numberLong" : "1"}}), - .useRangeV2 = true, .expectError = "'trimFactor' must be non-negative"}, }; @@ -88,7 +80,7 @@ static void test_mc_RangeOpts_parse(_mongocrypt_tester_t *tester) { mongocrypt_status_t *status = mongocrypt_status_new(); mc_RangeOpts_t ro; TEST_PRINTF("running test_mc_RangeOpts_parse subtest: %s\n", test->desc); - bool ret = mc_RangeOpts_parse(&ro, TMP_BSON(test->in), test->useRangeV2, status); + bool ret = mc_RangeOpts_parse(&ro, TMP_BSON_STR(test->in), status); if (!test->expectError) { ASSERT_OK_STATUS(ret, status); ASSERT_CMPINT(test->expectMin.set, ==, ro.min.set); @@ -119,8 +111,6 @@ static void test_mc_RangeOpts_to_FLE2RangeInsertSpec(_mongocrypt_tester_t *teste const char *v; const char *expectError; const char *expect; - // Most of the tests are for trim factor, so range V2 is default enabled. - bool disableRangeV2; } testcase; testcase tests[] = { @@ -128,11 +118,6 @@ static void test_mc_RangeOpts_to_FLE2RangeInsertSpec(_mongocrypt_tester_t *teste .in = RAW_STRING({"min" : 123, "max" : 456, "sparsity" : {"$numberLong" : "1"}}), .v = RAW_STRING({"v" : 789}), .expect = RAW_STRING({"v" : {"v" : 789, "min" : 123, "max" : 456}})}, - {.desc = "Trim factor not appended if range V2 disabled", - .in = RAW_STRING({"min" : 123, "max" : 456, "sparsity" : {"$numberLong" : "1"}}), - .v = RAW_STRING({"v" : 789}), - .disableRangeV2 = true, - .expect = RAW_STRING({"v" : {"v" : 789, "min" : 123, "max" : 456}})}, {.desc = "Works with precision", .in = RAW_STRING({"min" : 123.0, "max" : 456.0, "precision" : 2, "sparsity" : {"$numberLong" : "1"}}), .v = RAW_STRING({"v" : 789.0}), @@ -260,7 +245,7 @@ static void test_mc_RangeOpts_to_FLE2RangeInsertSpec(_mongocrypt_tester_t *teste .expectError = "Trim factor (64) must be less than the total number of bits (64) used to represent any " "element in the domain."}, -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() {.desc = "tf bound check passes correctly for decimal with min, max, precision set (tf = 9, 2^9 < domain size " "< 2^10)", .in = RAW_STRING({ @@ -317,12 +302,12 @@ static void test_mc_RangeOpts_to_FLE2RangeInsertSpec(_mongocrypt_tester_t *teste mongocrypt_status_t *status = mongocrypt_status_new(); mc_RangeOpts_t ro; TEST_PRINTF("running test_mc_RangeOpts_to_FLE2RangeInsertSpec subtest: %s\n", test->desc); - ASSERT_OK_STATUS(mc_RangeOpts_parse(&ro, TMP_BSON(test->in), !test->disableRangeV2, status), status); + ASSERT_OK_STATUS(mc_RangeOpts_parse(&ro, TMP_BSON_STR(test->in), status), status); bson_t out = BSON_INITIALIZER; - bool ret = mc_RangeOpts_to_FLE2RangeInsertSpec(&ro, TMP_BSON(test->v), &out, !test->disableRangeV2, status); + bool ret = mc_RangeOpts_to_FLE2RangeInsertSpec(&ro, TMP_BSON_STR(test->v), &out, status); if (!test->expectError) { ASSERT_OK_STATUS(ret, status); - ASSERT_EQUAL_BSON(TMP_BSON(test->expect), &out); + ASSERT_EQUAL_BSON(TMP_BSON_STR(test->expect), &out); } else { ASSERT_FAILS_STATUS(ret, status, test->expectError); } diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-reader.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-reader.c index 3d052fb..ceafa2c 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-reader.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-reader.c @@ -26,7 +26,7 @@ static void _test_mc_reader(_mongocrypt_tester_t *tester) { status = mongocrypt_status_new(); mc_reader_t reader; - mc_reader_init_from_buffer(&reader, &input_buf, __FUNCTION__); + mc_reader_init_from_buffer(&reader, &input_buf, __func__); uint8_t value; ASSERT_OK_STATUS(mc_reader_read_u8(&reader, &value, status), status); @@ -57,7 +57,7 @@ static void _test_mc_reader_uuid(_mongocrypt_tester_t *tester) { status = mongocrypt_status_new(); mc_reader_t reader; - mc_reader_init_from_buffer(&reader, &input_buf, __FUNCTION__); + mc_reader_init_from_buffer(&reader, &input_buf, __func__); _mongocrypt_buffer_t value; ASSERT_OK_STATUS(mc_reader_read_uuid_buffer(&reader, &value, status), status); @@ -93,7 +93,7 @@ static void _test_mc_reader_prfblock(_mongocrypt_tester_t *tester) { status = mongocrypt_status_new(); mc_reader_t reader; - mc_reader_init_from_buffer(&reader, &input_buf, __FUNCTION__); + mc_reader_init_from_buffer(&reader, &input_buf, __func__); _mongocrypt_buffer_t value; ASSERT_OK_STATUS(mc_reader_read_prfblock_buffer(&reader, &value, status), status); @@ -117,7 +117,7 @@ static void _test_mc_reader_ints(_mongocrypt_tester_t *tester) { status = mongocrypt_status_new(); mc_reader_t reader; - mc_reader_init_from_buffer(&reader, &input_buf, __FUNCTION__); + mc_reader_init_from_buffer(&reader, &input_buf, __func__); uint32_t u32; ASSERT_OK_STATUS(mc_reader_read_u32(&reader, &u32, status), status); @@ -143,7 +143,7 @@ static void _test_mc_reader_bytes(_mongocrypt_tester_t *tester) { status = mongocrypt_status_new(); mc_reader_t reader; - mc_reader_init_from_buffer(&reader, &input_buf, __FUNCTION__); + mc_reader_init_from_buffer(&reader, &input_buf, __func__); const uint8_t *ptr; const uint64_t len = 4; diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-text-search-str-encode.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-text-search-str-encode.c index df625e8..26d2f41 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-text-search-str-encode.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-text-search-str-encode.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "mongocrypt.h" #include "test-mongocrypt-assert.h" #include "test-mongocrypt.h" @@ -138,7 +139,7 @@ static void test_nofold_suffix_prefix_case(_mongocrypt_tester_t *tester, ASSERT_CMPPTR((uint8_t *)affix, ==, sets->base_string->buf.data + start_offset); ASSERT_CMPUINT32(affix_len, ==, - sets->base_string->codepoint_offsets[folded_codepoint_len] - start_offset) + sets->base_string->codepoint_offsets[folded_codepoint_len] - start_offset); } else { uint32_t end_offset = sets->base_string->codepoint_offsets[lb + idx]; ASSERT_CMPPTR((uint8_t *)affix, ==, sets->base_string->buf.data); @@ -360,21 +361,21 @@ static void test_nofold_substring_case_multiple_mlen(_mongocrypt_tester_t *teste test_nofold_substring_case(tester, str, lb, ub, byte_len + 64, casef, diacf, foldable_codepoints); } -const char *normal_ascii_strings[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", - "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", - "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", - "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; -const char *ascii_diacritics[] = {"^", "`"}; -const char *normal_unicode_strings[] = {"ぁ", "あ", "ぃ", "い", "ぅ", "う", "ぇ", "え", "ぉ", "お", "か", "が", - "き", "ぎ", "く", "け", "Ѐ", "Ё", "Ђ", "Ѓ", "Є", "Ѕ", "І", "Ї", - "Ј", "Љ", "Њ", "Ћ", "Ќ", "Ѝ", "Ў", "Џ", "𓀀", "𓀁", "𓀂", "𓀃", - "𓀄", "𓀅", "𓀆", "𓀇", "𓀈", "𓀉", "𓀊", "𓀋", "𓀌", "𓀍", "𓀎", "𓀏"}; -const char *unicode_diacritics[] = {"̀", "́", "̂", "̃", "̄", "̅", "̆", "̇", "̈", "̉", "̊", "̋", "̌", "̍", "̎", - "̏", "᷄", "᷅", "᷆", "᷇", "᷈", "᷉", "᷊", "᷋", "᷌", "᷍", "᷎", "᷏", "︠", "︡", - "︢", "︣", "︤", "︥", "︦", "︧", "︨", "︩", "︪", "︫", "︬", "︭", "︮", "︯"}; +static const char *normal_ascii_strings[] = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", + "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", + "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; +static const char *ascii_diacritics[] = {"^", "`"}; +static const char *normal_unicode_strings[] = {"ぁ", "あ", "ぃ", "い", "ぅ", "う", "ぇ", "え", "ぉ", "お", "か", "が", + "き", "ぎ", "く", "け", "Ѐ", "Ё", "Ђ", "Ѓ", "Є", "Ѕ", "І", "Ї", + "Ј", "Љ", "Њ", "Ћ", "Ќ", "Ѝ", "Ў", "Џ", "𓀀", "𓀁", "𓀂", "𓀃", + "𓀄", "𓀅", "𓀆", "𓀇", "𓀈", "𓀉", "𓀊", "𓀋", "𓀌", "𓀍", "𓀎", "𓀏"}; +static const char *unicode_diacritics[] = {"̀", "́", "̂", "̃", "̄", "̅", "̆", "̇", "̈", "̉", "̊", "̋", "̌", "̍", "̎", + "̏", "᷄", "᷅", "᷆", "᷇", "᷈", "᷉", "᷊", "᷋", "᷌", "᷍", "᷎", "᷏", "︠", "︡", + "︢", "︣", "︤", "︥", "︦", "︧", "︨", "︩", "︪", "︫", "︬", "︭", "︮", "︯"}; // Build a random string which has unfolded_len codepoints, but folds to folded_len codepoints after diacritic folding. -char *build_random_string_to_fold(uint32_t folded_len, uint32_t unfolded_len) { +static char *build_random_string_to_fold(uint32_t folded_len, uint32_t unfolded_len) { // 1/3 to generate all unicode, 1/3 to be half and half, 1/3 to be all ascii. int ascii_ratio = rand() % 3; ASSERT_CMPUINT32(unfolded_len, >=, folded_len); @@ -526,11 +527,11 @@ static void suffix_prefix_run_folding_case(_mongocrypt_tester_t *tester, test_nofold_suffix_prefix_case(tester, long_s, 32, 49, casef, diacf, foldable_codepoints); } -const uint32_t UNFOLDED_CASES[] = {0, 1, 3, 16}; +static const uint32_t UNFOLDED_CASES[] = {0, 1, 3, 16}; // Predefined lengths to test a variety of cases -const uint32_t SHORT_LEN = 9; -const uint32_t MEDIUM_LEN = 16; -const uint32_t LONG_LEN = 27; +static const uint32_t SHORT_LEN = 9; +static const uint32_t MEDIUM_LEN = 16; +static const uint32_t LONG_LEN = 27; static void _test_text_search_str_encode_suffix_prefix(_mongocrypt_tester_t *tester) { unsigned int seed = (unsigned int)time(0); @@ -1198,10 +1199,138 @@ static void _test_text_search_str_encode_empty_string(_mongocrypt_tester_t *test } } +// Tests mc_text_search_str_query() fails on invalid utf-8. +static void _test_text_search_str_query_bad_string(_mongocrypt_tester_t *tester) { + mongocrypt_status_t *status = mongocrypt_status_new(); + _mongocrypt_buffer_t out; + mc_FLE2TextSearchInsertSpec_t spec = {.v = "\xff\xff\xff\xff\xff\xff\xff\xff\xff", .len = 9}; + + bool res = mc_text_search_str_query(&spec, &out, status); + ASSERT_FAILS_STATUS(res, status, "not valid UTF-8"); + mongocrypt_status_destroy(status); +} + +// Tests mc_text_search_str_query() checks the input string codepoint length against lb and ub +// for substring, suffix, and prefix queries, and not for exact queres. +static void _test_text_search_str_query_bounds_checking(_mongocrypt_tester_t *tester) { + mc_FLE2TextSearchInsertSpec_t substrSpec = {.substr = {{.mlen = 20, .lb = 4, .ub = 7}, .set = true}}; + mc_FLE2TextSearchInsertSpec_t suffixSpec = {.suffix = {{.lb = 4, .ub = 7}, .set = true}}; + mc_FLE2TextSearchInsertSpec_t prefixSpec = {.prefix = {{.lb = 4, .ub = 7}, .set = true}}; + mc_FLE2TextSearchInsertSpec_t *specs[3] = {&substrSpec, &suffixSpec, &prefixSpec}; + + char *short_str = build_random_string_to_fold(3, 5); + char *long_str = build_random_string_to_fold(8, 10); + + mongocrypt_status_t *status = mongocrypt_status_new(); + _mongocrypt_buffer_t out; + + for (int i = 0; i < 3; i++) { + // long_str always fails regardless of folding + for (int d = 0; d < 2; d++) { + specs[i]->v = long_str; + specs[i]->len = (uint32_t)strlen(specs[i]->v); + specs[i]->diacf = d; + ASSERT_FAILS_STATUS(mc_text_search_str_query(specs[i], &out, status), + status, + "longer than the maximum query length"); + _mongocrypt_buffer_cleanup(&out); + _mongocrypt_status_reset(status); + } + // short_str only fails if diacritic folding is on + specs[i]->v = short_str; + specs[i]->len = (uint32_t)strlen(specs[i]->v); + specs[i]->diacf = true; + ASSERT_FAILS_STATUS(mc_text_search_str_query(specs[i], &out, status), + status, + "shorter than the minimum query length"); + _mongocrypt_buffer_cleanup(&out); + _mongocrypt_status_reset(status); + + specs[i]->diacf = false; + ASSERT_OK_STATUS(mc_text_search_str_query(specs[i], &out, status), status); + _mongocrypt_buffer_cleanup(&out); + _mongocrypt_status_reset(status); + } + + // test no bounds checking performed if no substr/suffix/prefix specs + mc_FLE2TextSearchInsertSpec_t exactSpecShort = {.diacf = true, .v = short_str, .len = (uint32_t)strlen(short_str)}; + mc_FLE2TextSearchInsertSpec_t exactSpecLong = {.diacf = true, .v = long_str, .len = (uint32_t)strlen(long_str)}; + ASSERT_OK_STATUS(mc_text_search_str_query(&exactSpecShort, &out, status), status); + _mongocrypt_buffer_cleanup(&out); + _mongocrypt_status_reset(status); + ASSERT_OK_STATUS(mc_text_search_str_query(&exactSpecLong, &out, status), status); + + _mongocrypt_buffer_cleanup(&out); + mongocrypt_status_destroy(status); + bson_free(short_str); + bson_free(long_str); +} + +// Tests mc_text_search_str_query() rejects empty string input for substr/suffix/prefix queries, +// but not for exact match queries. +static void _test_text_search_str_query_empty_string(_mongocrypt_tester_t *tester) { + mc_FLE2TextSearchInsertSpec_t substrSpec = {.substr = {{20, 4, 7}, true}, .v = "", .len = 0}; + mc_FLE2TextSearchInsertSpec_t suffixSpec = {.suffix = {{4, 7}, true}, .v = "", .len = 0}; + mc_FLE2TextSearchInsertSpec_t prefixSpec = {.prefix = {{4, 7}, true}, .v = "", .len = 0}; + mc_FLE2TextSearchInsertSpec_t exactSpec = {.v = "", .len = 0}; + mc_FLE2TextSearchInsertSpec_t *specs[3] = {&substrSpec, &suffixSpec, &prefixSpec}; + mongocrypt_status_t *status = mongocrypt_status_new(); + _mongocrypt_buffer_t out; + for (int i = 0; i < 3; i++) { + ASSERT_FAILS_STATUS(mc_text_search_str_query(specs[i], &out, status), status, "string value cannot be empty"); + _mongocrypt_buffer_cleanup(&out); + _mongocrypt_status_reset(status); + } + + ASSERT_OK_STATUS(mc_text_search_str_query(&exactSpec, &out, status), status); + _mongocrypt_buffer_cleanup(&out); + mongocrypt_status_destroy(status); +} + +// Tests mc_text_search_str_query() performs folding per the diacf and casef parameters. +static void _test_text_search_str_query_folding(_mongocrypt_tester_t *tester) { + const char *testStr = "Düsseldorf"; + const char *diacFoldStr = "Dusseldorf"; + const char *caseFoldStr = "düsseldorf"; + const char *bothFoldStr = "dusseldorf"; + mc_FLE2TextSearchInsertSpec_t spec = {.v = testStr, .len = (uint32_t)strlen(testStr)}; + mongocrypt_status_t *status = mongocrypt_status_new(); + _mongocrypt_buffer_t out; + + spec.diacf = true; + ASSERT_OK_STATUS(mc_text_search_str_query(&spec, &out, status), status); + ASSERT_CMPUINT32((uint32_t)strlen(diacFoldStr) + 5, ==, out.len); // +5 for BSON overhead + ASSERT_STREQUAL(diacFoldStr, (const char *)(out.data + 4)); // +4 skips past 32-bit size field + + _mongocrypt_buffer_cleanup(&out); + _mongocrypt_status_reset(status); + + spec.casef = true; + spec.diacf = false; + ASSERT_OK_STATUS(mc_text_search_str_query(&spec, &out, status), status); + ASSERT_CMPUINT32((uint32_t)strlen(caseFoldStr) + 5, ==, out.len); + ASSERT_STREQUAL(caseFoldStr, (const char *)(out.data + 4)); + + _mongocrypt_buffer_cleanup(&out); + _mongocrypt_status_reset(status); + + spec.diacf = true; + ASSERT_OK_STATUS(mc_text_search_str_query(&spec, &out, status), status); + ASSERT_CMPUINT32((uint32_t)strlen(bothFoldStr) + 5, ==, out.len); + ASSERT_STREQUAL(bothFoldStr, (const char *)(out.data + 4)); + + _mongocrypt_buffer_cleanup(&out); + mongocrypt_status_destroy(status); +} + void _mongocrypt_tester_install_text_search_str_encode(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_text_search_str_encode_suffix_prefix); INSTALL_TEST(_test_text_search_str_encode_substring); INSTALL_TEST(_test_text_search_str_encode_multiple); INSTALL_TEST(_test_text_search_str_encode_bad_string); INSTALL_TEST(_test_text_search_str_encode_empty_string); + INSTALL_TEST(_test_text_search_str_query_bad_string); + INSTALL_TEST(_test_text_search_str_query_bounds_checking); + INSTALL_TEST(_test_text_search_str_query_empty_string); + INSTALL_TEST(_test_text_search_str_query_folding); } diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-tokens.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-tokens.c index 26ff422..160fd52 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-tokens.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-tokens.c @@ -54,6 +54,14 @@ F(ServerTextSubstringToken) \ F(ServerTextSuffixToken) \ F(ServerTextPrefixToken) \ + F(EDCTextExactDerivedFromDataToken) \ + F(EDCTextSubstringDerivedFromDataToken) \ + F(EDCTextSuffixDerivedFromDataToken) \ + F(EDCTextPrefixDerivedFromDataToken) \ + F(ESCTextExactDerivedFromDataToken) \ + F(ESCTextSubstringDerivedFromDataToken) \ + F(ESCTextSuffixDerivedFromDataToken) \ + F(ESCTextPrefixDerivedFromDataToken) \ F(EDCTextExactDerivedFromDataTokenAndContentionFactorToken) \ F(EDCTextSubstringDerivedFromDataTokenAndContentionFactorToken) \ F(EDCTextSuffixDerivedFromDataTokenAndContentionFactorToken) \ @@ -222,12 +230,9 @@ static void _mc_token_test_run(_mongocrypt_tester_t *tester, const char *path) { #define TEST_TEXT(Name, Suffix) TEST_HELPER(Name, Token, Text##Suffix##Token, ) #define TEST_TEXT_EXTRA(Name, Suffix, BaseSuffix) TEST_HELPER(Name, BaseSuffix##Token, Text##Suffix##Token, ) -#define TEST_TEXT_DERIVED_FROM_BOTH(Name) \ - TEST_HELPER(Name, \ - Token, \ - DerivedFromDataTokenAndContentionFactorToken, \ - &test.value COMMA test.contentionFactor COMMA) #define TEST_TEXT_DERIVED_FROM_DATA(Name) TEST_HELPER(Name, Token, DerivedFromDataToken, &test.value COMMA) +#define TEST_TEXT_DERIVED_FROM_CONTENTION(Name) \ + TEST_HELPER(Name, Token, TokenAndContentionFactorToken, test.contentionFactor COMMA) TEST_TEXT(EDC, Exact); TEST_TEXT(EDC, Substring); @@ -244,15 +249,23 @@ static void _mc_token_test_run(_mongocrypt_tester_t *tester, const char *path) { TEST_TEXT_EXTRA(Server, Suffix, TokenDerivationLevel1); TEST_TEXT_EXTRA(Server, Prefix, TokenDerivationLevel1); - TEST_TEXT_DERIVED_FROM_BOTH(EDCTextExact); - TEST_TEXT_DERIVED_FROM_BOTH(EDCTextSubstring); - TEST_TEXT_DERIVED_FROM_BOTH(EDCTextPrefix); - TEST_TEXT_DERIVED_FROM_BOTH(EDCTextSuffix); - - TEST_TEXT_DERIVED_FROM_BOTH(ESCTextExact); - TEST_TEXT_DERIVED_FROM_BOTH(ESCTextSubstring); - TEST_TEXT_DERIVED_FROM_BOTH(ESCTextPrefix); - TEST_TEXT_DERIVED_FROM_BOTH(ESCTextSuffix); + TEST_TEXT_DERIVED_FROM_DATA(EDCTextExact); + TEST_TEXT_DERIVED_FROM_DATA(EDCTextSubstring); + TEST_TEXT_DERIVED_FROM_DATA(EDCTextSuffix); + TEST_TEXT_DERIVED_FROM_DATA(EDCTextPrefix); + TEST_TEXT_DERIVED_FROM_CONTENTION(EDCTextExactDerivedFromData); + TEST_TEXT_DERIVED_FROM_CONTENTION(EDCTextSubstringDerivedFromData); + TEST_TEXT_DERIVED_FROM_CONTENTION(EDCTextSuffixDerivedFromData); + TEST_TEXT_DERIVED_FROM_CONTENTION(EDCTextPrefixDerivedFromData); + + TEST_TEXT_DERIVED_FROM_DATA(ESCTextExact); + TEST_TEXT_DERIVED_FROM_DATA(ESCTextSubstring); + TEST_TEXT_DERIVED_FROM_DATA(ESCTextSuffix); + TEST_TEXT_DERIVED_FROM_DATA(ESCTextPrefix); + TEST_TEXT_DERIVED_FROM_CONTENTION(ESCTextExactDerivedFromData); + TEST_TEXT_DERIVED_FROM_CONTENTION(ESCTextSubstringDerivedFromData); + TEST_TEXT_DERIVED_FROM_CONTENTION(ESCTextSuffixDerivedFromData); + TEST_TEXT_DERIVED_FROM_CONTENTION(ESCTextPrefixDerivedFromData); TEST_TEXT_DERIVED_FROM_DATA(ServerTextExact); TEST_TEXT_DERIVED_FROM_DATA(ServerTextSubstring); @@ -272,6 +285,10 @@ static void _mc_token_test_run(_mongocrypt_tester_t *tester, const char *path) { ESCTextSubstringDerivedFromDataTokenAndContentionFactorToken); mc_ESCTextExactDerivedFromDataTokenAndContentionFactorToken_destroy( ESCTextExactDerivedFromDataTokenAndContentionFactorToken); + mc_ESCTextPrefixDerivedFromDataToken_destroy(ESCTextPrefixDerivedFromDataToken); + mc_ESCTextSuffixDerivedFromDataToken_destroy(ESCTextSuffixDerivedFromDataToken); + mc_ESCTextSubstringDerivedFromDataToken_destroy(ESCTextSubstringDerivedFromDataToken); + mc_ESCTextExactDerivedFromDataToken_destroy(ESCTextExactDerivedFromDataToken); mc_EDCTextPrefixDerivedFromDataTokenAndContentionFactorToken_destroy( EDCTextPrefixDerivedFromDataTokenAndContentionFactorToken); mc_EDCTextSuffixDerivedFromDataTokenAndContentionFactorToken_destroy( @@ -280,6 +297,10 @@ static void _mc_token_test_run(_mongocrypt_tester_t *tester, const char *path) { EDCTextSubstringDerivedFromDataTokenAndContentionFactorToken); mc_EDCTextExactDerivedFromDataTokenAndContentionFactorToken_destroy( EDCTextExactDerivedFromDataTokenAndContentionFactorToken); + mc_EDCTextPrefixDerivedFromDataToken_destroy(EDCTextPrefixDerivedFromDataToken); + mc_EDCTextSuffixDerivedFromDataToken_destroy(EDCTextSuffixDerivedFromDataToken); + mc_EDCTextSubstringDerivedFromDataToken_destroy(EDCTextSubstringDerivedFromDataToken); + mc_EDCTextExactDerivedFromDataToken_destroy(EDCTextExactDerivedFromDataToken); mc_ServerTextPrefixToken_destroy(ServerTextPrefixToken); mc_ServerTextSuffixToken_destroy(ServerTextSuffixToken); mc_ServerTextSubstringToken_destroy(ServerTextSubstringToken); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mc-writer.c b/ext/libmongocrypt/libmongocrypt/test/test-mc-writer.c index a9151fe..cc762db 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mc-writer.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mc-writer.c @@ -28,13 +28,13 @@ static void _test_mc_writer_ints(_mongocrypt_tester_t *tester) { _mongocrypt_buffer_init_size(&write_buffer, sizeof(uint8_t)); mc_writer_t writer; - mc_writer_init_from_buffer(&writer, &write_buffer, __FUNCTION__); + mc_writer_init_from_buffer(&writer, &write_buffer, __func__); uint8_t num = 4; ASSERT_OK_STATUS(mc_writer_write_u8(&writer, num, status), status); mc_reader_t reader; - mc_reader_init_from_buffer(&reader, &write_buffer, __FUNCTION__); + mc_reader_init_from_buffer(&reader, &write_buffer, __func__); uint8_t out; ASSERT_OK_STATUS(mc_reader_read_u8(&reader, &out, status), status); @@ -53,13 +53,13 @@ static void _test_mc_writer_ints(_mongocrypt_tester_t *tester) { _mongocrypt_buffer_init_size(&write_buffer, sizeof(uint32_t)); mc_writer_t writer; - mc_writer_init_from_buffer(&writer, &write_buffer, __FUNCTION__); + mc_writer_init_from_buffer(&writer, &write_buffer, __func__); uint32_t num = 23832405; ASSERT_OK_STATUS(mc_writer_write_u32(&writer, num, status), status); mc_reader_t reader; - mc_reader_init_from_buffer(&reader, &write_buffer, __FUNCTION__); + mc_reader_init_from_buffer(&reader, &write_buffer, __func__); uint32_t out; ASSERT_OK_STATUS(mc_reader_read_u32(&reader, &out, status), status); @@ -78,13 +78,13 @@ static void _test_mc_writer_ints(_mongocrypt_tester_t *tester) { _mongocrypt_buffer_init_size(&write_buffer, sizeof(uint64_t)); mc_writer_t writer; - mc_writer_init_from_buffer(&writer, &write_buffer, __FUNCTION__); + mc_writer_init_from_buffer(&writer, &write_buffer, __func__); uint64_t num = 23832405; ASSERT_OK_STATUS(mc_writer_write_u64(&writer, num, status), status); mc_reader_t reader; - mc_reader_init_from_buffer(&reader, &write_buffer, __FUNCTION__); + mc_reader_init_from_buffer(&reader, &write_buffer, __func__); uint64_t out; ASSERT_OK_STATUS(mc_reader_read_u64(&reader, &out, status), status); @@ -109,13 +109,13 @@ static void _test_mc_writer_buffer(_mongocrypt_tester_t *tester) { _mongocrypt_buffer_init_size(&write_buffer, input_buffer.len); mc_writer_t writer; - mc_writer_init_from_buffer(&writer, &write_buffer, __FUNCTION__); + mc_writer_init_from_buffer(&writer, &write_buffer, __func__); ASSERT_OK_STATUS(mc_writer_write_buffer(&writer, &input_buffer, input_buffer.len, status), status); _mongocrypt_buffer_t read_buffer; mc_reader_t reader; - mc_reader_init_from_buffer(&reader, &write_buffer, __FUNCTION__); + mc_reader_init_from_buffer(&reader, &write_buffer, __func__); ASSERT_OK_STATUS(mc_reader_read_buffer(&reader, &read_buffer, write_buffer.len, status), status); ASSERT_CMPBUF(input_buffer, read_buffer); @@ -137,7 +137,7 @@ static void _test_mc_writer_prf(_mongocrypt_tester_t *tester) { _mongocrypt_buffer_init_size(&write_buffer, input_buffer.len); mc_writer_t writer; - mc_writer_init_from_buffer(&writer, &write_buffer, __FUNCTION__); + mc_writer_init_from_buffer(&writer, &write_buffer, __func__); ASSERT_OK_STATUS(mc_writer_write_prfblock_buffer(&writer, &input_buffer, status), status); ASSERT_CMPBUF(input_buffer, write_buffer); @@ -158,7 +158,7 @@ static void _test_mc_writer_uuid(_mongocrypt_tester_t *tester) { _mongocrypt_buffer_init_size(&write_buffer, input_buffer.len); mc_writer_t writer; - mc_writer_init_from_buffer(&writer, &write_buffer, __FUNCTION__); + mc_writer_init_from_buffer(&writer, &write_buffer, __func__); ASSERT_OK_STATUS(mc_writer_write_uuid_buffer(&writer, &input_buffer, status), status); ASSERT_CMPBUF(input_buffer, write_buffer); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.c index 6138dab..c4b3420 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.c @@ -78,11 +78,6 @@ bool match_json(const bson_t *doc, const char *json_pattern, ...); -#define ASSERT_MATCH(doc, ...) \ - do { \ - BSON_ASSERT(match_json(doc, false, __FILE__, __LINE__, BSON_FUNC, __VA_ARGS__)); \ - } while (0) - const char *_mongoc_bson_type_to_str(bson_type_t t); static bool get_exists_operator(const bson_value_t *value, bool *exists); @@ -225,7 +220,7 @@ bool match_bson(const bson_t *doc, const bson_t *pattern, bool is_command) { MLIB_ANNOTATE_PRINTF(2, 3) -void match_err(match_ctx_t *ctx, const char *fmt, ...) { +static void match_err(match_ctx_t *ctx, const char *fmt, ...) { va_list args; char *formatted; @@ -849,7 +844,8 @@ bool match_bson_value(const bson_value_t *doc, const bson_value_t *pattern, matc "numeric values may be equal)"); } break; - default: match_err(ctx, "unexpected value type %d: %s", doc->value_type, _mongoc_bson_type_to_str(doc->value_type)); + default: + match_err(ctx, "unexpected value type %d: %s", (int)doc->value_type, _mongoc_bson_type_to_str(doc->value_type)); } if (!ret) { diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert.h b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert.h index a4361cd..c5060fa 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert.h +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert.h @@ -44,29 +44,32 @@ ((void)0) #define TEST_ERROR(...) \ - do { \ - TEST_STDERR_PRINTF("test error %s:%d %s(): ", __FILE__, __LINE__, __FUNCTION__); \ + if (1) { \ + TEST_STDERR_PRINTF("test error %s:%d %s(): ", __FILE__, __LINE__, __func__); \ TEST_STDERR_PRINTF(__VA_ARGS__); \ TEST_STDERR_PRINTF("\n"); \ abort(); \ - } while (0) + } else \ + ((void)0) #define ASSERT(stmt) \ if (!(stmt)) { \ TEST_ERROR("statement failed %s", #stmt); \ - } + } else \ + ((void)0) #define ASSERT_OR_PRINT_MSG(_statement, msg) \ - do { \ + if (1) { \ if (!(_statement)) { \ TEST_ERROR("%s failed with msg: %s", #_statement, (msg)); \ } \ - } while (0) + } else \ + ((void)0) #define ASSERT_OR_PRINT(_statement, _err) ASSERT_OR_PRINT_MSG(_statement, mongocrypt_status_message(_err, NULL)) #define ASSERT_OK_STATUS(_stmt, _status) \ - do { \ + if (1) { \ bool _retval = (_stmt); \ bool _status_ok = mongocrypt_status_ok(_status); \ const char *_msg = mongocrypt_status_message(_status, NULL); \ @@ -75,10 +78,11 @@ } else if (!_status_ok) { \ TEST_ERROR("%s resulted in unexpected error status: %s\n", #_stmt, _msg); \ } \ - } while (0) + } else \ + ((void)0) #define ASSERT_FAILS_STATUS(_stmt, _status, _msg_pattern) \ - do { \ + if (1) { \ bool _retval = (_stmt); \ bool _status_ok = mongocrypt_status_ok(_status); \ const char *_msg = mongocrypt_status_message(_status, NULL); \ @@ -90,7 +94,8 @@ } else if (!_found_msg) { \ TEST_ERROR("'%s' does not contain '%s'\n", _msg, _msg_pattern); \ } \ - } while (0) + } else \ + ((void)0) #define ASSERT_OK(_stmt, _obj) ASSERT_OK_STATUS(_stmt, (_obj)->status) @@ -101,7 +106,7 @@ #define ASSERT_STATUS_CONTAINS(status, _msg_pattern) ASSERT_FAILS_STATUS(false, status, _msg_pattern) #define ASSERT_STREQUAL(_expr_a, _expr_b) \ - do { \ + if (1) { \ const char *_str_a = (_expr_a); \ const char *_str_b = (_expr_b); \ ASSERT(_str_a); \ @@ -110,47 +115,52 @@ if (_ret != 0) { \ TEST_ERROR("strings not equal:\n%s\nvs.\n%s\n", _str_a, _str_b); \ } \ - } while (0); + } else \ + ((void)0) #define ASSERT_STRCONTAINS(_expr_a, _expr_b) \ - do { \ + if (1) { \ const char *_str_a = (_expr_a); \ const char *_str_b = (_expr_b); \ char *_ret = strstr(_str_a, _str_b); \ if (_ret == NULL) { \ TEST_ERROR("string %s does not contain %s\n", _str_a, _str_b); \ } \ - } while (0); + } else \ + ((void)0) #define ASSERT_STATE_EQUAL(actual, expected) \ - do { \ + if (1) { \ if (actual != expected) { \ TEST_ERROR("actual state: %s, but expected state: %s\n", \ mongocrypt_ctx_state_to_string(actual), \ mongocrypt_ctx_state_to_string(expected)); \ abort(); \ } \ - } while (0) + } else \ + ((void)0) #define ASSERT_CMPBYTES(expected_bytes, expected_len, actual_bytes, actual_len) \ - do { \ + if (1) { \ char *_actual_hex = data_to_hex(actual_bytes, actual_len); \ char *_expected_hex = data_to_hex(expected_bytes, expected_len); \ ASSERT_STREQUAL(_actual_hex, _expected_hex); \ free(_actual_hex); \ free(_expected_hex); \ - } while (0) + } else \ + ((void)0) #define ASSERT_CMPBUF(expected, actual) ASSERT_CMPBYTES((expected).data, (expected).len, (actual).data, (actual).len) #define ASSERT_CMP_HELPER(_a, _operator, _b, fmt, type) \ - do { \ + if (1) { \ type _a_value = (_a); \ type _b_value = (_b); \ if (!(_a_value _operator _b_value)) { \ TEST_ERROR("comparison failed: %" fmt " %s %" fmt, _a_value, #_operator, _b_value); \ } \ - } while (0); + } else \ + ((void)0) #define ASSERT_CMPINT(a, eq, b) ASSERT_CMP_HELPER(a, eq, b, "d", int) #define ASSERT_CMPUINT(a, eq, b) ASSERT_CMP_HELPER(a, eq, b, "u", unsigned int) @@ -184,7 +194,7 @@ ((void)0) #define ASSERT_EQUAL_BSON(expected, actual) \ - do { \ + if (1) { \ bson_t *_expected_bson = expected, *_actual_bson = actual; \ char *_expected_str, *_actual_str; \ _expected_str = bson_as_canonical_extended_json(_expected_bson, NULL); \ @@ -194,10 +204,11 @@ } \ bson_free(_actual_str); \ bson_free(_expected_str); \ - } while (0) + } else \ + ((void)0) #define ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(expected, actual) \ - do { \ + if (1) { \ bson_t _expected_bson, _actual_bson; \ char *_expected_str, *_actual_str; \ ASSERT(_mongocrypt_binary_to_bson(expected, &_expected_bson)); \ @@ -209,6 +220,7 @@ } \ bson_free(_actual_str); \ bson_free(_expected_str); \ - } while (0) + } else \ + ((void)0) #endif /* TEST_MONGOCRYPT_ASSERT_H */ diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-buffer.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-buffer.c index 1945be8..9748dce 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-buffer.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-buffer.c @@ -35,7 +35,7 @@ static void _get_bytes(const void *in, char *out, int len) { dest[-1] = '\0'; } -bool assert_excess_bytes_removed(char *key, char *wrapped, char *unwrapped, uint32_t type, bson_value_t *out) { +static bool assert_excess_bytes_removed(char *key, char *wrapped, char *unwrapped, uint32_t type, bson_value_t *out) { _mongocrypt_buffer_t plaintext = {0}; _mongocrypt_marking_t marking = {0}; bson_iter_t iter; @@ -48,13 +48,13 @@ bool assert_excess_bytes_removed(char *key, char *wrapped, char *unwrapped, uint BSON_APPEND_INT32(&bson, "int_key", TEST_INT); bson_iter_init_find(&iter, &bson, key); - memcpy(&marking.v_iter, &iter, sizeof(bson_iter_t)); + memcpy(&marking.u.fle1.v_iter, &iter, sizeof(bson_iter_t)); - bson_append_iter(&wrapper, "", 0, &marking.v_iter); + bson_append_iter(&wrapper, "", 0, &marking.u.fle1.v_iter); _get_bytes(bson_get_data(&wrapper), actual, wrapper.len); BSON_ASSERT(0 == strcmp(wrapped, actual)); - _mongocrypt_buffer_from_iter(&plaintext, &(&marking)->v_iter); + _mongocrypt_buffer_from_iter(&plaintext, &(&marking)->u.fle1.v_iter); _get_bytes(plaintext.data, actual, plaintext.len); BSON_ASSERT(0 == strcmp(unwrapped, actual)); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cache.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cache.c index db566a1..194c7f9 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cache.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cache.c @@ -18,7 +18,7 @@ #include "mongocrypt-crypto-private.h" #include "test-mongocrypt.h" -void _test_cache(_mongocrypt_tester_t *tester) { +static void _test_cache(_mongocrypt_tester_t *tester) { _mongocrypt_cache_t cache; mongocrypt_status_t *status; bson_t *entry = BCON_NEW("a", "b"), *entry2 = BCON_NEW("c", "d"); @@ -221,4 +221,4 @@ void _mongocrypt_tester_install_cache(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_cache); INSTALL_TEST(_test_cache_expiration); INSTALL_TEST(_test_cache_duplicates); -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ciphertext.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ciphertext.c index 03bed17..b3b81a4 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ciphertext.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ciphertext.c @@ -91,7 +91,7 @@ static void _test_malformed_ciphertext(_mongocrypt_tester_t *tester) { mongocrypt_status_destroy(status); } -void _test_ciphertext_algorithm(_mongocrypt_tester_t *tester) { +static void _test_ciphertext_algorithm(_mongocrypt_tester_t *tester) { mongocrypt_t *crypt; mongocrypt_ctx_t *ctx; mongocrypt_status_t *status; @@ -118,10 +118,10 @@ void _test_ciphertext_algorithm(_mongocrypt_tester_t *tester) { ctx = mongocrypt_ctx_new(crypt); ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "test", -1, TEST_FILE("./test/example/cmd.json")), ctx); - _mongocrypt_buffer_from_binary(&marking.key_id, TEST_BIN(16)); - marking.key_id.subtype = BSON_SUBTYPE_UUID; + _mongocrypt_buffer_from_binary(&marking.u.fle1.key_id, TEST_BIN(16)); + marking.u.fle1.key_id.subtype = BSON_SUBTYPE_UUID; kb = &ctx->kb; - _mongocrypt_key_broker_add_test_key(kb, &marking.key_id); + _mongocrypt_key_broker_add_test_key(kb, &marking.u.fle1.key_id); bson = BCON_NEW("v", "a", "v", "b"); bson_iter_init(&a_iter, bson); @@ -131,26 +131,26 @@ void _test_ciphertext_algorithm(_mongocrypt_tester_t *tester) { bson_iter_next(&b_iter); /* Marking type = 1, plaintext = a */ - marking.algorithm = 1; - memcpy(&marking.v_iter, &a_iter, sizeof(bson_iter_t)); + marking.u.fle1.algorithm = 1; + memcpy(&marking.u.fle1.v_iter, &a_iter, sizeof(bson_iter_t)); res = _mongocrypt_marking_to_ciphertext((void *)kb, &marking, &type1_valueA, status); ASSERT_OR_PRINT(res, status); /* Marking type = 1, plaintext = a */ - marking.algorithm = 1; - memcpy(&marking.v_iter, &a_iter, sizeof(bson_iter_t)); + marking.u.fle1.algorithm = 1; + memcpy(&marking.u.fle1.v_iter, &a_iter, sizeof(bson_iter_t)); res = _mongocrypt_marking_to_ciphertext((void *)kb, &marking, &type1_valueA_again, status); ASSERT_OR_PRINT(res, status); /* Marking type = 2, plaintext = a */ - marking.algorithm = 2; - memcpy(&marking.v_iter, &a_iter, sizeof(bson_iter_t)); + marking.u.fle1.algorithm = 2; + memcpy(&marking.u.fle1.v_iter, &a_iter, sizeof(bson_iter_t)); res = _mongocrypt_marking_to_ciphertext((void *)kb, &marking, &type2_valueA, status); ASSERT_OR_PRINT(res, status); /* Marking type = 1, plaintext = b */ - marking.algorithm = 1; - memcpy(&marking.v_iter, &b_iter, sizeof(bson_iter_t)); + marking.u.fle1.algorithm = 1; + memcpy(&marking.u.fle1.v_iter, &b_iter, sizeof(bson_iter_t)); res = _mongocrypt_marking_to_ciphertext((void *)kb, &marking, &type1_valueB, status); ASSERT_OR_PRINT(res, status); @@ -184,7 +184,7 @@ void _test_ciphertext_algorithm(_mongocrypt_tester_t *tester) { mongocrypt_status_destroy(status); } -void _test_ciphertext_serialize_associated_data(_mongocrypt_tester_t *tester) { +static void _test_ciphertext_serialize_associated_data(_mongocrypt_tester_t *tester) { _mongocrypt_ciphertext_t ciphertext; _mongocrypt_buffer_t serialized; /* Expected associated data is: diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cleanup.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cleanup.c index 43e7e0e..d68846c 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cleanup.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cleanup.c @@ -17,59 +17,50 @@ #include "test-mongocrypt.h" static void _test_cleanup_success(_mongocrypt_tester_t *tester) { - for (int use_range_v2 = 0; use_range_v2 <= 1; use_range_v2++) { - mongocrypt_t *crypt; - mongocrypt_ctx_t *ctx; - - crypt = - _mongocrypt_tester_mongocrypt(use_range_v2 ? TESTER_MONGOCRYPT_WITH_RANGE_V2 : TESTER_MONGOCRYPT_DEFAULT); - ctx = mongocrypt_ctx_new(crypt); - - ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE("./test/data/cleanup/success/cmd.json")), ctx); - - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_COLLINFO); - { - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, TEST_FILE("./test/data/cleanup/success/collinfo.json")), ctx); - ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); - } - - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS); - { - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, - TEST_FILE("./test/data/keys/" - "12345678123498761234123456789012-local-document.json")), - ctx); - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, - TEST_FILE("./test/data/keys/" - "ABCDEFAB123498761234123456789012-local-document.json")), - ctx); - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, - TEST_FILE("./test/data/keys/" - "12345678123498761234123456789013-local-document.json")), - ctx); - ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); - } - - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY); - { - mongocrypt_binary_t *out = mongocrypt_binary_new(); - ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); - if (use_range_v2) { - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON( - TEST_FILE("./test/data/cleanup/success/encrypted-payload-range-v2.json"), - out); - } else { - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/cleanup/success/encrypted-payload.json"), - out); - } - mongocrypt_binary_destroy(out); - } - - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_DONE); - - mongocrypt_ctx_destroy(ctx); - mongocrypt_destroy(crypt); + mongocrypt_t *crypt; + mongocrypt_ctx_t *ctx; + + crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + ctx = mongocrypt_ctx_new(crypt); + + ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE("./test/data/cleanup/success/cmd.json")), ctx); + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_COLLINFO); + { + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, TEST_FILE("./test/data/cleanup/success/collinfo.json")), ctx); + ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); } + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS); + { + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, + TEST_FILE("./test/data/keys/" + "12345678123498761234123456789012-local-document.json")), + ctx); + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, + TEST_FILE("./test/data/keys/" + "ABCDEFAB123498761234123456789012-local-document.json")), + ctx); + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, + TEST_FILE("./test/data/keys/" + "12345678123498761234123456789013-local-document.json")), + ctx); + ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); + } + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY); + { + mongocrypt_binary_t *out = mongocrypt_binary_new(); + ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/cleanup/success/encrypted-payload-range-v2.json"), + out); + mongocrypt_binary_destroy(out); + } + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_DONE); + + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); } static void _test_cleanup_nonlocal_kms(_mongocrypt_tester_t *tester) { @@ -135,7 +126,8 @@ static void _test_cleanup_nonlocal_kms(_mongocrypt_tester_t *tester) { { mongocrypt_binary_t *out = mongocrypt_binary_new(); ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/cleanup/success/encrypted-payload.json"), out); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/cleanup/success/encrypted-payload-range-v2.json"), + out); mongocrypt_binary_destroy(out); } @@ -269,7 +261,8 @@ static void _test_cleanup_need_kms_credentials(_mongocrypt_tester_t *tester) { { mongocrypt_binary_t *out = mongocrypt_binary_new(); ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/cleanup/success/encrypted-payload.json"), out); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/cleanup/success/encrypted-payload-range-v2.json"), + out); mongocrypt_binary_destroy(out); } @@ -353,7 +346,8 @@ static void _test_cleanup_from_encrypted_field_config_map(_mongocrypt_tester_t * { mongocrypt_binary_t *out = mongocrypt_binary_new(); ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/cleanup/success/encrypted-payload.json"), out); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/cleanup/success/encrypted-payload-range-v2.json"), + out); mongocrypt_binary_destroy(out); } diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-compact.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-compact.c index 255f709..f0b1579 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-compact.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-compact.c @@ -25,80 +25,19 @@ static void _test_compact_success(_mongocrypt_tester_t *tester) { strcpy(datapath, basepath); size_t nullb = strlen(basepath); for (int use_anchor_pad = 0; use_anchor_pad <= 1; use_anchor_pad++) { - for (int use_range_v2 = 0; use_range_v2 <= 1; use_range_v2++) { - datapath[nullb] = 0; - strcat(datapath, use_anchor_pad ? "anchor-pad/" : "success/"); - strcpy(cmdfile, datapath); - strcat(cmdfile, "cmd.json"); - strcpy(collfile, datapath); - strcat(collfile, "collinfo.json"); - strcpy(payloadfile, datapath); - strcat(payloadfile, use_range_v2 ? "encrypted-payload-range-v2.json" : "encrypted-payload.json"); - - mongocrypt_t *crypt; - mongocrypt_ctx_t *ctx; - - crypt = _mongocrypt_tester_mongocrypt(use_range_v2 ? TESTER_MONGOCRYPT_WITH_RANGE_V2 - : TESTER_MONGOCRYPT_DEFAULT); - ctx = mongocrypt_ctx_new(crypt); - - ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE(cmdfile)), ctx); - - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_COLLINFO); - { - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, TEST_FILE(collfile)), ctx); - ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); - } - - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS); - { - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, - TEST_FILE("./test/data/keys/" - "12345678123498761234123456789012-local-document.json")), - ctx); - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, - TEST_FILE("./test/data/keys/" - "ABCDEFAB123498761234123456789012-local-document.json")), - ctx); - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, - TEST_FILE("./test/data/keys/" - "12345678123498761234123456789013-local-document.json")), - ctx); - ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); - } - - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY); - { - mongocrypt_binary_t *out = mongocrypt_binary_new(); - ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE(payloadfile), out); - mongocrypt_binary_destroy(out); - } - - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_DONE); - - mongocrypt_ctx_destroy(ctx); - mongocrypt_destroy(crypt); - } - } - - // Test `compactStructuredEncryptionData` without range fields omits encryptionInformation. - // This is a regression test for MONGOCRYPT-699. - for (int use_range_v2 = 0; use_range_v2 <= 1; use_range_v2++) { datapath[nullb] = 0; - strcat(datapath, "no-range/"); + strcat(datapath, use_anchor_pad ? "anchor-pad/" : "success/"); strcpy(cmdfile, datapath); strcat(cmdfile, "cmd.json"); strcpy(collfile, datapath); strcat(collfile, "collinfo.json"); strcpy(payloadfile, datapath); - strcat(payloadfile, "encrypted-payload.json"); // Expect same result regardless of range v2. + strcat(payloadfile, "encrypted-payload-range-v2.json"); mongocrypt_t *crypt; mongocrypt_ctx_t *ctx; - crypt = - _mongocrypt_tester_mongocrypt(use_range_v2 ? TESTER_MONGOCRYPT_WITH_RANGE_V2 : TESTER_MONGOCRYPT_DEFAULT); + crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); ctx = mongocrypt_ctx_new(crypt); ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE(cmdfile)), ctx); @@ -139,6 +78,61 @@ static void _test_compact_success(_mongocrypt_tester_t *tester) { mongocrypt_ctx_destroy(ctx); mongocrypt_destroy(crypt); } + + // Test `compactStructuredEncryptionData` without range fields omits encryptionInformation. + // This is a regression test for MONGOCRYPT-699. + datapath[nullb] = 0; + strcat(datapath, "no-range/"); + strcpy(cmdfile, datapath); + strcat(cmdfile, "cmd.json"); + strcpy(collfile, datapath); + strcat(collfile, "collinfo.json"); + strcpy(payloadfile, datapath); + strcat(payloadfile, "encrypted-payload.json"); + + mongocrypt_t *crypt; + mongocrypt_ctx_t *ctx; + + crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + ctx = mongocrypt_ctx_new(crypt); + + ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE(cmdfile)), ctx); + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_COLLINFO); + { + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, TEST_FILE(collfile)), ctx); + ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); + } + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS); + { + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, + TEST_FILE("./test/data/keys/" + "12345678123498761234123456789012-local-document.json")), + ctx); + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, + TEST_FILE("./test/data/keys/" + "ABCDEFAB123498761234123456789012-local-document.json")), + ctx); + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, + TEST_FILE("./test/data/keys/" + "12345678123498761234123456789013-local-document.json")), + ctx); + ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); + } + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY); + { + mongocrypt_binary_t *out = mongocrypt_binary_new(); + ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE(payloadfile), out); + mongocrypt_binary_destroy(out); + } + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_DONE); + + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); } static void _test_compact_nonlocal_kms(_mongocrypt_tester_t *tester) { @@ -204,7 +198,8 @@ static void _test_compact_nonlocal_kms(_mongocrypt_tester_t *tester) { { mongocrypt_binary_t *out = mongocrypt_binary_new(); ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/compact/success/encrypted-payload.json"), out); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/compact/success/encrypted-payload-range-v2.json"), + out); mongocrypt_binary_destroy(out); } @@ -338,7 +333,8 @@ static void _test_compact_need_kms_credentials(_mongocrypt_tester_t *tester) { { mongocrypt_binary_t *out = mongocrypt_binary_new(); ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/compact/success/encrypted-payload.json"), out); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/compact/success/encrypted-payload-range-v2.json"), + out); mongocrypt_binary_destroy(out); } @@ -422,7 +418,8 @@ static void _test_compact_from_encrypted_field_config_map(_mongocrypt_tester_t * { mongocrypt_binary_t *out = mongocrypt_binary_new(); ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/compact/success/encrypted-payload.json"), out); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/compact/success/encrypted-payload-range-v2.json"), + out); mongocrypt_binary_destroy(out); } diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-hooks.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-hooks.c index a2fdb8f..b723e14 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-hooks.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-hooks.c @@ -117,11 +117,11 @@ static bool _mock_aes_256_xxx_decrypt(void *ctx, return true; } -bool _hmac_sha_512(void *ctx, - mongocrypt_binary_t *key, - mongocrypt_binary_t *in, - mongocrypt_binary_t *out, - mongocrypt_status_t *status) { +static bool _hmac_sha_512(void *ctx, + mongocrypt_binary_t *key, + mongocrypt_binary_t *in, + mongocrypt_binary_t *out, + mongocrypt_status_t *status) { _mongocrypt_buffer_t tmp; BSON_ASSERT(0 == strncmp("error_on:", (char *)ctx, strlen("error_on:"))); @@ -141,11 +141,11 @@ bool _hmac_sha_512(void *ctx, return true; } -bool _hmac_sha_256(void *ctx, - mongocrypt_binary_t *key, - mongocrypt_binary_t *in, - mongocrypt_binary_t *out, - mongocrypt_status_t *status) { +static bool _hmac_sha_256(void *ctx, + mongocrypt_binary_t *key, + mongocrypt_binary_t *in, + mongocrypt_binary_t *out, + mongocrypt_status_t *status) { _mongocrypt_buffer_t tmp; BSON_ASSERT(0 == strncmp("error_on:", (char *)ctx, strlen("error_on:"))); @@ -165,7 +165,7 @@ bool _hmac_sha_256(void *ctx, return true; } -bool _sha_256(void *ctx, mongocrypt_binary_t *in, mongocrypt_binary_t *out, mongocrypt_status_t *status) { +static bool _sha_256(void *ctx, mongocrypt_binary_t *in, mongocrypt_binary_t *out, mongocrypt_status_t *status) { _mongocrypt_buffer_t tmp; BSON_ASSERT(0 == strncmp("error_on:", (char *)ctx, strlen("error_on:"))); @@ -184,7 +184,7 @@ bool _sha_256(void *ctx, mongocrypt_binary_t *in, mongocrypt_binary_t *out, mong return true; } -bool _random(void *ctx, mongocrypt_binary_t *out, uint32_t count, mongocrypt_status_t *status) { +static bool _random(void *ctx, mongocrypt_binary_t *out, uint32_t count, mongocrypt_status_t *status) { /* only have 32 bytes of random test data. */ BSON_ASSERT(count <= 96); @@ -204,11 +204,11 @@ bool _random(void *ctx, mongocrypt_binary_t *out, uint32_t count, mongocrypt_sta return true; } -bool _sign_rsaes_pkcs1_v1_5(void *ctx, - mongocrypt_binary_t *key, - mongocrypt_binary_t *in, - mongocrypt_binary_t *out, - mongocrypt_status_t *status) { +static bool _sign_rsaes_pkcs1_v1_5(void *ctx, + mongocrypt_binary_t *key, + mongocrypt_binary_t *in, + mongocrypt_binary_t *out, + mongocrypt_status_t *status) { _mongocrypt_buffer_t tmp; BSON_ASSERT(0 == strncmp("error_on:", (char *)ctx, strlen("error_on:"))); @@ -696,7 +696,7 @@ static bool _aes_256_ecb_encrypt(void *ctx, return _native_crypto_aes_256_ecb_encrypt(args); } -void _test_fle2_crypto_via_ecb_hook(_mongocrypt_tester_t *tester) { +static void _test_fle2_crypto_via_ecb_hook(_mongocrypt_tester_t *tester) { const _mongocrypt_value_encryption_algorithm_t *fle2alg = _mcFLE2Algorithm(); bool ret; _mongocrypt_buffer_t key; diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-std-hooks.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-std-hooks.c index 85c569c..f336d67 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-std-hooks.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-std-hooks.c @@ -14,6 +14,10 @@ * limitations under the License. */ +#include "test-mongocrypt-crypto-std-hooks.h" + +// + #include #include "test-mongocrypt.h" diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto.c index 782715a..bdd42d5 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto.c @@ -44,9 +44,10 @@ static bool _test_uses_ctr(const _test_mc_crypto_roundtrip_t *test) { /* we just get garbage data. */ \ ASSERT(out.len == test->plaintext.len); \ ASSERT(memcmp(out.data, test->plaintext.data, out.len) != 0); \ - } else { \ + } else if (1) { \ ASSERT_FAILS_STATUS(ret, status, "HMAC validation failure"); \ - } + } else \ + ((void)0) static void _test_roundtrip_single(const _test_mc_crypto_roundtrip_t *test) { if (!_aes_ctr_is_supported_by_os && _test_uses_ctr(test)) { @@ -283,7 +284,7 @@ typedef struct { const char *expect; } hmac_sha_256_test_t; -void _test_native_crypto_hmac_sha_256(_mongocrypt_tester_t *tester) { +static void _test_native_crypto_hmac_sha_256(_mongocrypt_tester_t *tester) { /* Test data generated with OpenSSL CLI: $ echo -n "test" | openssl dgst -mac hmac -macopt \ hexkey:6bb2664e8d444377d3cd9566c005593b7ed8a35ab8eac9eb5ffa6e426854e5cc \ diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-csfle-lib.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-csfle-lib.c index dca826f..e568f4c 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-csfle-lib.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-csfle-lib.c @@ -96,7 +96,7 @@ static void _test_csfle_load_twice_fail(_mongocrypt_tester_t *tester) { mongocrypt_t *const crypt2 = get_test_mongocrypt(tester); mongocrypt_setopt_set_crypt_shared_lib_path_override(crypt2, "$ORIGIN/stubbed-crypt_shared-2.dll"); // Loading a second different library is an error: - ASSERT_FAILS(_mongocrypt_init_for_test(crypt2), crypt2, "attempted to load a second CSFLE library"); + ASSERT_FAILS(_mongocrypt_init_for_test(crypt2), crypt2, "attempted to load a second crypt_shared library"); mstr_view version = mstrv_view_cstr(mongocrypt_crypt_shared_lib_version_string(crypt1, NULL)); if (TEST_MONGOCRYPT_HAVE_REAL_CRYPT_SHARED_LIB) { @@ -143,7 +143,7 @@ static void _test_csfle_path_override_fail(_mongocrypt_tester_t *tester) { static void _test_cur_exe_path(_mongocrypt_tester_t *tester) { current_module_result self = current_module_path(); BSON_ASSERT(self.error == 0); - BSON_ASSERT(self.path.len != 0); + BSON_ASSERT(self.path.raw.len != 0); mstr_free(self.path); } @@ -180,7 +180,7 @@ static void _test_lookup_version_check(_mongocrypt_tester_t *tester) { mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_WITH_CRYPT_SHARED_LIB); uint64_t version = crypt->csfle.get_version(); mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); - mongocrypt_binary_t *cmd = TEST_FILE("./test/data/lookup/csfle/01-cmd.json"); + mongocrypt_binary_t *cmd = TEST_FILE("./test/data/lookup/csfle/cmd.json"); if (version >= CRYPT_SHARED_8_1) { ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, cmd), ctx); } else { @@ -190,6 +190,15 @@ static void _test_lookup_version_check(_mongocrypt_tester_t *tester) { mongocrypt_destroy(crypt); } +static void _test_loading_libmongocrypt_fails(_mongocrypt_tester_t *tester) { + mongocrypt_t *const crypt = get_test_mongocrypt(tester); + const char *path_to_libmongocrypt = TEST_MONGOCRYPT_MONGOCRYPT_SHARED_PATH; + mongocrypt_setopt_set_crypt_shared_lib_path_override(crypt, path_to_libmongocrypt); + bool ok = mongocrypt_init(crypt); + ASSERT_FAILS(ok, crypt, "detected libmongocrypt"); + mongocrypt_destroy(crypt); +} + void _mongocrypt_tester_install_csfle_lib(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_csfle_no_paths); INSTALL_TEST(_test_csfle_not_found); @@ -202,4 +211,5 @@ void _mongocrypt_tester_install_csfle_lib(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_csfle_not_loaded_with_bypassqueryanalysis); INSTALL_TEST(_test_override_error_includes_reason); INSTALL_TEST(_test_lookup_version_check); + INSTALL_TEST(_test_loading_libmongocrypt_fails); } diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-decrypt.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-decrypt.c index d3ea3c3..826cec6 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-decrypt.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-decrypt.c @@ -123,7 +123,7 @@ static void _test_decrypt_ready(_mongocrypt_tester_t *tester) { } /* Test with empty AWS credentials. */ -void _test_decrypt_empty_aws(_mongocrypt_tester_t *tester) { +static void _test_decrypt_empty_aws(_mongocrypt_tester_t *tester) { mongocrypt_t *crypt; mongocrypt_ctx_t *ctx; @@ -888,7 +888,8 @@ static void _test_explicit_decrypt(_mongocrypt_tester_t *tester) { } // FLE2InsertUpdatePayload can be decrypted. - // Payload is only used in the QE-V1 protocol removed in MongoDB 7.0. Decrypting is currently still supported. + // Payload is only used in the QE-V1 protocol removed in MongoDB 7.0. Decrypting is still supported. + // libmongocrypt no longer produces QE-V1 payloads. Payload is copied from libmongocrypt 1.8.0. { ed_testcase tc = { .desc = "FLE2InsertUpdatePayload", @@ -899,12 +900,13 @@ static void _test_explicit_decrypt(_mongocrypt_tester_t *tester) { ed_testcase_run(&tc); } - // FLE2InsertUpdatePayload with edges can be decrypted. - // Edges are sent on payloads for range algorithm. + // FLE2InsertUpdatePayload for RangeV1 can be decrypted. Range payloads include additional fields. + // Payload is only used in the Range-V1 protocol removed in MongoDB 8.0. Decrypting is still supported. + // libmongocrypt no longer produces Range-V1 payloads. Payload is copied from libmongocrypt 1.11.0. { ed_testcase tc = { - .desc = "FLE2InsertUpdatePayload with edges", - .msg = TEST_FILE("./test/data/explicit-decrypt/FLE2InsertUpdatePayload-with-edges.json"), + .desc = "FLE2InsertUpdatePayload for RangeV1", + .msg = TEST_FILE("./test/data/explicit-decrypt/FLE2InsertUpdatePayload-RangeV1.json"), .keys_to_feed = {keyABC}, .expect = TEST_BSON(BSON_STR({"v" : 123456})), }; @@ -912,7 +914,8 @@ static void _test_explicit_decrypt(_mongocrypt_tester_t *tester) { } // FLE2UnindexedEncryptedValue can be decrypted. - // Payload is only used in the QE-V1 protocol removed in MongoDB 7.0. Decrypting is currently still supported. + // Payload is only used in the QE-V1 protocol removed in MongoDB 7.0. Decrypting is still supported. + // libmongocrypt no longer produces QE-V1 payloads. Payload is copied from libmongocrypt 1.8.0. { ed_testcase tc = { .desc = "FLE2UnindexedEncryptedValue", @@ -924,7 +927,8 @@ static void _test_explicit_decrypt(_mongocrypt_tester_t *tester) { } // FLE2IndexedEqualityEncryptedValue can be decrypted. - // Payload is only used in the QE-V1 protocol removed in MongoDB 7.0. Decrypting is currently still supported. + // Payload is only used in the QE-V1 protocol removed in MongoDB 7.0. Decrypting is still supported. + // libmongocrypt no longer produces QE-V1 payloads. Payload is copied from libmongocrypt 1.8.0. { ed_testcase tc = { .desc = "FLE2IndexedEqualityEncryptedValue", @@ -936,7 +940,8 @@ static void _test_explicit_decrypt(_mongocrypt_tester_t *tester) { } // FLE2IndexedRangeEncryptedValue can be decrypted. - // Payload is only used in the QE-V1 protocol removed in MongoDB 7.0. Decrypting is currently still supported. + // Payload is only used in the QE-V1 protocol removed in MongoDB 7.0. Decrypting is still supported. + // libmongocrypt no longer produces QE-V1 payloads. Payload is copied from libmongocrypt 1.8.0. { ed_testcase tc = { .desc = "FLE2IndexedRangeEncryptedValue", @@ -967,12 +972,24 @@ static void _test_explicit_decrypt(_mongocrypt_tester_t *tester) { ed_testcase_run(&tc); } - // FLE2InsertUpdatePayloadV2 with edges can be decrypted. - // Edges are sent on payloads for range algorithm. + // FLE2InsertUpdatePayloadV2 for RangeV1 can be decrypted. Range payloads include additional fields. + // Payload is only used in the Range-V1 protocol removed in MongoDB 8.0. Decrypting is still supported. + // libmongocrypt no longer produces Range-V1 payloads. Payload is copied from libmongocrypt 1.11.0. { ed_testcase tc = { - .desc = "FLE2InsertUpdatePayloadV2 with edges", - .msg = TEST_FILE("./test/data/explicit-decrypt/FLE2InsertUpdatePayload-with-edges-V2.json"), + .desc = "FLE2InsertUpdatePayloadV2 for RangeV1", + .msg = TEST_FILE("./test/data/explicit-decrypt/FLE2InsertUpdatePayloadV2-RangeV1.json"), + .keys_to_feed = {keyABC}, + .expect = TEST_BSON(BSON_STR({"v" : 123456})), + }; + ed_testcase_run(&tc); + } + + // FLE2InsertUpdatePayloadV2 for RangeV2 can be decrypted. Range payloads include additional fields. + { + ed_testcase tc = { + .desc = "FLE2InsertUpdatePayloadV2 for RangeV2", + .msg = TEST_FILE("./test/data/explicit-decrypt/FLE2InsertUpdatePayloadV2-RangeV2.json"), .keys_to_feed = {keyABC}, .expect = TEST_BSON(BSON_STR({"v" : 123456})), }; @@ -1002,6 +1019,7 @@ static void _test_explicit_decrypt(_mongocrypt_tester_t *tester) { } // FLE2IndexedRangeEncryptedValueV2 can be decrypted. + // Payload did not change between RangeV1 and RangeV2. { ed_testcase tc = { .desc = "FLE2IndexedRangeEncryptedValueV2", diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-encrypt.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-encrypt.c index 5a85672..b4a021a 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-encrypt.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-encrypt.c @@ -883,7 +883,7 @@ static void _init_fails(_mongocrypt_tester_t *tester, const char *json, const ch crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); ctx = mongocrypt_ctx_new(crypt); - ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "test", -1, TEST_BSON(json)), ctx, msg); + ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "test", -1, TEST_BSON_STR(json)), ctx, msg); mongocrypt_ctx_destroy(ctx); mongocrypt_destroy(crypt); } @@ -895,7 +895,7 @@ static void _init_ok(_mongocrypt_tester_t *tester, const char *json) { crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); ctx = mongocrypt_ctx_new(crypt); - ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "test", -1, TEST_BSON(json)), ctx); + ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "test", -1, TEST_BSON_STR(json)), ctx); if (MONGOCRYPT_CTX_NEED_MONGO_COLLINFO == mongocrypt_ctx_state(ctx)) { mongocrypt_binary_t *filter; @@ -923,10 +923,10 @@ static void _init_bypass(_mongocrypt_tester_t *tester, const char *json) { bin = mongocrypt_binary_new(); crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); ctx = mongocrypt_ctx_new(crypt); - ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "test", -1, TEST_BSON(json)), ctx); + ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "test", -1, TEST_BSON_STR(json)), ctx); BSON_ASSERT(MONGOCRYPT_CTX_READY == mongocrypt_ctx_state(ctx)); ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(json), (bin)); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON_STR(json), (bin)); mongocrypt_binary_destroy(bin); mongocrypt_ctx_destroy(ctx); @@ -1087,7 +1087,7 @@ static void _test_explicit_encryption(_mongocrypt_tester_t *tester) { } /* Test with empty AWS credentials. */ -void _test_encrypt_empty_aws(_mongocrypt_tester_t *tester) { +static void _test_encrypt_empty_aws(_mongocrypt_tester_t *tester) { mongocrypt_t *crypt; mongocrypt_ctx_t *ctx; @@ -1608,10 +1608,11 @@ typedef enum { } _test_fle2v2_option; #define TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, data_path, rng_source, v2_failure) \ - { \ + if (1) { \ (rng_source)->pos = 0; \ _test_encrypt_fle2_encryption_placeholder(tester, data_path, rng_source, NULL); \ - } + } else \ + ((void)0) static void _test_encrypt_fle2_encryption_placeholder(_mongocrypt_tester_t *tester, const char *data_path, @@ -1716,28 +1717,28 @@ static void _test_encrypt_fle2_insert_payload(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-v2", &source, NULL); } static void _test_encrypt_fle2_insert_payload_with_str_encode_version(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-v2-with-str-encode-version", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-v2-with-str-encode-version", &source, NULL); } static void _test_encrypt_fle2_insert_text_search_payload(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-text-search", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-text-search", &source, NULL); } static void _test_encrypt_fle2_insert_text_search_payload_with_str_encode_version(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-text-search-with-str-encode-version", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-text-search-with-str-encode-version", &source, NULL); } #undef RNG_DATA @@ -1745,7 +1746,7 @@ static void _test_encrypt_fle2_insert_text_search_payload_with_str_encode_versio // FLE2FindEqualityPayload only uses deterministic token generation. static void _test_encrypt_fle2_find_payload(_mongocrypt_tester_t *tester) { _test_rng_data_source source = {{0}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-equality-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-equality-v2", &source, NULL); } /* 16 bytes of random data are used for IV. This IV produces the expected test @@ -1765,7 +1766,7 @@ static void _test_encrypt_fle2_unindexed_encrypted_payload(_mongocrypt_tester_t static void _test_encrypt_fle2_insert_range_payload_int32(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/int32-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/int32-v2", &source, NULL); } #undef RNG_DATA @@ -1775,7 +1776,7 @@ static void _test_encrypt_fle2_insert_range_payload_int32(_mongocrypt_tester_t * static void _test_encrypt_fle2_insert_range_payload_int64(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/int64-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/int64-v2", &source, NULL); } #undef RNG_DATA @@ -1785,7 +1786,7 @@ static void _test_encrypt_fle2_insert_range_payload_int64(_mongocrypt_tester_t * static void _test_encrypt_fle2_insert_range_payload_date(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/date-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/date-v2", &source, NULL); } #undef RNG_DATA @@ -1795,7 +1796,7 @@ static void _test_encrypt_fle2_insert_range_payload_date(_mongocrypt_tester_t *t static void _test_encrypt_fle2_insert_range_payload_double(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/double-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/double-v2", &source, NULL); } #undef RNG_DATA @@ -1805,18 +1806,18 @@ static void _test_encrypt_fle2_insert_range_payload_double(_mongocrypt_tester_t static void _test_encrypt_fle2_insert_range_payload_double_precision(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/double-precision-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/double-precision-v2", &source, NULL); } #undef RNG_DATA -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() #include "./data/fle2-insert-range/decimal128/RNG_DATA.h" static void _test_encrypt_fle2_insert_range_payload_decimal128(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/decimal128-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/decimal128-v2", &source, NULL); } #undef RNG_DATA @@ -1826,7 +1827,7 @@ static void _test_encrypt_fle2_insert_range_payload_decimal128(_mongocrypt_teste static void _test_encrypt_fle2_insert_range_payload_decimal128_precision(_mongocrypt_tester_t *tester) { uint8_t rng_data[] = RNG_DATA; _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/decimal128-precision-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-range/decimal128-precision-v2", &source, NULL); } #undef RNG_DATA @@ -1835,48 +1836,48 @@ static void _test_encrypt_fle2_insert_range_payload_decimal128_precision(_mongoc // FLE2FindRangePayload only uses deterministic token generation. static void _test_encrypt_fle2_find_range_payload_int32(_mongocrypt_tester_t *tester) { _test_rng_data_source source = {{0}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/int32-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/int32-v2", &source, NULL); } // FLE2FindRangePayload only uses deterministic token generation. static void _test_encrypt_fle2_find_range_payload_int64(_mongocrypt_tester_t *tester) { _test_rng_data_source source = {{0}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/int64-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/int64-v2", &source, NULL); } // FLE2FindRangePayload only uses deterministic token generation. static void _test_encrypt_fle2_find_range_payload_date(_mongocrypt_tester_t *tester) { _test_rng_data_source source = {{0}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/date-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/date-v2", &source, NULL); } // FLE2FindRangePayload only uses deterministic token generation. static void _test_encrypt_fle2_find_range_payload_double(_mongocrypt_tester_t *tester) { _test_rng_data_source source = {{0}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/double-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/double-v2", &source, NULL); } // FLE2FindRangePayload only uses deterministic token generation. static void _test_encrypt_fle2_find_range_payload_double_precision(_mongocrypt_tester_t *tester) { _test_rng_data_source source = {{0}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/double-precision-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/double-precision-v2", &source, NULL); } -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() // FLE2FindRangePayload only uses deterministic token generation. static void _test_encrypt_fle2_find_range_payload_decimal128(_mongocrypt_tester_t *tester) { _test_rng_data_source source = {{0}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/decimal128-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/decimal128-v2", &source, NULL); } // FLE2FindRangePayload only uses deterministic token generation. static void _test_encrypt_fle2_find_range_payload_decimal128_precision(_mongocrypt_tester_t *tester) { _test_rng_data_source source = {{0}}; - TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/decimal128-precision-v2", &source, NULL) + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-find-range/decimal128-precision-v2", &source, NULL); } #endif // MONGOCRYPT_HAVE_DECIMAL128_SUPPORT -static mongocrypt_t *_crypt_with_rng(_test_rng_data_source *rng_source, bool use_range_v2) { +static mongocrypt_t *_crypt_with_rng(_test_rng_data_source *rng_source) { mongocrypt_t *crypt; mongocrypt_binary_t *localkey; /* localkey_data is the KEK used to encrypt the keyMaterial @@ -1898,12 +1899,7 @@ static mongocrypt_t *_crypt_with_rng(_test_rng_data_source *rng_source, bool use crypt); mongocrypt_binary_destroy(localkey); - if (use_range_v2) { - ASSERT_OK(mongocrypt_setopt_use_range_v2(crypt), crypt); - ASSERT_OK(mongocrypt_init(crypt), crypt); - } else { - ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt); - } + ASSERT_OK(mongocrypt_init(crypt), crypt); return crypt; } @@ -1922,7 +1918,6 @@ typedef struct { const char *expect_finalize_error; const char *expect_init_error; bool is_expression; - bool use_range_v2; } ee_testcase; static void ee_testcase_run(ee_testcase *tc) { @@ -1933,12 +1928,9 @@ static void ee_testcase_run(ee_testcase *tc) { if (tc->rng_data.buf.len > 0) { // Use fixed data for random number generation to produce deterministic // results. - crypt = _crypt_with_rng(&tc->rng_data, tc->use_range_v2); + crypt = _crypt_with_rng(&tc->rng_data); } else { tester_mongocrypt_flags flags = TESTER_MONGOCRYPT_DEFAULT; - if (tc->use_range_v2) { - flags |= TESTER_MONGOCRYPT_WITH_RANGE_V2; - } crypt = _mongocrypt_tester_mongocrypt(flags); } mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); @@ -4114,7 +4106,7 @@ static void _test_bulkWrite(_mongocrypt_tester_t *tester) { bson_free(local_kek); } -// `_test_rangePreview_fails` tests that use of "rangePreview" errors when rangeV2 is opted-in. +// `_test_rangePreview_fails` tests that use of "rangePreview" errors. static void _test_rangePreview_fails(_mongocrypt_tester_t *tester) { // 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}; @@ -4126,7 +4118,6 @@ static void _test_rangePreview_fails(_mongocrypt_tester_t *tester) { { mongocrypt_t *crypt = mongocrypt_new(); mongocrypt_setopt_kms_providers(crypt, kms_providers); - ASSERT_OK(mongocrypt_setopt_use_range_v2(crypt), crypt); ASSERT_OK(mongocrypt_init(crypt), crypt); mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); ASSERT_OK(ctx, crypt); @@ -4141,7 +4132,6 @@ static void _test_rangePreview_fails(_mongocrypt_tester_t *tester) { { mongocrypt_t *crypt = mongocrypt_new(); mongocrypt_setopt_kms_providers(crypt, kms_providers); - ASSERT_OK(mongocrypt_setopt_use_range_v2(crypt), crypt); ASSERT_OK(mongocrypt_init(crypt), crypt); mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); ASSERT_OK(ctx, crypt); @@ -4156,7 +4146,6 @@ static void _test_rangePreview_fails(_mongocrypt_tester_t *tester) { { mongocrypt_t *crypt = mongocrypt_new(); mongocrypt_setopt_kms_providers(crypt, kms_providers); - ASSERT_OK(mongocrypt_setopt_use_range_v2(crypt), crypt); ASSERT_OK(mongocrypt_setopt_encrypted_field_config_map( crypt, TEST_FILE("./test/data/fle2-insert-range/int32/encrypted-field-map.json")), // Uses 'rangePreview' @@ -4227,7 +4216,6 @@ static void autoencryption_test_run(autoencryption_test *aet) { } ASSERT_OK(mongocrypt_setopt_encrypted_field_config_map(crypt, aet->encrypted_field_map), crypt); - ASSERT_OK(mongocrypt_setopt_use_range_v2(crypt), crypt); ASSERT_OK(mongocrypt_init(crypt), crypt); } @@ -4357,7 +4345,6 @@ static void _test_range_sends_cryptoParams(_mongocrypt_tester_t *tester) { tc.msg = TEST_BSON("{'v': 123456}"); tc.keys_to_feed[0] = key123; tc.expect = TEST_FILE("./test/data/range-sends-cryptoParams/explicit-insert-int32/expected.json"); - tc.use_range_v2 = true; // Use RangeV2 protocol. ee_testcase_run(&tc); // Check the parameters are present in the final payload. { @@ -4382,7 +4369,6 @@ static void _test_range_sends_cryptoParams(_mongocrypt_tester_t *tester) { tc.msg = TEST_BSON("{'v': 123456}"); tc.keys_to_feed[0] = key123; tc.expect = TEST_FILE("./test/data/range-sends-cryptoParams/explicit-insert-int32-defaults/expected.json"); - tc.use_range_v2 = true; // Use RangeV2 protocol. ee_testcase_run(&tc); // Check the parameters are present in the final payload. { @@ -4408,7 +4394,6 @@ static void _test_range_sends_cryptoParams(_mongocrypt_tester_t *tester) { tc.msg = TEST_BSON("{'v': 123456.0}"); tc.keys_to_feed[0] = key123; tc.expect = TEST_FILE("./test/data/range-sends-cryptoParams/explicit-insert-double/expected.json"); - tc.use_range_v2 = true; // Use RangeV2 protocol. ee_testcase_run(&tc); // Check the parameters are present in the final payload. { @@ -4433,7 +4418,6 @@ static void _test_range_sends_cryptoParams(_mongocrypt_tester_t *tester) { tc.msg = TEST_FILE("./test/data/range-sends-cryptoParams/explicit-find-int32-defaults/to-encrypt.json"); tc.keys_to_feed[0] = key123; tc.expect = TEST_FILE("./test/data/range-sends-cryptoParams/explicit-find-int32-defaults/expected.json"); - tc.use_range_v2 = true; // Use RangeV2 protocol. ee_testcase_run(&tc); // Check the parameters are present in the final payload. { @@ -4458,7 +4442,6 @@ static void _test_range_sends_cryptoParams(_mongocrypt_tester_t *tester) { tc.msg = TEST_FILE("./test/data/range-sends-cryptoParams/explicit-find-int32/to-encrypt.json"); tc.keys_to_feed[0] = key123; tc.expect = TEST_FILE("./test/data/range-sends-cryptoParams/explicit-find-int32/expected.json"); - tc.use_range_v2 = true; // Use RangeV2 protocol. ee_testcase_run(&tc); // Check the parameters are present in the final payload. { @@ -5866,7 +5849,7 @@ void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_encrypt_fle2_insert_range_payload_date); INSTALL_TEST(_test_encrypt_fle2_insert_range_payload_double); INSTALL_TEST(_test_encrypt_fle2_insert_range_payload_double_precision); -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() INSTALL_TEST(_test_encrypt_fle2_insert_range_payload_decimal128); INSTALL_TEST(_test_encrypt_fle2_insert_range_payload_decimal128_precision); #endif @@ -5875,7 +5858,7 @@ void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_encrypt_fle2_find_range_payload_date); INSTALL_TEST(_test_encrypt_fle2_find_range_payload_double); INSTALL_TEST(_test_encrypt_fle2_find_range_payload_double_precision); -#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT +#if MONGOCRYPT_HAVE_DECIMAL128_SUPPORT() INSTALL_TEST(_test_encrypt_fle2_find_range_payload_decimal128); INSTALL_TEST(_test_encrypt_fle2_find_range_payload_decimal128_precision); #endif diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-rewrap-many-datakey.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-rewrap-many-datakey.c index 69381db..8528ebb 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-rewrap-many-datakey.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-rewrap-many-datakey.c @@ -139,7 +139,7 @@ static int64_t _find_date_field(mongocrypt_binary_t *key, const char *dotkey) { ASSERT(bson_iter_init(&iter, &bson)); ASSERT(bson_iter_find_descendant(&iter, dotkey, &iter)); ASSERT(BSON_ITER_HOLDS_DATE_TIME(&iter)); - ASSERT((res = bson_iter_date_time(&iter)) != 0) + ASSERT((res = bson_iter_date_time(&iter)) != 0); return res; } @@ -570,6 +570,33 @@ static void _test_rewrap_many_datakey_need_kms_retry(_mongocrypt_tester_t *teste ASSERT(mongocrypt_kms_ctx_bytes_needed(kms) == 0); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); // To encrypt. + mongocrypt_ctx_destroy(ctx); + + /* Clear key cache. */ + mongocrypt_destroy(crypt); + crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + + /* Ensure KMS encrypt requests retry for network errors */ + ctx = mongocrypt_ctx_new(crypt); + ASSERT_OK(mongocrypt_ctx_rewrap_many_datakey_init(ctx, filter), ctx); + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS); + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, TEST_FILE("./test/data/rmd/key-document-a.json")), ctx); + ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); // To decrypt. + ASSERT((kms = mongocrypt_ctx_next_kms_ctx(ctx))); + ASSERT_OK(mongocrypt_kms_ctx_feed(kms, TEST_FILE("./test/data/rmd/kms-decrypt-reply-a.txt")), kms); + ASSERT(mongocrypt_kms_ctx_bytes_needed(kms) == 0); + ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); // To encrypt. + ASSERT((kms = mongocrypt_ctx_next_kms_ctx(ctx))); + ASSERT(mongocrypt_kms_ctx_fail(kms)); // Simulate driver-side network failure for an encrypt request. + ASSERT((kms = mongocrypt_ctx_next_kms_ctx(ctx))); // Assert fails. Expected KMS request to retry but did not. + ASSERT_OK(mongocrypt_kms_ctx_feed(kms, TEST_FILE("./test/data/rmd/kms-encrypt-reply-a.txt")), kms); + ASSERT(mongocrypt_kms_ctx_bytes_needed(kms) == 0); + ASSERT_OK(!mongocrypt_ctx_next_kms_ctx(ctx), ctx); + ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY); + mongocrypt_ctx_destroy(ctx); mongocrypt_destroy(crypt); } diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-setopt.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-setopt.c index 495c625..d6da72d 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-setopt.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-setopt.c @@ -28,61 +28,61 @@ static char invalid_utf8[] = {(char)0x80, (char)0x00}; /* Convenience macros for setting options */ #define ASSERT_MASTERKEY_AWS_OK(region, region_len, cmk, cmk_len) \ - ASSERT_OK(mongocrypt_ctx_setopt_masterkey_aws(ctx, region, region_len, cmk, cmk_len), ctx); + ASSERT_OK(mongocrypt_ctx_setopt_masterkey_aws(ctx, region, region_len, cmk, cmk_len), ctx) #define ASSERT_MASTERKEY_AWS_FAILS(region, region_len, cmk, cmk_len, msg) \ - ASSERT_FAILS(mongocrypt_ctx_setopt_masterkey_aws(ctx, region, region_len, cmk, cmk_len), ctx, msg); + ASSERT_FAILS(mongocrypt_ctx_setopt_masterkey_aws(ctx, region, region_len, cmk, cmk_len), ctx, msg) -#define ASSERT_MASTERKEY_LOCAL_OK ASSERT_OK(mongocrypt_ctx_setopt_masterkey_local(ctx), ctx); -#define ASSERT_MASTERKEY_LOCAL_FAILS(msg) ASSERT_FAILS(mongocrypt_ctx_setopt_masterkey_local(ctx), ctx, msg); +#define ASSERT_MASTERKEY_LOCAL_OK ASSERT_OK(mongocrypt_ctx_setopt_masterkey_local(ctx), ctx) +#define ASSERT_MASTERKEY_LOCAL_FAILS(msg) ASSERT_FAILS(mongocrypt_ctx_setopt_masterkey_local(ctx), ctx, msg) -#define ASSERT_KEY_ENCRYPTION_KEY_OK(bin) ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, bin), ctx); +#define ASSERT_KEY_ENCRYPTION_KEY_OK(bin) ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, bin), ctx) #define ASSERT_KEY_ENCRYPTION_KEY_FAILS(bin, msg) \ - ASSERT_FAILS(mongocrypt_ctx_setopt_key_encryption_key(ctx, bin), ctx, msg); + ASSERT_FAILS(mongocrypt_ctx_setopt_key_encryption_key(ctx, bin), ctx, msg) -#define ASSERT_KEY_ID_OK(key_id) ASSERT_OK(mongocrypt_ctx_setopt_key_id(ctx, key_id), ctx); -#define ASSERT_KEY_ID_FAILS(key_id, msg) ASSERT_FAILS(mongocrypt_ctx_setopt_key_id(ctx, key_id), ctx, msg); +#define ASSERT_KEY_ID_OK(key_id) ASSERT_OK(mongocrypt_ctx_setopt_key_id(ctx, key_id), ctx) +#define ASSERT_KEY_ID_FAILS(key_id, msg) ASSERT_FAILS(mongocrypt_ctx_setopt_key_id(ctx, key_id), ctx, msg) -#define ASSERT_KEY_ALT_NAME_OK(key_alt_name) ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, key_alt_name), ctx); +#define ASSERT_KEY_ALT_NAME_OK(key_alt_name) ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, key_alt_name), ctx) #define ASSERT_KEY_ALT_NAME_FAILS(key_alt_name, msg) \ - ASSERT_FAILS(mongocrypt_ctx_setopt_key_alt_name(ctx, key_alt_name), ctx, msg); + ASSERT_FAILS(mongocrypt_ctx_setopt_key_alt_name(ctx, key_alt_name), ctx, msg) -#define ASSERT_KEY_MATERIAL_OK(key_material) ASSERT_OK(mongocrypt_ctx_setopt_key_material(ctx, key_material), ctx); +#define ASSERT_KEY_MATERIAL_OK(key_material) ASSERT_OK(mongocrypt_ctx_setopt_key_material(ctx, key_material), ctx) #define ASSERT_KEY_MATERIAL_FAILS(key_material, msg) \ - ASSERT_FAILS(mongocrypt_ctx_setopt_key_material(ctx, key_material), ctx, msg); + ASSERT_FAILS(mongocrypt_ctx_setopt_key_material(ctx, key_material), ctx, msg) -#define ASSERT_ALGORITHM_OK(algo, algo_len) ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, algo, algo_len), ctx); +#define ASSERT_ALGORITHM_OK(algo, algo_len) ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, algo, algo_len), ctx) #define ASSERT_ALGORITHM_FAILS(algo, algo_len, msg) \ - ASSERT_FAILS(mongocrypt_ctx_setopt_algorithm(ctx, algo, algo_len), ctx, msg); + ASSERT_FAILS(mongocrypt_ctx_setopt_algorithm(ctx, algo, algo_len), ctx, msg) -#define ASSERT_QUERY_TYPE_OK(qt, qt_len) ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, qt, qt_len), ctx); +#define ASSERT_QUERY_TYPE_OK(qt, qt_len) ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, qt, qt_len), ctx) #define ASSERT_QUERY_TYPE_FAILS(qt, qt_len, msg) \ - ASSERT_FAILS(mongocrypt_ctx_setopt_query_type(ctx, qt, qt_len), ctx, msg); + ASSERT_FAILS(mongocrypt_ctx_setopt_query_type(ctx, qt, qt_len), ctx, msg) #define ASSERT_ENDPOINT_OK(endpoint, endpoint_len) \ - ASSERT_OK(mongocrypt_ctx_setopt_masterkey_aws_endpoint(ctx, endpoint, endpoint_len), ctx); + ASSERT_OK(mongocrypt_ctx_setopt_masterkey_aws_endpoint(ctx, endpoint, endpoint_len), ctx) #define ASSERT_ENDPOINT_FAILS(endpoint, endpoint_len, msg) \ - ASSERT_FAILS(mongocrypt_ctx_setopt_masterkey_aws_endpoint(ctx, endpoint, endpoint_len), ctx, msg); + ASSERT_FAILS(mongocrypt_ctx_setopt_masterkey_aws_endpoint(ctx, endpoint, endpoint_len), ctx, msg) -#define ASSERT_DATAKEY_INIT_OK ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx); -#define ASSERT_DATAKEY_INIT_FAILS(msg) ASSERT_FAILS(mongocrypt_ctx_datakey_init(ctx), ctx, msg); +#define ASSERT_DATAKEY_INIT_OK ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx) +#define ASSERT_DATAKEY_INIT_FAILS(msg) ASSERT_FAILS(mongocrypt_ctx_datakey_init(ctx), ctx, msg) -#define ASSERT_ENCRYPT_INIT_OK(db, db_len, cmd) ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, db, db_len, cmd), ctx); +#define ASSERT_ENCRYPT_INIT_OK(db, db_len, cmd) ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, db, db_len, cmd), ctx) #define ENCRYPT_INIT_FAILS(db, db_len, cmd, msg) \ - ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, db, db_len, cmd), ctx, msg); + ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, db, db_len, cmd), ctx, msg) -#define ASSERT_EX_ENCRYPT_INIT_OK(bin) ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, bin), ctx); -#define ASSERT_EX_ENCRYPT_INIT_FAILS(bin, msg) ASSERT_FAILS(mongocrypt_ctx_explicit_encrypt_init(ctx, bin), ctx, msg); +#define ASSERT_EX_ENCRYPT_INIT_OK(bin) ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, bin), ctx) +#define ASSERT_EX_ENCRYPT_INIT_FAILS(bin, msg) ASSERT_FAILS(mongocrypt_ctx_explicit_encrypt_init(ctx, bin), ctx, msg) #define ASSERT_EX_ENCRYPT_EXPRESSION_INIT_OK(bin) \ - ASSERT_OK(mongocrypt_ctx_explicit_encrypt_expression_init(ctx, bin), ctx); + ASSERT_OK(mongocrypt_ctx_explicit_encrypt_expression_init(ctx, bin), ctx) #define ASSERT_EX_ENCRYPT_EXPRESSION_INIT_FAILS(bin, msg) \ - ASSERT_FAILS(mongocrypt_ctx_explicit_encrypt_expression_init(ctx, bin), ctx, msg); + ASSERT_FAILS(mongocrypt_ctx_explicit_encrypt_expression_init(ctx, bin), ctx, msg) -#define ASSERT_DECRYPT_INIT_OK(bin) ASSERT_OK(mongocrypt_ctx_decrypt_init(ctx, bin), ctx); -#define ASSERT_DECRYPT_INIT_FAILS(bin, msg) ASSERT_FAILS(mongocrypt_ctx_decrypt_init(ctx, bin), ctx, msg); +#define ASSERT_DECRYPT_INIT_OK(bin) ASSERT_OK(mongocrypt_ctx_decrypt_init(ctx, bin), ctx) +#define ASSERT_DECRYPT_INIT_FAILS(bin, msg) ASSERT_FAILS(mongocrypt_ctx_decrypt_init(ctx, bin), ctx, msg) -#define ASSERT_EX_DECRYPT_INIT_OK(bin) ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, bin), ctx); -#define ASSERT_EX_DECRYPT_INIT_FAILS(bin, msg) ASSERT_FAILS(mongocrypt_ctx_explicit_decrypt_init(ctx, bin), ctx, msg); +#define ASSERT_EX_DECRYPT_INIT_OK(bin) ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, bin), ctx) +#define ASSERT_EX_DECRYPT_INIT_FAILS(bin, msg) ASSERT_FAILS(mongocrypt_ctx_explicit_decrypt_init(ctx, bin), ctx, msg) #define REFRESH \ do { \ @@ -296,11 +296,13 @@ static void _test_setopt_key_alt_name(_mongocrypt_tester_t *tester) { } static void _test_setopt_key_material(_mongocrypt_tester_t *tester) { +#define KEY_MATERIAL_PATTERN "{'keyMaterial': {'$binary': {'base64': '%s', 'subType': '00'}}%s}" + /* "0123456789abcef", repeated 6 times. */ const char *const material = "MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1" "Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVm"; - const char *const pattern = "{'keyMaterial': {'$binary': {'base64': '%s', 'subType': '00'}}%s}"; - mongocrypt_binary_t *const valid = TEST_BSON(pattern, material, ""); + + mongocrypt_binary_t *const valid = TEST_BSON(KEY_MATERIAL_PATTERN, material, ""); mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); mongocrypt_ctx_t *ctx = NULL; @@ -320,18 +322,19 @@ static void _test_setopt_key_material(_mongocrypt_tester_t *tester) { /* Test empty key material. */ REFRESH; - ASSERT_KEY_MATERIAL_FAILS(TEST_BSON(pattern, "", ""), "keyMaterial should have length 96, but has length 0"); + ASSERT_KEY_MATERIAL_FAILS(TEST_BSON(KEY_MATERIAL_PATTERN, "", ""), + "keyMaterial should have length 96, but has length 0"); /* Test too short key material. */ REFRESH; - ASSERT_KEY_MATERIAL_FAILS(TEST_BSON(pattern, + ASSERT_KEY_MATERIAL_FAILS(TEST_BSON(KEY_MATERIAL_PATTERN, "dG9vc2hvcnQ=", /* "tooshort" */ ""), "keyMaterial should have length 96, but has length 8"); /* Test too long key material. */ REFRESH; - ASSERT_KEY_MATERIAL_FAILS(TEST_BSON(pattern, + ASSERT_KEY_MATERIAL_FAILS(TEST_BSON(KEY_MATERIAL_PATTERN, /* "0123456789abcdef", repeated 6 times, followed by "toolong". */ "MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyM" "zQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmdG9vbG9uZw" @@ -351,7 +354,7 @@ static void _test_setopt_key_material(_mongocrypt_tester_t *tester) { /* Test extra key. */ REFRESH; - ASSERT_KEY_MATERIAL_FAILS(TEST_BSON(pattern, material, ", 'a': 1"), + ASSERT_KEY_MATERIAL_FAILS(TEST_BSON(KEY_MATERIAL_PATTERN, material, ", 'a': 1"), "unrecognized field, only keyMaterial expected"); /* Test error propagation. */ @@ -361,6 +364,8 @@ static void _test_setopt_key_material(_mongocrypt_tester_t *tester) { mongocrypt_ctx_destroy(ctx); mongocrypt_destroy(crypt); + +#undef KEY_MATERIAL_PATTERN } static void _test_setopt_algorithm(_mongocrypt_tester_t *tester) { @@ -393,7 +398,7 @@ static void _test_setopt_algorithm(_mongocrypt_tester_t *tester) { REFRESH; _mongocrypt_ctx_fail_w_msg(ctx, "test"); - ASSERT_ALGORITHM_FAILS(RAND, -1, "test") + ASSERT_ALGORITHM_FAILS(RAND, -1, "test"); /* Test case insensitive. */ REFRESH; @@ -435,7 +440,7 @@ static void _test_setopt_query_type(_mongocrypt_tester_t *tester) { /* Test with failed context. */ REFRESH; _mongocrypt_ctx_fail_w_msg(ctx, "test"); - ASSERT_QUERY_TYPE_FAILS(MONGOCRYPT_QUERY_TYPE_EQUALITY_STR, -1, "test") + ASSERT_QUERY_TYPE_FAILS(MONGOCRYPT_QUERY_TYPE_EQUALITY_STR, -1, "test"); /* Test case insensitive. */ REFRESH; @@ -652,7 +657,7 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { REFRESH; ASSERT_ALGORITHM_OK(RAND, -1); - ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "key id or key alt name required") + ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "key id or key alt name required"); REFRESH; ASSERT_KEY_ID_OK(uuid); @@ -843,7 +848,7 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { { // Create a crypt with rangeV2 enabled. mongocrypt_destroy(crypt); - crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT | TESTER_MONGOCRYPT_WITH_RANGE_V2); + crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT | TESTER_MONGOCRYPT_DEFAULT); REFRESH_CTX; /* Set key ID to get past the 'either key id or key alt name required' * error */ @@ -899,7 +904,7 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { // Can't use "rangePreview" algorithm or query type with range V2. { mongocrypt_destroy(crypt); - crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_WITH_RANGE_V2); + crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); REFRESH_CTX; ASSERT_KEY_ID_OK(uuid); ASSERT_FAILS(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR, -1), @@ -907,7 +912,7 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { "'rangePreview' is deprecated"); mongocrypt_destroy(crypt); - crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_WITH_RANGE_V2); + 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_RANGEPREVIEW_DEPRECATED_STR, -1), @@ -915,58 +920,12 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) { "'rangePreview' is deprecated"); } - /* Error if query type == "rangePreview" and algorithm == "range" for range V1. */ - // Explanation: Algorithm "rangePreview" accepts both query type "rangePreview" (for compatibility) and "range" (new - // behavior), but algorithm "range" only accepts query type "range". This is because if we are using the new - // algorithm type, we don't need to support the deprecated name for compatibility. + /* If query type == algorithm == "range", succeeds. */ { REFRESH; ASSERT_KEY_ID_OK(uuid); ASSERT_OK(mongocrypt_ctx_setopt_algorithm_range(ctx, rangeopts), ctx); ASSERT_ALGORITHM_OK(MONGOCRYPT_ALGORITHM_RANGE_STR, -1); - ASSERT_QUERY_TYPE_OK(MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED_STR, -1); - ASSERT_OK(mongocrypt_ctx_setopt_contention_factor(ctx, 0), ctx); - ASSERT_EX_ENCRYPT_EXPRESSION_INIT_FAILS(bson, "must match index_type"); - } - - /* If query type == "range" and algorithm == "rangePreview", succeeds for range V1 */ - { - REFRESH; - ASSERT_KEY_ID_OK(uuid); - ASSERT_OK(mongocrypt_ctx_setopt_algorithm_range(ctx, rangeopts), ctx); - ASSERT_ALGORITHM_OK(MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR, -1); - ASSERT_QUERY_TYPE_OK(MONGOCRYPT_QUERY_TYPE_RANGE_STR, -1); - ASSERT_OK(mongocrypt_ctx_setopt_contention_factor(ctx, 0), ctx); - ASSERT_EX_ENCRYPT_EXPRESSION_INIT_OK(bson); - } - - /* If query type == algorithm == "rangePreview", succeeds for range V1. */ - { - REFRESH; - ASSERT_KEY_ID_OK(uuid); - ASSERT_OK(mongocrypt_ctx_setopt_algorithm_range(ctx, rangeopts), ctx); - ASSERT_ALGORITHM_OK(MONGOCRYPT_ALGORITHM_RANGEPREVIEW_DEPRECATED_STR, -1); - ASSERT_QUERY_TYPE_OK(MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED_STR, -1); - ASSERT_OK(mongocrypt_ctx_setopt_contention_factor(ctx, 0), ctx); - ASSERT_EX_ENCRYPT_EXPRESSION_INIT_OK(bson); - } - - /* If query type == algorithm == "range", succeeds for both V2 and V1. */ - { - REFRESH; - ASSERT_KEY_ID_OK(uuid); - ASSERT_OK(mongocrypt_ctx_setopt_algorithm_range(ctx, rangeopts), ctx); - ASSERT_ALGORITHM_OK(MONGOCRYPT_ALGORITHM_RANGE_STR, -1); - ASSERT_QUERY_TYPE_OK(MONGOCRYPT_QUERY_TYPE_RANGE_STR, -1); - ASSERT_OK(mongocrypt_ctx_setopt_contention_factor(ctx, 0), ctx); - ASSERT_EX_ENCRYPT_EXPRESSION_INIT_OK(bson); - - mongocrypt_destroy(crypt); - crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_WITH_RANGE_V2); - REFRESH_CTX; - ASSERT_KEY_ID_OK(uuid); - ASSERT_OK(mongocrypt_ctx_setopt_algorithm_range(ctx, rangeopts), ctx); - ASSERT_ALGORITHM_OK(MONGOCRYPT_ALGORITHM_RANGE_STR, -1); ASSERT_QUERY_TYPE_OK(MONGOCRYPT_QUERY_TYPE_RANGE_STR, -1); ASSERT_OK(mongocrypt_ctx_setopt_contention_factor(ctx, 0), ctx); ASSERT_EX_ENCRYPT_EXPRESSION_INIT_OK(bson); @@ -1148,7 +1107,7 @@ static void _test_setopt_endpoint(_mongocrypt_tester_t *tester) { REFRESH; _mongocrypt_ctx_fail_w_msg(ctx, "test"); - ASSERT_ENDPOINT_FAILS(RAND, -1, "test") + ASSERT_ENDPOINT_FAILS(RAND, -1, "test"); mongocrypt_ctx_destroy(ctx); mongocrypt_destroy(crypt); @@ -1169,7 +1128,7 @@ static void _test_createdatakey_with_wrong_kms_provider_helper(_mongocrypt_teste mongocrypt_setopt_use_need_kms_credentials_state(crypt); ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt); ctx = mongocrypt_ctx_new(crypt); - ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(kek)), ctx); + ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON_STR(kek)), ctx); ASSERT_FAILS(mongocrypt_ctx_datakey_init(ctx), ctx, "kms provider required by datakey is not configured"); mongocrypt_ctx_destroy(ctx); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-datakey.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-datakey.c index 8be2898..1d48940 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-datakey.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-datakey.c @@ -539,7 +539,7 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { const char *str = (const char *)mongocrypt_binary_data(bin); ASSERT_STRCONTAINS(str, "oauth2"); mongocrypt_binary_destroy(bin); - }; + } // Feed a successful response. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kms_ctx); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-dll.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-dll.c index 557343d..2cfc889 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-dll.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-dll.c @@ -13,10 +13,13 @@ static void _test_load_simple_library(_mongocrypt_tester_t *t) { mstr dll_path = mpath_join(mpath_parent(self_path.view, MPATH_NATIVE), mstrv_view_cstr("test-dll.dll"), MPATH_NATIVE); - mcr_dll lib = mcr_dll_open(dll_path.data); - BSON_ASSERT(lib.error_string.len == 0); + mcr_dll lib = mcr_dll_open(dll_path.raw.data); + BSON_ASSERT(lib.error_string.raw.len == 0); + + MC_BEGIN_CAST_FUNCTION_TYPE_STRICT_IGNORE + int (*say_hello)(void) = (int (*)(void))mcr_dll_sym(lib, "say_hello"); + MC_END_CAST_FUNCTION_TYPE_STRICT_IGNORE - int (*say_hello)(void) = mcr_dll_sym(lib, "say_hello"); BSON_ASSERT(say_hello != NULL); int rval = say_hello(); @@ -31,7 +34,7 @@ static void _test_load_nonesuch(_mongocrypt_tester_t *t) { (void)t; mcr_dll lib = mcr_dll_open("no-such-directory/no-such-lib.dll"); BSON_ASSERT(lib._native_handle == NULL); - BSON_ASSERT(lib.error_string.len > 0); + BSON_ASSERT(lib.error_string.raw.len > 0); mcr_dll_close(lib); } diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-endpoint.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-endpoint.c index d03f722..474a1ec 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-endpoint.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-endpoint.c @@ -18,7 +18,7 @@ #include "test-mongocrypt.h" -void _test_mongocrypt_endpoint(_mongocrypt_tester_t *tester) { +static void _test_mongocrypt_endpoint(_mongocrypt_tester_t *tester) { _mongocrypt_endpoint_t *endpoint; mongocrypt_status_t *status; _mongocrypt_endpoint_parse_opts_t opts; diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kek.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kek.c index b0a4fde..f4da6bb 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kek.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kek.c @@ -81,7 +81,7 @@ static void _run_one_test(_mongocrypt_tester_t *tester, bson_t *test) { mongocrypt_status_destroy(status); } -void test_mongocrypt_kek_parsing(_mongocrypt_tester_t *tester) { +static void test_mongocrypt_kek_parsing(_mongocrypt_tester_t *tester) { bson_t test_file; bson_iter_t iter; diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key-cache.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key-cache.c index a92ac95..fa14a53 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key-cache.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key-cache.c @@ -30,7 +30,7 @@ typedef struct { /* The JSON spec tests refer to key ids by a shorthand integer. * This function maps that integer to a UUID buffer. */ -void lookup_key_id(uint32_t index, _mongocrypt_buffer_t *buf) { +static void lookup_key_id(uint32_t index, _mongocrypt_buffer_t *buf) { const char *key_ids[] = {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"}; @@ -44,10 +44,8 @@ void lookup_key_id(uint32_t index, _mongocrypt_buffer_t *buf) { /* Generate a realistic key document given a @key_description, which contains an * _id * and possible keyAltNames. key_out and key_doc_out are NULLable outputs. */ -void gen_key(_mongocrypt_tester_t *tester, - bson_t *key_description, - bson_t *key_out, - _mongocrypt_key_doc_t *key_doc_out) { +static void +gen_key(_mongocrypt_tester_t *tester, bson_t *key_description, bson_t *key_out, _mongocrypt_key_doc_t *key_doc_out) { bson_iter_t iter; _mongocrypt_buffer_t key_material; _mongocrypt_buffer_t key_id; diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-ctx.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-ctx.c index 156a159..f26cacc 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-ctx.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-ctx.c @@ -611,7 +611,7 @@ static void _test_mongocrypt_kms_ctx_kmip_encrypt(_mongocrypt_tester_t *tester) _mongocrypt_endpoint_t *endpoint; _mongocrypt_buffer_t plaintext = {0}; - ASSERT(_mongocrypt_buffer_copy_from_data_and_size(&plaintext, PLAINTEXT, sizeof(PLAINTEXT))) + ASSERT(_mongocrypt_buffer_copy_from_data_and_size(&plaintext, PLAINTEXT, sizeof(PLAINTEXT))); status = mongocrypt_status_new(); endpoint = _mongocrypt_endpoint_new("example.com", -1, NULL /* opts */, status); @@ -748,7 +748,7 @@ static void _test_mongocrypt_kms_ctx_kmip_decrypt(_mongocrypt_tester_t *tester) key_doc.kek.kms_provider = MONGOCRYPT_KMS_PROVIDER_KMIP; key_doc.kek.provider.kmip.delegated = true; key_doc.kek.provider.kmip.key_id = (char *)KEK_UNIQUE_IDENTIFIER; - ASSERT(_mongocrypt_buffer_copy_from_data_and_size(&key_doc.key_material, IV_CIPHERTEXT, sizeof(IV_CIPHERTEXT))) + ASSERT(_mongocrypt_buffer_copy_from_data_and_size(&key_doc.key_material, IV_CIPHERTEXT, sizeof(IV_CIPHERTEXT))); status = mongocrypt_status_new(); endpoint = _mongocrypt_endpoint_new("example.com", -1, NULL /* opts */, status); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-local-kms.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-local-kms.c index d80cc9b..b364731 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-local-kms.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-local-kms.c @@ -75,4 +75,4 @@ static void _test_local_roundtrip(_mongocrypt_tester_t *tester) { void _mongocrypt_tester_install_local_kms(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_local_roundtrip); -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-log.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-log.c index bef2be5..78b54d8 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-log.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-log.c @@ -88,10 +88,10 @@ static void _test_trace_log(_mongocrypt_tester_t *tester) { #if defined(__GLIBC__) || defined(__APPLE__) static void _test_no_log(_mongocrypt_tester_t *tester) { - const int buffer_size = BUFSIZ; mongocrypt_t *crypt; mongocrypt_status_t *status; - char captured_logs[buffer_size]; + char captured_logs[BUFSIZ]; + const int buffer_size = sizeof(captured_logs); int saved_stdout = dup(1); /* Redirect stdout to /dev/null and capture output in a buffer diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-marking.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-marking.c index 877dd49..ee3494c 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-marking.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-marking.c @@ -18,10 +18,12 @@ #include "bson/bson.h" #include "mc-fle-blob-subtype-private.h" +#include "mc-fle2-find-text-payload-private.h" #include "mc-tokens-private.h" #include "mongocrypt-buffer-private.h" #include "mongocrypt-ciphertext-private.h" #include "mongocrypt-marking-private.h" +#include "mongocrypt-private.h" #include "mongocrypt.h" #include "test-mongocrypt-assert.h" #include "test-mongocrypt.h" @@ -68,8 +70,8 @@ static void test_mongocrypt_marking_parse(_mongocrypt_tester_t *tester) { marking_bson = TMP_BSON("{'a': 2, 'v': 'abc', 'ka': 'alt'}"); _make_marking(marking_bson, &marking_buf); _parse_ok(&marking_buf, &marking); - BSON_ASSERT(marking.algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM); - BSON_ASSERT(0 == strcmp("abc", bson_iter_utf8(&marking.v_iter, NULL))); + BSON_ASSERT(marking.u.fle1.algorithm == MONGOCRYPT_ENCRYPTION_ALGORITHM_RANDOM); + BSON_ASSERT(0 == strcmp("abc", bson_iter_utf8(&marking.u.fle1.v_iter, NULL))); _mongocrypt_buffer_cleanup(&marking_buf); _mongocrypt_marking_cleanup(&marking); @@ -198,36 +200,9 @@ static void test_mc_get_mincover_from_FLE2RangeFindSpec(_mongocrypt_tester_t *te mc_optional_int64_t sparsity; const char *expectedError; const char *expectedErrorAtParseTime; - bool disableRangeV2; } testcase_t; testcase_t tests[] = { - {.description = "Range V2 disabled w/ trim factor fails", - .findSpecJSON = RAW_STRING({ - "lowerBound" : {"$numberInt" : "7"}, - "lbIncluded" : true, - "upperBound" : {"$numberInt" : "32"}, - "ubIncluded" : true, - "indexMin" : {"$numberInt" : "0"}, - "indexMax" : {"$numberInt" : "32"}, - "trimFactor" : 0 - }), - .disableRangeV2 = true, - .expectedErrorAtParseTime = "'trimFactor' is not supported for QE range v1"}, - {.description = "Range V2 disabled w/ no trim factor succeeds", - .findSpecJSON = RAW_STRING({ - "lowerBound" : {"$numberInt" : "7"}, - "lbIncluded" : true, - "upperBound" : {"$numberInt" : "32"}, - "ubIncluded" : true, - "indexMin" : {"$numberInt" : "0"}, - "indexMax" : {"$numberInt" : "32"} - }), - .disableRangeV2 = true, - .expectedMinCover = "000111\n" - "001\n" - "01\n" - "100000\n"}, {.description = "Int32 Bounds included", .findSpecJSON = RAW_STRING({ "lowerBound" : {"$numberInt" : "7"}, @@ -875,7 +850,7 @@ static void test_mc_get_mincover_from_FLE2RangeFindSpec(_mongocrypt_tester_t *te ASSERT(bson_iter_init_find(&findSpecIter, findSpecDoc, "findSpec")); mc_FLE2RangeFindSpec_t findSpec; - bool res = mc_FLE2RangeFindSpec_parse(&findSpec, &findSpecIter, !test->disableRangeV2, status); + bool res = mc_FLE2RangeFindSpec_parse(&findSpec, &findSpecIter, status); if (test->expectedErrorAtParseTime) { ASSERT(!res); ASSERT_STATUS_CONTAINS(status, test->expectedErrorAtParseTime); @@ -889,8 +864,7 @@ static void test_mc_get_mincover_from_FLE2RangeFindSpec(_mongocrypt_tester_t *te sparsity = (size_t)test->sparsity.value; } - const bool use_range_v2 = !test->disableRangeV2; - mc_mincover_t *mc = mc_get_mincover_from_FLE2RangeFindSpec(&findSpec, sparsity, status, use_range_v2); + mc_mincover_t *mc = mc_get_mincover_from_FLE2RangeFindSpec(&findSpec, sparsity, status); if (test->expectedError) { ASSERT(NULL == mc); @@ -950,7 +924,7 @@ static void get_ciphertext_from_marking_json(_mongocrypt_tester_t *tester, const char *markingJSON, _mongocrypt_ciphertext_t *out) { get_ciphertext_from_marking_json_with_bufs(crypt, - TMP_BSON(markingJSON), + TMP_BSON_STR(markingJSON), out, TEST_FILE("./test/example/cmd.json"), TEST_BIN(16), @@ -1089,11 +1063,9 @@ static iupv2_fields_common validate_iupv2_common(bson_t *iup_bson) { // Assert that the encryptedTokens fields in V2 insert/update ciphertext matches our expectations. Specifically, checks // that the length of these fields are what we expect, and that the "isLeaf" token is appended when using range V2. -static void validate_range_ciphertext(_mongocrypt_ciphertext_t *ciphertext, - mongocrypt_t *crypt, - bool useRangeV2, - uint32_t expectedEdges) { - uint32_t expectedPLength = useRangeV2 ? (MONGOCRYPT_HMAC_SHA256_LEN + 1) : MONGOCRYPT_HMAC_SHA256_LEN; +static void +validate_range_ciphertext(_mongocrypt_ciphertext_t *ciphertext, mongocrypt_t *crypt, uint32_t expectedEdges) { + uint32_t expectedPLength = (MONGOCRYPT_HMAC_SHA256_LEN + 1); bson_t ciphertextBSON; bson_iter_t iter; @@ -1109,14 +1081,10 @@ static void validate_range_ciphertext(_mongocrypt_ciphertext_t *ciphertext, ASSERT(res.p.len == 16 + expectedPLength); // validate crypto of 'p' - if (useRangeV2) { - uint8_t is_leaf = 255; - validate_encrypted_token(crypt, &res.p, &res.s, true, &is_leaf); - // isLeaf byte should be 0. - ASSERT(is_leaf == 0); - } else { - validate_encrypted_token(crypt, &res.p, &res.s, false, NULL); - } + uint8_t is_leaf = 255; + validate_encrypted_token(crypt, &res.p, &res.s, true, &is_leaf); + // isLeaf byte should be 0. + ASSERT(is_leaf == 0); // 'g' field should be available ASSERT(bson_iter_init_find(&iter, &ciphertextBSON, "g")); @@ -1150,24 +1118,18 @@ static void validate_range_ciphertext(_mongocrypt_ciphertext_t *ciphertext, ASSERT_CMPUINT32(encrypted_token_bin.len, ==, 16 + expectedPLength); ASSERT_CMPUINT32(esc_token_bin.len, ==, MONGOCRYPT_HMAC_SHA256_LEN); - if (useRangeV2) { - uint8_t is_leaf = 255; - validate_encrypted_token(crypt, &encrypted_token_bin, &esc_token_bin, true, &is_leaf); - // isLeaf byte should be either 0 or 1. - if (is_leaf == 1) { - leaf_count++; - } else { - ASSERT_CMPUINT8(is_leaf, ==, 0) - } + uint8_t is_leaf = 255; + validate_encrypted_token(crypt, &encrypted_token_bin, &esc_token_bin, true, &is_leaf); + // isLeaf byte should be either 0 or 1. + if (is_leaf == 1) { + leaf_count++; } else { - validate_encrypted_token(crypt, &encrypted_token_bin, &esc_token_bin, false, NULL); + ASSERT_CMPUINT8(is_leaf, ==, 0); } } ASSERT_CMPSIZE_T(g_count, ==, expectedEdges); - if (useRangeV2) { - // There should be exactly one leaf in any insert call. - ASSERT_CMPSIZE_T(leaf_count, ==, 1); - } + // There should be exactly one leaf in any insert call. + ASSERT_CMPSIZE_T(leaf_count, ==, 1); bson_destroy(&ciphertextBSON); } @@ -1177,25 +1139,7 @@ static void test_mc_marking_to_ciphertext_fle2_range(_mongocrypt_tester_t *teste return; } - // Test that whether range V2 is enabled or disabled, the ciphertext matches our expectations. - { - const char markingJSON[] = RAW_STRING({ - 't' : 1, - 'a' : 3, - 'v' : {'min' : 0, 'max' : 7, 'v' : 5}, - 's' : {'$numberLong' : '1'}, - 'cm' : {'$numberLong' : '1'} - }); - _mongocrypt_ciphertext_t ciphertext; - _mongocrypt_ciphertext_init(&ciphertext); - mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); - - get_ciphertext_from_marking_json(tester, crypt, markingJSON, &ciphertext); - - validate_range_ciphertext(&ciphertext, crypt, false, 4); - _mongocrypt_ciphertext_cleanup(&ciphertext); - mongocrypt_destroy(crypt); - } + // Test that ciphertext matches our expectations. { const char markingJSON[] = RAW_STRING({ 't' : 1, @@ -1206,11 +1150,11 @@ static void test_mc_marking_to_ciphertext_fle2_range(_mongocrypt_tester_t *teste }); _mongocrypt_ciphertext_t ciphertext; _mongocrypt_ciphertext_init(&ciphertext); - mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_WITH_RANGE_V2); + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); get_ciphertext_from_marking_json(tester, crypt, markingJSON, &ciphertext); - validate_range_ciphertext(&ciphertext, crypt, true, 4); + validate_range_ciphertext(&ciphertext, crypt, 4); _mongocrypt_ciphertext_cleanup(&ciphertext); mongocrypt_destroy(crypt); @@ -1280,13 +1224,13 @@ typedef struct { static void validate_text_search_ciphertext(_mongocrypt_tester_t *tester, _mongocrypt_ciphertext_t *ciphertext, mongocrypt_t *crypt, - const char *text_value, + mc_FLE2TextSearchInsertSpec_t *spec, mongocrypt_fle2_placeholder_type_t type, uint64_t contention_max, - text_search_expected_token_counts expected_tag_counts) { - bson_t iup_bson; + text_search_expected_token_counts *expected_tag_counts) { + bson_t payload_bson; bson_iter_t iter; - ASSERT(_mongocrypt_buffer_to_bson(&ciphertext->data, &iup_bson)); + ASSERT(_mongocrypt_buffer_to_bson(&ciphertext->data, &payload_bson)); mc_ServerDataEncryptionLevel1Token_t *sdel1Token = getSDEL1Token(crypt); const mongocrypt_binary_t *keyId = TEST_BIN(16); // don't free! @@ -1296,7 +1240,7 @@ static void validate_text_search_ciphertext(_mongocrypt_tester_t *tester, ASSERT_CMPUINT8(ciphertext->original_bson_type, ==, 0); // unset ASSERT_CMPUINT32(ciphertext->key_id.len, ==, 0); // unset - iupv2_fields_common res = validate_iupv2_common(&iup_bson); + iupv2_fields_common res = validate_iupv2_common(&payload_bson); // validate u, t, k have correct values ASSERT_CMPBYTES(keyId->data, keyId->len, res.u.data, res.u.len); @@ -1333,8 +1277,8 @@ static void validate_text_search_ciphertext(_mongocrypt_tester_t *tester, // BSON strings have 5 (4 for size + 1 null terminator) bytes of overhead ASSERT_CMPUINT32(pbytes, >=, 5); - ASSERT_CMPSIZE_T(strlen(text_value), ==, (pbytes - 5)); - ASSERT_STREQUAL(text_value, ((char *)(ptext.data + 4))); + ASSERT_CMPSIZE_T(spec->len, ==, (pbytes - 5)); + ASSERT_STREQUAL(spec->v, ((char *)(ptext.data + 4))); _mongocrypt_buffer_cleanup(&ptext); _mongocrypt_buffer_cleanup(&ctext); @@ -1344,7 +1288,7 @@ static void validate_text_search_ciphertext(_mongocrypt_tester_t *tester, } // assert b exists with correct fields - ASSERT(bson_iter_init_find(&iter, &iup_bson, "b")); + ASSERT(bson_iter_init_find(&iter, &payload_bson, "b")); ASSERT(BSON_ITER_HOLDS_DOCUMENT(&iter)); bson_t b_bson; @@ -1362,19 +1306,66 @@ static void validate_text_search_ciphertext(_mongocrypt_tester_t *tester, size_t tscount = 0; ASSERT(bson_iter_init_find(&b_iter, &b_bson, "s")); tscount = validate_text_search_token_set_array_common(&b_iter, crypt); - ASSERT_CMPSIZE_T(expected_tag_counts.substrings, ==, tscount); + ASSERT_CMPSIZE_T(expected_tag_counts->substrings, ==, tscount); ASSERT(bson_iter_init_find(&b_iter, &b_bson, "u")); tscount = validate_text_search_token_set_array_common(&b_iter, crypt); - ASSERT_CMPSIZE_T(expected_tag_counts.suffixes, ==, tscount); + ASSERT_CMPSIZE_T(expected_tag_counts->suffixes, ==, tscount); ASSERT(bson_iter_init_find(&b_iter, &b_bson, "p")); tscount = validate_text_search_token_set_array_common(&b_iter, crypt); - ASSERT_CMPSIZE_T(expected_tag_counts.prefixes, ==, tscount); + ASSERT_CMPSIZE_T(expected_tag_counts->prefixes, ==, tscount); + } else { + ASSERT_CMPUINT8(ciphertext->blob_subtype, ==, MC_SUBTYPE_FLE2FindTextPayload); + ASSERT_CMPUINT8(ciphertext->original_bson_type, ==, 0); // unset + ASSERT_CMPUINT32(ciphertext->key_id.len, ==, 0); // unset + mc_FLE2FindTextPayload_t parsed; + mongocrypt_status_t *status = mongocrypt_status_new(); + + ASSERT_OK_STATUS(mc_FLE2FindTextPayload_parse(&parsed, &payload_bson, status), status); + ASSERT_CMPUINT64(parsed.maxContentionFactor, ==, contention_max); + ASSERT(parsed.caseFold == spec->casef); + ASSERT(parsed.diacriticFold == spec->diacf); + + bool exact = !(spec->prefix.set || spec->suffix.set || spec->substr.set); + ASSERT(parsed.tokenSets.prefix.set == spec->prefix.set); + ASSERT(parsed.tokenSets.substring.set == spec->substr.set); + ASSERT(parsed.tokenSets.suffix.set == spec->suffix.set); + ASSERT(parsed.tokenSets.exact.set == exact); + ASSERT(parsed.prefixSpec.set == spec->prefix.set); + ASSERT(parsed.substringSpec.set == spec->substr.set); + ASSERT(parsed.suffixSpec.set == spec->suffix.set); + +#define CHECK_TOKENS(Type) \ + if (parsed.tokenSets.Type.set) { \ + ASSERT_CMPUINT32(parsed.tokenSets.Type.value.edcDerivedToken.len, ==, MONGOCRYPT_HMAC_SHA256_LEN); \ + ASSERT_CMPUINT32(parsed.tokenSets.Type.value.escDerivedToken.len, ==, MONGOCRYPT_HMAC_SHA256_LEN); \ + ASSERT_CMPUINT32(parsed.tokenSets.Type.value.serverDerivedFromDataToken.len, ==, MONGOCRYPT_HMAC_SHA256_LEN); \ + } + CHECK_TOKENS(prefix); + CHECK_TOKENS(suffix); + CHECK_TOKENS(substring); + CHECK_TOKENS(exact); +#undef CHECK_TOKENS + if (parsed.prefixSpec.set) { + ASSERT_CMPUINT32(parsed.prefixSpec.value.lb, ==, spec->prefix.value.lb); + ASSERT_CMPUINT32(parsed.prefixSpec.value.ub, ==, spec->prefix.value.ub); + } + if (parsed.suffixSpec.set) { + ASSERT_CMPUINT32(parsed.suffixSpec.value.lb, ==, spec->suffix.value.lb); + ASSERT_CMPUINT32(parsed.suffixSpec.value.ub, ==, spec->suffix.value.ub); + } + if (parsed.substringSpec.set) { + ASSERT_CMPUINT32(parsed.substringSpec.value.mlen, ==, spec->substr.value.mlen); + ASSERT_CMPUINT32(parsed.substringSpec.value.lb, ==, spec->substr.value.lb); + ASSERT_CMPUINT32(parsed.substringSpec.value.ub, ==, spec->substr.value.ub); + } + mongocrypt_status_destroy(status); + mc_FLE2FindTextPayload_cleanup(&parsed); } mc_ServerDataEncryptionLevel1Token_destroy(sdel1Token); - bson_destroy(&iup_bson); + bson_destroy(&payload_bson); } static size_t calculate_expected_substring_tag_count(size_t beta, size_t mlen, size_t ub, size_t lb) { @@ -1408,16 +1399,15 @@ static size_t calculate_expected_nfix_tag_count(size_t beta, size_t ub, size_t l } // Runs _mongocrypt_marking_to_ciphertext to compute the ciphertext for the given marking. -static bool test_text_search_insert_marking_to_ciphertext(_mongocrypt_tester_t *tester, - mongocrypt_t *crypt, - _mongocrypt_ciphertext_t *out, - const char *test_string, - int test_string_len, - int mlen, - mongocrypt_status_t *status) { - ASSERT_CMPINT(mlen, >, 0); - +static bool test_text_search_marking_to_ciphertext(_mongocrypt_tester_t *tester, + mongocrypt_t *crypt, + _mongocrypt_ciphertext_t *out, + mongocrypt_fle2_placeholder_type_t type, + int64_t contention_max, + mc_FLE2TextSearchInsertSpec_t *test_spec, + mongocrypt_status_t *status) { mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + // Set up encryption environment ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "test", -1, TEST_FILE("./test/example/cmd.json")), ctx); // Add a test key @@ -1430,20 +1420,36 @@ static bool test_text_search_insert_marking_to_ciphertext(_mongocrypt_tester_t * _mongocrypt_marking_t marking; bson_t *marking_bson = bson_new(); - BSON_APPEND_INT32(marking_bson, "t", 1); - BSON_APPEND_INT32(marking_bson, "a", 4); - BSON_APPEND_INT64(marking_bson, "cm", 2); + BSON_APPEND_INT32(marking_bson, "t", type); + BSON_APPEND_INT32(marking_bson, "a", MONGOCRYPT_FLE2_ALGORITHM_TEXT_SEARCH); + BSON_APPEND_INT64(marking_bson, "cm", contention_max); bson_t text_spec; BSON_APPEND_DOCUMENT_BEGIN(marking_bson, "v", &text_spec); - bson_append_utf8(&text_spec, "v", 1, test_string, test_string_len); - BSON_APPEND_BOOL(&text_spec, "casef", false); - BSON_APPEND_BOOL(&text_spec, "diacf", false); - bson_t subspec; - BSON_APPEND_DOCUMENT_BEGIN(&text_spec, "substr", &subspec); - BSON_APPEND_INT32(&subspec, "mlen", mlen); - BSON_APPEND_INT32(&subspec, "ub", 1); - BSON_APPEND_INT32(&subspec, "lb", 1); - ASSERT(bson_append_document_end(&text_spec, &subspec)); + bson_append_utf8(&text_spec, "v", 1, test_spec->v, test_spec->len); + BSON_APPEND_BOOL(&text_spec, "casef", test_spec->casef); + BSON_APPEND_BOOL(&text_spec, "diacf", test_spec->diacf); + if (test_spec->prefix.set) { + bson_t subspec; + BSON_APPEND_DOCUMENT_BEGIN(&text_spec, "prefix", &subspec); + BSON_APPEND_INT32(&subspec, "ub", test_spec->prefix.value.ub); + BSON_APPEND_INT32(&subspec, "lb", test_spec->prefix.value.lb); + ASSERT(bson_append_document_end(&text_spec, &subspec)); + } + if (test_spec->substr.set) { + bson_t subspec; + BSON_APPEND_DOCUMENT_BEGIN(&text_spec, "substr", &subspec); + BSON_APPEND_INT32(&subspec, "mlen", test_spec->substr.value.mlen); + BSON_APPEND_INT32(&subspec, "ub", test_spec->substr.value.ub); + BSON_APPEND_INT32(&subspec, "lb", test_spec->substr.value.lb); + ASSERT(bson_append_document_end(&text_spec, &subspec)); + } + if (test_spec->suffix.set) { + bson_t subspec; + BSON_APPEND_DOCUMENT_BEGIN(&text_spec, "suffix", &subspec); + BSON_APPEND_INT32(&subspec, "ub", test_spec->suffix.value.ub); + BSON_APPEND_INT32(&subspec, "lb", test_spec->suffix.value.lb); + ASSERT(bson_append_document_end(&text_spec, &subspec)); + } ASSERT(bson_append_document_end(marking_bson, &text_spec)); // Add key identifier info to the marking @@ -1471,99 +1477,104 @@ static void test_mc_marking_to_ciphertext_fle2_text_search(_mongocrypt_tester_t // Test substring { - const char *markingJSON = RAW_STRING({ - 't' : 1, - 'a' : 4, - 'v' : { - 'v' : "foobar", - 'casef' : false, - 'diacf' : false, - 'substr' : - {'mlen' : {'$numberInt' : '1000'}, 'ub' : {'$numberInt' : '100'}, 'lb' : {'$numberInt' : '10'}} - }, - 'cm' : {'$numberLong' : '2'} - }); _mongocrypt_ciphertext_t ciphertext; _mongocrypt_ciphertext_init(&ciphertext); mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foobar", + .len = 6, + .substr.set = true, + .substr.value = {.mlen = 1000, .ub = 100, .lb = 10}}; text_search_expected_token_counts counts = {0}; counts.substrings = calculate_expected_substring_tag_count(6, 1000, 100, 10); - get_ciphertext_from_marking_json(tester, crypt, markingJSON, &ciphertext); + ASSERT_OK_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, + 2, + &spec, + status), + status); validate_text_search_ciphertext(tester, &ciphertext, crypt, - "foobar", + &spec, MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, 2, - counts); + &counts); + mongocrypt_status_destroy(status); mongocrypt_destroy(crypt); _mongocrypt_ciphertext_cleanup(&ciphertext); } // Test suffix + prefix { - const char *markingJSON = RAW_STRING({ - 't' : 1, - 'a' : 4, - 'v' : { - 'v' : "foobar", - 'casef' : false, - 'diacf' : false, - 'suffix' : {'ub' : {'$numberInt' : '100'}, 'lb' : {'$numberInt' : '10'}}, - 'prefix' : {'ub' : {'$numberInt' : '100'}, 'lb' : {'$numberInt' : '10'}} - }, - 'cm' : {'$numberLong' : '2'} - }); _mongocrypt_ciphertext_t ciphertext; _mongocrypt_ciphertext_init(&ciphertext); mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foobar", + .len = 6, + .suffix.set = true, + .suffix.value = {.ub = 100, .lb = 10}, + .prefix.set = true, + .prefix.value = {.ub = 100, .lb = 10}}; text_search_expected_token_counts counts = {0}; counts.suffixes = counts.prefixes = calculate_expected_nfix_tag_count(6, 100, 10); - get_ciphertext_from_marking_json(tester, crypt, markingJSON, &ciphertext); + ASSERT_OK_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, + 2, + &spec, + status), + status); validate_text_search_ciphertext(tester, &ciphertext, crypt, - "foobar", + &spec, MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, 2, - counts); - + &counts); + mongocrypt_status_destroy(status); mongocrypt_destroy(crypt); _mongocrypt_ciphertext_cleanup(&ciphertext); } // Test empty string { - const char *markingJSON = RAW_STRING({ - 't' : 1, - 'a' : 4, - 'v' : { - 'v' : "", - 'casef' : false, - 'diacf' : false, - 'prefix' : {'ub' : {'$numberInt' : '100'}, 'lb' : {'$numberInt' : '10'}} - }, - 'cm' : {'$numberLong' : '2'} - }); _mongocrypt_ciphertext_t ciphertext; _mongocrypt_ciphertext_init(&ciphertext); mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "", + .len = 0, + .prefix.set = true, + .prefix.value = {.ub = 100, .lb = 10}}; text_search_expected_token_counts counts = {0}; // beta is 1 for empty strings counts.prefixes = calculate_expected_nfix_tag_count(1, 100, 10); - get_ciphertext_from_marking_json(tester, crypt, markingJSON, &ciphertext); + ASSERT_OK_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, + 2, + &spec, + status), + status); validate_text_search_ciphertext(tester, &ciphertext, crypt, - "", + &spec, MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, 2, - counts); + &counts); + mongocrypt_status_destroy(status); mongocrypt_destroy(crypt); _mongocrypt_ciphertext_cleanup(&ciphertext); } @@ -1571,33 +1582,37 @@ static void test_mc_marking_to_ciphertext_fle2_text_search(_mongocrypt_tester_t // Test string cbc-padded length is less than lb (ie. substring/suffix/prefix tag sets will be // empty) { - const char *markingJSON = RAW_STRING({ - 't' : 1, - 'a' : 4, - 'v' : { - 'v' : "foobar", - 'casef' : false, - 'diacf' : false, - 'substr' : - {'mlen' : {'$numberInt' : '1000'}, 'ub' : {'$numberInt' : '100'}, 'lb' : {'$numberInt' : '20'}}, - 'prefix' : {'ub' : {'$numberInt' : '100'}, 'lb' : {'$numberInt' : '20'}}, - 'suffix' : {'ub' : {'$numberInt' : '100'}, 'lb' : {'$numberInt' : '20'}} - }, - 'cm' : {'$numberLong' : '2'} - }); _mongocrypt_ciphertext_t ciphertext; _mongocrypt_ciphertext_init(&ciphertext); mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foobar", + .len = 6, + .substr.set = true, + .substr.value = {.mlen = 1000, .ub = 100, .lb = 20}, + .prefix.set = true, + .prefix.value = {.ub = 100, .lb = 20}, + .suffix.set = true, + .suffix.value = {.ub = 100, .lb = 20}}; text_search_expected_token_counts counts = {0}; - get_ciphertext_from_marking_json(tester, crypt, markingJSON, &ciphertext); + ASSERT_OK_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, + 2, + &spec, + status), + status); + validate_text_search_ciphertext(tester, &ciphertext, crypt, - "foobar", + &spec, MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, 2, - counts); + &counts); + mongocrypt_status_destroy(status); mongocrypt_destroy(crypt); _mongocrypt_ciphertext_cleanup(&ciphertext); } @@ -1608,11 +1623,19 @@ static void test_mc_marking_to_ciphertext_fle2_text_search(_mongocrypt_tester_t _mongocrypt_ciphertext_init(&ciphertext); mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); mongocrypt_status_t *status = mongocrypt_status_new(); - - ASSERT_FAILS_STATUS( - test_text_search_insert_marking_to_ciphertext(tester, crypt, &ciphertext, "foobar", 6, 3, status), - status, - "longer than the maximum length for substring indexing"); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foobar", + .len = 6, + .substr.set = true, + .substr.value = {.mlen = 3, .ub = 1, .lb = 1}}; + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, + 2, + &spec, + status), + status, + "longer than the maximum length for substring indexing"); mongocrypt_status_destroy(status); mongocrypt_destroy(crypt); @@ -1626,37 +1649,46 @@ static void test_mc_marking_to_ciphertext_fle2_text_search(_mongocrypt_tester_t mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); const char *expected_msg = "String passed in was not valid UTF-8"; mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foob\xffr", + .len = 6, + .substr.set = true, + .substr.value = {.mlen = INT32_MAX, .ub = 1, .lb = 1}}; // invalid utf-8 byte 0xff - ASSERT_FAILS_STATUS(test_text_search_insert_marking_to_ciphertext(tester, - crypt, - &ciphertext, - "foob\xffr", - 6, - INT32_MAX, - status), + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, + 2, + &spec, + status), status, expected_msg); _mongocrypt_status_reset(status); + // embedded null byte - ASSERT_FAILS_STATUS(test_text_search_insert_marking_to_ciphertext(tester, - crypt, - &ciphertext, - "foob\x00r", - 6, - INT32_MAX, - status), + spec.v = "foob\x00r"; + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, + 2, + &spec, + status), status, expected_msg); _mongocrypt_status_reset(status); + // overlong encoding of 'a' (\x61) - ASSERT_FAILS_STATUS(test_text_search_insert_marking_to_ciphertext(tester, - crypt, - &ciphertext, - "foob\xE0\x81\xA1r", - 8, - INT32_MAX, - status), + spec.v = "foob\xE0\x81\xA1r"; + spec.len = 8; + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, + 2, + &spec, + status), status, expected_msg); @@ -1665,26 +1697,30 @@ static void test_mc_marking_to_ciphertext_fle2_text_search(_mongocrypt_tester_t _mongocrypt_ciphertext_cleanup(&ciphertext); } - // test string is too large + // Test string is too large { _mongocrypt_ciphertext_t ciphertext; _mongocrypt_ciphertext_init(&ciphertext); mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); const char *expected_msg = "String passed in was too long"; mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.substr.set = true, + .substr.value = {.mlen = INT32_MAX, .ub = 1, .lb = 1}}; int len = (16 * 1024 * 1024) + 2; char *large_str = bson_malloc(len); memset(large_str, 'a', len); large_str[len - 1] = '\0'; - - ASSERT_FAILS_STATUS(test_text_search_insert_marking_to_ciphertext(tester, - crypt, - &ciphertext, - large_str, - len - 1, - INT32_MAX, - status), + spec.v = large_str; + spec.len = len - 1; + + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, + 2, + &spec, + status), status, expected_msg); bson_free(large_str); @@ -1692,20 +1728,284 @@ static void test_mc_marking_to_ciphertext_fle2_text_search(_mongocrypt_tester_t mongocrypt_destroy(crypt); _mongocrypt_ciphertext_cleanup(&ciphertext); } + + // Test insert placeholder missing substring/suffix/prefix spec + { + _mongocrypt_ciphertext_t ciphertext; + _mongocrypt_ciphertext_init(&ciphertext); + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + const char *expected_msg = "missing a substring, suffix, or prefix index specification"; + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foo", .len = 3}; + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_INSERT, + 2, + &spec, + status), + status, + expected_msg); + mongocrypt_status_destroy(status); + mongocrypt_destroy(crypt); + _mongocrypt_ciphertext_cleanup(&ciphertext); + } + + // Test find placeholder has multiple query specs + { + _mongocrypt_ciphertext_t ciphertext; + _mongocrypt_ciphertext_init(&ciphertext); + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + const char *expected_msg = "cannot contain multiple query type specifications"; + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foo", + .len = 3, + .substr.set = true, + .substr.value = {.mlen = 3, .ub = 1, .lb = 1}, + .prefix.set = true, + .prefix.value = {.ub = 1, .lb = 1}}; + + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 2, + &spec, + status), + status, + expected_msg); + mongocrypt_status_destroy(status); + mongocrypt_destroy(crypt); + _mongocrypt_ciphertext_cleanup(&ciphertext); + } + + // Test find placeholder has invalid UTF-8 string + { + _mongocrypt_ciphertext_t ciphertext; + _mongocrypt_ciphertext_init(&ciphertext); + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + const char *expected_msg = "String passed in was not valid UTF-8"; + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foob\xffr", + .len = 6, + .substr.set = true, + .substr.value = {.mlen = 50, .ub = 30, .lb = 1}}; + + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 2, + &spec, + status), + status, + expected_msg); + mongocrypt_status_destroy(status); + mongocrypt_destroy(crypt); + _mongocrypt_ciphertext_cleanup(&ciphertext); + } + + // Test exact match find + { + _mongocrypt_ciphertext_t ciphertext; + _mongocrypt_ciphertext_init(&ciphertext); + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foo", .len = 3, .diacf = true, .casef = true}; + ASSERT_OK_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 7, + &spec, + status), + status); + validate_text_search_ciphertext(tester, + &ciphertext, + crypt, + &spec, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 7, + NULL); + _mongocrypt_ciphertext_cleanup(&ciphertext); + _mongocrypt_ciphertext_init(&ciphertext); + + // Test empty string case + spec.v = ""; + spec.len = 0; + ASSERT_OK_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 7, + &spec, + status), + status); + validate_text_search_ciphertext(tester, + &ciphertext, + crypt, + &spec, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 7, + NULL); + + mongocrypt_status_destroy(status); + mongocrypt_destroy(crypt); + _mongocrypt_ciphertext_cleanup(&ciphertext); + } + + // Test substring find + { + _mongocrypt_ciphertext_t ciphertext; + _mongocrypt_ciphertext_init(&ciphertext); + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foo", + .len = 3, + .diacf = true, + .substr.set = true, + .substr.value = {.mlen = 300, .ub = 200, .lb = 2}}; + ASSERT_OK_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 8, + &spec, + status), + status); + validate_text_search_ciphertext(tester, + &ciphertext, + crypt, + &spec, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 8, + NULL); + _mongocrypt_ciphertext_cleanup(&ciphertext); + _mongocrypt_ciphertext_init(&ciphertext); + + // Test empty string case + spec.v = ""; + spec.len = 0; + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 8, + &spec, + status), + status, + "string value cannot be empty"); + mongocrypt_status_destroy(status); + _mongocrypt_ciphertext_cleanup(&ciphertext); + mongocrypt_destroy(crypt); + } + + // Test suffix find + { + _mongocrypt_ciphertext_t ciphertext; + _mongocrypt_ciphertext_init(&ciphertext); + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foo", + .len = 3, + .casef = true, + .suffix.set = true, + .suffix.value = {.ub = 100, .lb = 1}}; + ASSERT_OK_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 9, + &spec, + status), + status); + validate_text_search_ciphertext(tester, + &ciphertext, + crypt, + &spec, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 9, + NULL); + _mongocrypt_ciphertext_cleanup(&ciphertext); + _mongocrypt_ciphertext_init(&ciphertext); + + // Test empty string case + spec.v = ""; + spec.len = 0; + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 8, + &spec, + status), + status, + "string value cannot be empty"); + mongocrypt_status_destroy(status); + _mongocrypt_ciphertext_cleanup(&ciphertext); + mongocrypt_destroy(crypt); + } + + // Test prefix find + { + _mongocrypt_ciphertext_t ciphertext; + _mongocrypt_ciphertext_init(&ciphertext); + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_status_t *status = mongocrypt_status_new(); + mc_FLE2TextSearchInsertSpec_t spec = {.v = "foo", + .len = 3, + .prefix.set = true, + .prefix.value = {.ub = 300, .lb = 3}}; + ASSERT_OK_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 10, + &spec, + status), + status); + validate_text_search_ciphertext(tester, + &ciphertext, + crypt, + &spec, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 10, + NULL); + _mongocrypt_ciphertext_cleanup(&ciphertext); + _mongocrypt_ciphertext_init(&ciphertext); + + // Test empty string case + spec.v = ""; + spec.len = 0; + ASSERT_FAILS_STATUS(test_text_search_marking_to_ciphertext(tester, + crypt, + &ciphertext, + MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND, + 8, + &spec, + status), + status, + "string value cannot be empty"); + mongocrypt_status_destroy(status); + _mongocrypt_ciphertext_cleanup(&ciphertext); + mongocrypt_destroy(crypt); + } } static void test_ciphertext_len_steps_fle2_text_search(_mongocrypt_tester_t *tester) { - const char *markingJSONFormat = RAW_STRING({ - 't' : 1, - 'a' : 4, - 'v' : { - 'v' : "%s", - 'casef' : false, - 'diacf' : false, - 'suffix' : {'ub' : {'$numberInt' : '2'}, 'lb' : {'$numberInt' : '1'}} - }, - 'cm' : {'$numberLong' : '2'} - }); +#define MARKING_JSON_FORMAT \ + RAW_STRING({ \ + 't' : 1, \ + 'a' : 4, \ + 'v' : { \ + 'v' : "%s", \ + 'casef' : false, \ + 'diacf' : false, \ + 'suffix' : {'ub' : {'$numberInt' : '2'}, 'lb' : {'$numberInt' : '1'}} \ + }, \ + 'cm' : {'$numberLong' : '2'} \ + }) + size_t last_len = 0; mongocrypt_binary_t *cmd = TEST_FILE("./test/example/cmd.json"); mongocrypt_binary_t *key_file = TEST_BIN(16); @@ -1715,10 +2015,10 @@ static void test_ciphertext_len_steps_fle2_text_search(_mongocrypt_tester_t *tes for (size_t str_len = 0; str_len < 256; str_len++) { char *v = bson_malloc0(str_len + 1); memset(v, 'a', str_len); - size_t bufsize = snprintf(NULL, 0, markingJSONFormat, v) + 1; + size_t bufsize = snprintf(NULL, 0, MARKING_JSON_FORMAT, v) + 1; char *markingJSON = bson_malloc(bufsize); - sprintf(markingJSON, markingJSONFormat, v); - bson_t *marking_bson = TMP_BSON(markingJSON); + sprintf(markingJSON, MARKING_JSON_FORMAT, v); + bson_t *marking_bson = TMP_BSON_STR(markingJSON); _mongocrypt_ciphertext_t ciphertext; _mongocrypt_ciphertext_init(&ciphertext); @@ -1750,6 +2050,8 @@ static void test_ciphertext_len_steps_fle2_text_search(_mongocrypt_tester_t *tes bson_destroy(marking_bson); tester->bson_count--; } + +#undef MARKING_JSON_FORMAT } void _mongocrypt_tester_install_marking(_mongocrypt_tester_t *tester) { diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-status.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-status.c index 548a975..673e929 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-status.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-status.c @@ -73,4 +73,4 @@ static void _test_status_len(_mongocrypt_tester_t *tester) { void _mongocrypt_tester_install_status(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_status_len); -} \ No newline at end of file +} diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.c b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.c index 53b45d1..9726f84 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.c @@ -81,10 +81,13 @@ void _usleep(int64_t usec) { } #define TEST_DATA_COUNT_INC(var) \ - (var)++; \ - if ((var) >= TEST_DATA_COUNT) { \ - TEST_ERROR("TEST_DATA_COUNT exceeded for %s. Increment TEST_DATA_COUNT.", #var); \ - } + if (1) { \ + (var)++; \ + if ((var) >= TEST_DATA_COUNT) { \ + TEST_ERROR("TEST_DATA_COUNT exceeded for %s. Increment TEST_DATA_COUNT.", #var); \ + } \ + } else \ + ((void)0) static void _load_json(_mongocrypt_tester_t *tester, const char *path) { bson_t as_bson; @@ -206,26 +209,20 @@ bson_t *_mongocrypt_tester_file_as_bson(_mongocrypt_tester_t *tester, const char return bson; } -bson_t *_mongocrypt_tester_bson_from_json(_mongocrypt_tester_t *tester, const char *json, ...) { - va_list ap; - char *full_json; - bson_t *bson; - bson_error_t error; - char *c; +bson_t *_mongocrypt_tester_bson_from_str(_mongocrypt_tester_t *tester, const char *json) { + char *const full_json = bson_strdup(json); - va_start(ap, json); - full_json = bson_strdupv_printf(json, ap); /* Replace ' with " */ - for (c = full_json; *c; c++) { + for (char *c = full_json; *c; c++) { if (*c == '\'') { *c = '"'; } } - va_end(ap); - bson = &tester->test_bson[tester->bson_count]; + bson_error_t error; + bson_t *const bson = &tester->test_bson[tester->bson_count]; TEST_DATA_COUNT_INC(tester->bson_count); - if (!bson_init_from_json(bson, full_json, strlen(full_json), &error)) { + if (!bson_init_from_json(bson, full_json, -1, &error)) { TEST_STDERR_PRINTF("%s", error.message); abort(); } @@ -233,6 +230,17 @@ bson_t *_mongocrypt_tester_bson_from_json(_mongocrypt_tester_t *tester, const ch return bson; } +bson_t *_mongocrypt_tester_bson_from_json(_mongocrypt_tester_t *tester, const char *json, ...) { + va_list ap; + va_start(ap, json); + char *const full_json = bson_strdupv_printf(json, ap); + va_end(ap); + + bson_t *const bson = _mongocrypt_tester_bson_from_str(tester, full_json); + bson_free(full_json); + return bson; +} + bson_t *tmp_bsonf(_mongocrypt_tester_t *tester, const char *fmt, ...) { va_list arg; va_start(arg, fmt); @@ -283,41 +291,30 @@ bson_t *tmp_bsonf(_mongocrypt_tester_t *tester, const char *fmt, ...) { #undef ENSURE_CAPACITY dst[dst_len] = '\0'; - bson_t *tmp = TMP_BSON(dst); + bson_t *tmp = TMP_BSON_STR(dst); va_end(arg); bson_free(dst); return tmp; } -mongocrypt_binary_t *_mongocrypt_tester_bin_from_json(_mongocrypt_tester_t *tester, const char *json, ...) { - va_list ap; - char *full_json; - bson_t *bson; - mongocrypt_binary_t *bin; - bson_error_t error; - char *c; - - va_start(ap, json); - full_json = bson_strdupv_printf(json, ap); - /* Replace ' with " */ - for (c = full_json; *c; c++) { - if (*c == '\'') { - *c = '"'; - } - } - - va_end(ap); - bson = &tester->test_bson[tester->bson_count]; - TEST_DATA_COUNT_INC(tester->bson_count); - if (!bson_init_from_json(bson, full_json, strlen(full_json), &error)) { - TEST_STDERR_PRINTF("failed to parse JSON %s: %s", error.message, json); - abort(); - } - bin = mongocrypt_binary_new(); +mongocrypt_binary_t *_mongocrypt_tester_bin_from_str(_mongocrypt_tester_t *tester, const char *json) { + mongocrypt_binary_t *const bin = mongocrypt_binary_new(); tester->test_bin[tester->bin_count] = bin; TEST_DATA_COUNT_INC(tester->bin_count); + + bson_t *const bson = _mongocrypt_tester_bson_from_str(tester, json); bin->data = (uint8_t *)bson_get_data(bson); bin->len = bson->len; + return bin; +} + +mongocrypt_binary_t *_mongocrypt_tester_bin_from_json(_mongocrypt_tester_t *tester, const char *json, ...) { + va_list ap; + va_start(ap, json); + char *const full_json = bson_strdupv_printf(json, ap); + va_end(ap); + + mongocrypt_binary_t *const bin = _mongocrypt_tester_bin_from_str(tester, full_json); bson_free(full_json); return bin; } @@ -459,8 +456,8 @@ const char *_mongocrypt_tester_plaintext(_mongocrypt_tester_t *tester) { status = mongocrypt_status_new(); ASSERT_OR_PRINT(_mongocrypt_marking_parse_unowned(&buf, &marking, status), status); mongocrypt_status_destroy(status); - BSON_ASSERT(BSON_ITER_HOLDS_UTF8(&marking.v_iter)); - return bson_iter_utf8(&marking.v_iter, NULL); + BSON_ASSERT(BSON_ITER_HOLDS_UTF8(&marking.u.fle1.v_iter)); + return bson_iter_utf8(&marking.u.fle1.v_iter, NULL); } mongocrypt_binary_t *_mongocrypt_tester_encrypted_doc(_mongocrypt_tester_t *tester) { @@ -575,11 +572,6 @@ mongocrypt_t *_mongocrypt_tester_mongocrypt(tester_mongocrypt_flags flags) { if (flags & TESTER_MONGOCRYPT_WITH_CRYPT_SHARED_LIB) { mongocrypt_setopt_append_crypt_shared_lib_search_path(crypt, "$ORIGIN"); } - if (flags & TESTER_MONGOCRYPT_WITH_RANGE_V2) { - ASSERT(mongocrypt_setopt_use_range_v2(crypt)); - } else { - crypt->opts.use_range_v2 = false; - } if (flags & TESTER_MONGOCRYPT_WITH_SHORT_CACHE) { ASSERT(mongocrypt_setopt_key_expiration(crypt, 1)); } @@ -599,10 +591,6 @@ mongocrypt_t *_mongocrypt_tester_mongocrypt(tester_mongocrypt_flags flags) { bool _mongocrypt_init_for_test(mongocrypt_t *crypt) { BSON_ASSERT_PARAM(crypt); - // Even if the ENABLE_USE_RANGE_V2 compile flag is on, we should have range V2 off by default for testing, as many - // existing tests are based around range V2 being disabled. To use range V2, use the TESTER_MONGOCRYPT_WITH_RANGE_V2 - // flag with the above function. - crypt->opts.use_range_v2 = false; return mongocrypt_init(crypt); } @@ -876,14 +864,14 @@ static void _test_setopt_kms_providers(_mongocrypt_tester_t *tester) { mongocrypt_setopt_use_need_kms_credentials_state(crypt); } if (!test->errmsg) { - ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, TEST_BSON(test->value)), crypt); + ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, TEST_BSON_STR(test->value)), crypt); if (!test->errmsg_init) { ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt); } else { ASSERT_FAILS(_mongocrypt_init_for_test(crypt), crypt, test->errmsg_init); } } else { - ASSERT_FAILS(mongocrypt_setopt_kms_providers(crypt, TEST_BSON(test->value)), crypt, test->errmsg); + ASSERT_FAILS(mongocrypt_setopt_kms_providers(crypt, TEST_BSON_STR(test->value)), crypt, test->errmsg); } mongocrypt_destroy(crypt); } @@ -930,7 +918,7 @@ static void test_tmp_bsonf(_mongocrypt_tester_t *tester) { bool _aes_ctr_is_supported_by_os = true; int main(int argc, char **argv) { - _mongocrypt_tester_t tester = {0}; + static _mongocrypt_tester_t tester = {0}; int i; TEST_PRINTF("Pass a list of patterns to run a subset of tests.\n"); @@ -989,6 +977,7 @@ int main(int argc, char **argv) { _mongocrypt_tester_install_fle2_payload_iup_v2(&tester); _mongocrypt_tester_install_fle2_payload_find_equality_v2(&tester); _mongocrypt_tester_install_fle2_payload_find_range_v2(&tester); + _mongocrypt_tester_install_fle2_payload_find_text(&tester); _mongocrypt_tester_install_fle2_tag_and_encrypted_metadata_block(&tester); _mongocrypt_tester_install_range_encoding(&tester); _mongocrypt_tester_install_range_edge_generation(&tester); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.h b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.h index c22637d..06a4d0d 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.h +++ b/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.h @@ -40,8 +40,6 @@ typedef enum tester_mongocrypt_flags { /// crypt_shared library must be present in the same directory as the test /// executable. TESTER_MONGOCRYPT_WITH_CRYPT_SHARED_LIB = 1 << 0, - /// Enable range V2 - TESTER_MONGOCRYPT_WITH_RANGE_V2 = 1 << 2, /// Short cache expiration TESTER_MONGOCRYPT_WITH_SHORT_CACHE = 1 << 3, /// Do not call `mongocrypt_init` yet to allow for further configuration of the resulting `mongocrypt_t`. @@ -49,7 +47,6 @@ typedef enum tester_mongocrypt_flags { } tester_mongocrypt_flags; /* Arbitrary max of 2148 instances of temporary test data. Increase as needed. - * TODO(MONGOCRYPT-775) increasing further (e.g. 3000+) causes a segfault on Windows test runs. Revise. */ #define TEST_DATA_COUNT 2148 @@ -195,6 +192,8 @@ void _mongocrypt_tester_install_fle2_payload_find_equality_v2(_mongocrypt_tester void _mongocrypt_tester_install_fle2_payload_find_range_v2(_mongocrypt_tester_t *tester); +void _mongocrypt_tester_install_fle2_payload_find_text(_mongocrypt_tester_t *tester); + void _mongocrypt_tester_install_fle2_tag_and_encrypted_metadata_block(_mongocrypt_tester_t *tester); void _mongocrypt_tester_install_gcp_auth(_mongocrypt_tester_t *tester); @@ -228,6 +227,11 @@ void _mongocrypt_tester_install_mc_schema_broker(_mongocrypt_tester_t *tester); /* Conveniences for getting test data. */ /* Get a temporary bson_t from a JSON string. Do not free it. */ +bson_t *_mongocrypt_tester_bson_from_str(_mongocrypt_tester_t *tester, const char *json); +#define TMP_BSON_STR(...) _mongocrypt_tester_bson_from_str(tester, __VA_ARGS__) + +/* Get a temporary bson_t from a formattable JSON string. Do not free it. */ +MLIB_ANNOTATE_PRINTF(2, 3) bson_t *_mongocrypt_tester_bson_from_json(_mongocrypt_tester_t *tester, const char *json, ...); #define TMP_BSON(...) _mongocrypt_tester_bson_from_json(tester, __VA_ARGS__) @@ -246,6 +250,11 @@ bson_t *_mongocrypt_tester_file_as_bson(_mongocrypt_tester_t *tester, const char #define TEST_FILE_AS_BSON(path) _mongocrypt_tester_file_as_bson(tester, path) /* Get a temporary binary from a JSON string. Do not free it. */ +mongocrypt_binary_t *_mongocrypt_tester_bin_from_str(_mongocrypt_tester_t *tester, const char *json); +#define TEST_BSON_STR(...) _mongocrypt_tester_bin_from_str(tester, __VA_ARGS__) + +/* Get a temporary binary from a formattable JSON string. Do not free it. */ +MLIB_ANNOTATE_PRINTF(2, 3) mongocrypt_binary_t *_mongocrypt_tester_bin_from_json(_mongocrypt_tester_t *tester, const char *json, ...); #define TEST_BSON(...) _mongocrypt_tester_bin_from_json(tester, __VA_ARGS__) diff --git a/ext/libmongocrypt/libmongocrypt/test/test-named-kms-providers.c b/ext/libmongocrypt/libmongocrypt/test/test-named-kms-providers.c index ea5727a..8a2742b 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-named-kms-providers.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-named-kms-providers.c @@ -387,7 +387,7 @@ static void test_create_datakey_with_named_kms_provider(_mongocrypt_tester_t *te { mongocrypt_t *crypt = mongocrypt_new(); mongocrypt_binary_t *kms_providers = - TEST_BSON(BSON_STR({"local" : {}, "local:name1" : {"key" : "%s"}}), LOCAL_KEK1_BASE64, LOCAL_KEK2_BASE64); + TEST_BSON(BSON_STR({"local" : {}, "local:name1" : {"key" : "%s"}}), LOCAL_KEK1_BASE64); ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt); mongocrypt_setopt_use_need_kms_credentials_state(crypt); ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt); @@ -425,7 +425,7 @@ static void test_create_datakey_with_named_kms_provider(_mongocrypt_tester_t *te bson_t out_bson; ASSERT(_mongocrypt_binary_to_bson(out, &out_bson)); char *pattern = BSON_STR({"masterKey" : {"provider" : "local:name1"}}); - _assert_match_bson(&out_bson, TMP_BSON(pattern)); + _assert_match_bson(&out_bson, TMP_BSON_STR(pattern)); bson_destroy(&out_bson); mongocrypt_binary_destroy(out); mongocrypt_ctx_destroy(ctx); @@ -491,7 +491,7 @@ static void test_create_datakey_with_named_kms_provider(_mongocrypt_tester_t *te bson_t out_bson; ASSERT(_mongocrypt_binary_to_bson(out, &out_bson)); char *pattern = BSON_STR({"masterKey" : {"provider" : "azure:name1"}}); - _assert_match_bson(&out_bson, TMP_BSON(pattern)); + _assert_match_bson(&out_bson, TMP_BSON_STR(pattern)); bson_destroy(&out_bson); mongocrypt_binary_destroy(out); mongocrypt_ctx_destroy(ctx); @@ -536,7 +536,7 @@ static void test_create_datakey_with_named_kms_provider(_mongocrypt_tester_t *te bson_t out_bson; ASSERT(_mongocrypt_binary_to_bson(out, &out_bson)); char *pattern = BSON_STR({"masterKey" : {"provider" : "azure:name1"}}); - _assert_match_bson(&out_bson, TMP_BSON(pattern)); + _assert_match_bson(&out_bson, TMP_BSON_STR(pattern)); bson_destroy(&out_bson); mongocrypt_binary_destroy(out); mongocrypt_ctx_destroy(ctx); @@ -611,7 +611,7 @@ static void test_create_datakey_with_named_kms_provider(_mongocrypt_tester_t *te bson_t out_bson; ASSERT(_mongocrypt_binary_to_bson(out, &out_bson)); char *pattern = BSON_STR({"masterKey" : {"provider" : "azure:name1"}}); - _assert_match_bson(&out_bson, TMP_BSON(pattern)); + _assert_match_bson(&out_bson, TMP_BSON_STR(pattern)); bson_destroy(&out_bson); mongocrypt_binary_destroy(out); mongocrypt_ctx_destroy(ctx); @@ -664,7 +664,7 @@ static void test_create_datakey_with_named_kms_provider(_mongocrypt_tester_t *te bson_t out_bson; ASSERT(_mongocrypt_binary_to_bson(out, &out_bson)); char *pattern = BSON_STR({"masterKey" : {"provider" : "azure:name2"}}); - _assert_match_bson(&out_bson, TMP_BSON(pattern)); + _assert_match_bson(&out_bson, TMP_BSON_STR(pattern)); bson_destroy(&out_bson); mongocrypt_binary_destroy(out); mongocrypt_ctx_destroy(ctx); @@ -717,7 +717,7 @@ static void test_create_datakey_with_named_kms_provider(_mongocrypt_tester_t *te bson_t out_bson; ASSERT(_mongocrypt_binary_to_bson(out, &out_bson)); char *pattern = BSON_STR({"masterKey" : {"provider" : "kmip:name1"}}); - _assert_match_bson(&out_bson, TMP_BSON(pattern)); + _assert_match_bson(&out_bson, TMP_BSON_STR(pattern)); bson_destroy(&out_bson); mongocrypt_binary_destroy(out); mongocrypt_ctx_destroy(ctx); @@ -810,7 +810,7 @@ static void test_create_datakey_with_named_kms_provider(_mongocrypt_tester_t *te bson_t out_bson; ASSERT(_mongocrypt_binary_to_bson(out, &out_bson)); char *pattern = BSON_STR({"masterKey" : {"provider" : "kmip:name1"}}); - _assert_match_bson(&out_bson, TMP_BSON(pattern)); + _assert_match_bson(&out_bson, TMP_BSON_STR(pattern)); bson_destroy(&out_bson); mongocrypt_binary_destroy(out); mongocrypt_ctx_destroy(ctx); @@ -2119,7 +2119,7 @@ static void test_rewrap_with_named_kms_provider_local2local(_mongocrypt_tester_t bson_t bin_bson; ASSERT(_mongocrypt_binary_to_bson(bin, &bin_bson)); char *pattern = BSON_STR({"v" : [ {"masterKey" : {"provider" : "local:name2"}} ]}); - _assert_match_bson(&bin_bson, TMP_BSON(pattern)); + _assert_match_bson(&bin_bson, TMP_BSON_STR(pattern)); } mongocrypt_binary_destroy(bin); mongocrypt_ctx_destroy(ctx); @@ -2242,7 +2242,7 @@ static void test_rewrap_with_named_kms_provider_azure2azure(_mongocrypt_tester_t bson_t bin_bson; ASSERT(_mongocrypt_binary_to_bson(bin, &bin_bson)); char *pattern = BSON_STR({"v" : [ {"masterKey" : {"provider" : "azure:name2"}} ]}); - _assert_match_bson(&bin_bson, TMP_BSON(pattern)); + _assert_match_bson(&bin_bson, TMP_BSON_STR(pattern)); } mongocrypt_binary_destroy(bin); mongocrypt_ctx_destroy(ctx); @@ -2330,7 +2330,7 @@ static void test_rewrap_with_named_kms_provider_azure2local(_mongocrypt_tester_t bson_t bin_bson; ASSERT(_mongocrypt_binary_to_bson(bin, &bin_bson)); char *pattern = BSON_STR({"v" : [ {"masterKey" : {"provider" : "local:name1"}} ]}); - _assert_match_bson(&bin_bson, TMP_BSON(pattern)); + _assert_match_bson(&bin_bson, TMP_BSON_STR(pattern)); } mongocrypt_binary_destroy(bin); mongocrypt_ctx_destroy(ctx); diff --git a/ext/libmongocrypt/libmongocrypt/test/test-unicode-fold.c b/ext/libmongocrypt/libmongocrypt/test/test-unicode-fold.c index d0f78d1..4f137b1 100644 --- a/ext/libmongocrypt/libmongocrypt/test/test-unicode-fold.c +++ b/ext/libmongocrypt/libmongocrypt/test/test-unicode-fold.c @@ -49,7 +49,7 @@ _both_len, \ input, \ _input_len, \ - kUnicodeFoldToLower | kUnicodeFoldRemoveDiacritics); \ + (unicode_fold_options_t)(kUnicodeFoldToLower | kUnicodeFoldRemoveDiacritics)); \ } while (0) static void test_unicode_fold(_mongocrypt_tester_t *tester) { @@ -85,7 +85,11 @@ static void test_unicode_fold(_mongocrypt_tester_t *tester) { TEST_UNICODE_FOLD_ALL_CASES("Cafe\xcc\x81", "cafe\xcc\x81", "Cafe", "cafe"); TEST_UNICODE_FOLD_ALL_CASES("CafE\xcc\x81", "cafe\xcc\x81", "CafE", "cafe"); // Test string with null bytes - TEST_UNICODE_FOLD("fo\0bar", 6, "fo\0bar", 6, kUnicodeFoldToLower | kUnicodeFoldRemoveDiacritics); + TEST_UNICODE_FOLD("fo\0bar", + 6, + "fo\0bar", + 6, + (unicode_fold_options_t)(kUnicodeFoldToLower | kUnicodeFoldRemoveDiacritics)); // Test strings with folded representations longer in bytes than the input TEST_UNICODE_FOLD("\xe2\xb1\xa6", 3, "\xc8\xbe", 2, kUnicodeFoldToLower); TEST_UNICODE_FOLD("\xf0\xa4\x8b\xae", 4, "\xef\xa9\xac", 3, kUnicodeFoldRemoveDiacritics); diff --git a/ext/libmongocrypt/libmongocrypt/test/util/HELP.autogen b/ext/libmongocrypt/libmongocrypt/test/util/HELP.autogen index 1c1ade9..3282332 100644 --- a/ext/libmongocrypt/libmongocrypt/test/util/HELP.autogen +++ b/ext/libmongocrypt/libmongocrypt/test/util/HELP.autogen @@ -101,4 +101,4 @@ "csfle auto_decrypt --document '{ 'insert' : 'coll', 'documents' : [ { 'ssn' : { '$binary' : { 'base64': 'ARG+PK8ud0RZlDIzKwQmFoMCOuSIPyrfYleSqMZRXgaPCQOAurv0LTLNL6Tn/G7TuVOyf/Qv3j6VxSxCQEeu/yO7vv/UDE5niDE0itjOqjmf5Q==', 'subType' : '06' } } } ] }'\n" "\n" "csfle explicit_encrypt --key_id 'Eb48ry53RFmUMjMrBCYWgw==' --value '{'v': 'test'}' --algorithm 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'\n" -"```\n" \ No newline at end of file +"```\n" diff --git a/ext/libmongocrypt/libmongocrypt/test/util/csfle.c b/ext/libmongocrypt/libmongocrypt/test/util/csfle.c index bf12c89..08fd522 100644 --- a/ext/libmongocrypt/libmongocrypt/test/util/csfle.c +++ b/ext/libmongocrypt/libmongocrypt/test/util/csfle.c @@ -23,7 +23,7 @@ #include "util.h" -const char *help_text = "" +static const char *help_text = "" #include "HELP.autogen" ; diff --git a/ext/libmongocrypt/libmongocrypt/test/util/util.c b/ext/libmongocrypt/libmongocrypt/test/util/util.c index ac18ce0..e94df32 100644 --- a/ext/libmongocrypt/libmongocrypt/test/util/util.c +++ b/ext/libmongocrypt/libmongocrypt/test/util/util.c @@ -50,7 +50,7 @@ void _errexit_ctx(mongocrypt_ctx_t *ctx, int line) { } void _errexit_bson(bson_error_t *error, int line) { - MONGOC_ERROR("Error at line %d with code %d and msg: %s", line, error->code, error->message); + MONGOC_ERROR("Error at line %d with code %" PRIu32 " and msg: %s", line, error->code, error->message); exit(1); } @@ -111,7 +111,7 @@ static void _status_to_error(mongocrypt_status_t *status, bson_error_t *error) { * Returns true if ok, and does not modify @error. * Returns false if error, and sets @error. */ -bool _test_ctx_check_error(mongocrypt_ctx_t *ctx, bson_error_t *error, bool error_expected) { +static bool _test_ctx_check_error(mongocrypt_ctx_t *ctx, bson_error_t *error, bool error_expected) { mongocrypt_status_t *status; status = mongocrypt_status_new(); @@ -131,7 +131,7 @@ bool _test_ctx_check_error(mongocrypt_ctx_t *ctx, bson_error_t *error, bool erro return true; } -bool _test_kms_ctx_check_error(mongocrypt_kms_ctx_t *kms_ctx, bson_error_t *error, bool error_expected) { +static bool _test_kms_ctx_check_error(mongocrypt_kms_ctx_t *kms_ctx, bson_error_t *error, bool error_expected) { mongocrypt_status_t *status; status = mongocrypt_status_new(); @@ -659,7 +659,7 @@ static bool _state_ready(_state_machine_t *state_machine, bson_t *result, bson_e return ret; } -const char *_state_string(mongocrypt_ctx_state_t state) { +static const char *_state_string(mongocrypt_ctx_state_t state) { switch (state) { case MONGOCRYPT_CTX_ERROR: return "MONGOCRYPT_CTX_ERROR"; case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO_WITH_DB: return "MONGOCRYPT_CTX_NEED_MONGO_COLLINFO_WITH_DB"; @@ -732,7 +732,7 @@ bool _csfle_state_machine_run(_state_machine_t *state_machine, bson_t *result, b goto fail; } break; - case MONGOCRYPT_CTX_DONE: goto success; break; + case MONGOCRYPT_CTX_DONE: goto success; } } diff --git a/ext/libmongocrypt/libmongocrypt/test/util/util.h b/ext/libmongocrypt/libmongocrypt/test/util/util.h index 82e091a..ebb660d 100644 --- a/ext/libmongocrypt/libmongocrypt/test/util/util.h +++ b/ext/libmongocrypt/libmongocrypt/test/util/util.h @@ -20,19 +20,20 @@ #include void _errexit_mongocrypt(mongocrypt_t *crypt, int line); -#define ERREXIT_MONGOCRYPT(crypt) _errexit_mongocrypt(crypt, __LINE__); +#define ERREXIT_MONGOCRYPT(crypt) _errexit_mongocrypt(crypt, __LINE__) void _errexit_ctx(mongocrypt_ctx_t *ctx, int line); -#define ERREXIT_CTX(ctx) _errexit_ctx(ctx, __LINE__); +#define ERREXIT_CTX(ctx) _errexit_ctx(ctx, __LINE__) void _errexit_bson(bson_error_t *error, int line); -#define ERREXIT_BSON(err) _errexit_bson(err, __LINE__); +#define ERREXIT_BSON(err) _errexit_bson(err, __LINE__) #define ERREXIT(...) \ - do { \ + if (1) { \ MONGOC_ERROR(__VA_ARGS__); \ abort(); \ - } while (0) + } else \ + ((void)0) void _log_to_stdout(mongocrypt_log_level_t level, const char *message, uint32_t message_len, void *ctx); @@ -71,4 +72,4 @@ bson_t *bson_get_json(bson_t *bson, const char *key); bson_t *bson_req_json(bson_t *bson, const char *key); -bool bson_get_bool(bson_t *bson, const char *key, bool default_value); \ No newline at end of file +bool bson_get_bool(bson_t *bson, const char *key, bool default_value); diff --git a/lib/libmongocrypt_helper/version.rb b/lib/libmongocrypt_helper/version.rb index 2d099f8..6d208bb 100644 --- a/lib/libmongocrypt_helper/version.rb +++ b/lib/libmongocrypt_helper/version.rb @@ -1,5 +1,5 @@ module LibmongocryptHelper - VERSION = '1.13.2.0.1001' + VERSION = '1.14.0.0.1001' - LIBMONGOCRYPT_VERSION = '1.13.2' + LIBMONGOCRYPT_VERSION = '1.14.0' end diff --git a/sbom.json b/sbom.json index 5f88fd4..1e49856 100644 --- a/sbom.json +++ b/sbom.json @@ -1,31 +1,31 @@ { "components": [ { - "bom-ref": "pkg:github/mongodb/libmongocrypt@1.13.2", + "bom-ref": "pkg:github/mongodb/libmongocrypt@1.14.0", "externalReferences": [ { "type": "distribution", - "url": "https://github.com/mongodb/libmongocrypt/archive/refs/tags/1.13.2.tar.gz" + "url": "https://github.com/mongodb/libmongocrypt/archive/refs/tags/1.14.0.tar.gz" }, { "type": "website", - "url": "https://github.com/mongodb/libmongocrypt/tree/1.13.2" + "url": "https://github.com/mongodb/libmongocrypt/tree/1.14.0" } ], "group": "mongodb", "name": "libmongocrypt", - "purl": "pkg:github/mongodb/libmongocrypt@1.13.2", + "purl": "pkg:github/mongodb/libmongocrypt@1.14.0", "type": "library", - "version": "1.13.2" + "version": "1.14.0" } ], "dependencies": [ { - "ref": "pkg:github/mongodb/libmongocrypt@1.13.2" + "ref": "pkg:github/mongodb/libmongocrypt@1.14.0" } ], "metadata": { - "timestamp": "2025-05-20T09:00:09.740656+00:00", + "timestamp": "2025-05-20T09:42:47.194999+00:00", "tools": [ { "externalReferences": [ @@ -69,7 +69,7 @@ ] }, "serialNumber": "urn:uuid:67ce9be7-c1c0-436f-a7d7-c636db7b882b", - "version": 4, + "version": 5, "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", "bomFormat": "CycloneDX", "specVersion": "1.5",