Skip to content

CDRIVER-4394 Add explicit encryption support and tests for range indexes #1152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 73 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
a9b6f38
CDRIVER-4394 Add range options struct and send options to mongocrypt
galon1 Nov 21, 2022
d93f57f
CDRIVER-4394 rename rangeopts to range_opts
galon1 Nov 21, 2022
299fdd9
CDRIVER-4394 change bson_t * to bson_t
galon1 Nov 21, 2022
0176e23
CDRIVER-4394 combine min max and precision into one function
galon1 Nov 21, 2022
96dce00
CDRIVER-4394 case insensitive checking of algorithm string
galon1 Nov 21, 2022
0edb450
CDRIVER-4394 add destroy function and 2 basic tests
galon1 Nov 22, 2022
8aff564
CDRIVER-4394 fix comments
galon1 Nov 22, 2022
2335818
CDRIVER-4394 fix parameter
galon1 Nov 22, 2022
630a957
CDRIVER-4394 remove free
galon1 Nov 22, 2022
1f3c697
CDRIVER-4394 add multiple documents to test
galon1 Nov 28, 2022
eb47427
CDRIVER-4394 update to rangePreview and precision additions in mongoc…
galon1 Nov 28, 2022
280b122
CDRIVER-4394 change name to include encrypt
galon1 Nov 28, 2022
2d09771
CDRIVER-4394 update name of function
galon1 Nov 28, 2022
36c3efb
CDRIVER-4394 remove double from json
galon1 Nov 28, 2022
458b9c3
WIP: PR changes and add new tests
galon1 Nov 28, 2022
73965a6
CDRIVER-4394 PR changes and add more tests for integer
galon1 Nov 28, 2022
803d18c
CDRIVER-4394 switch order of destroy
galon1 Nov 28, 2022
75282e7
CDRIVER-4394 refactor testing code for new data types
galon1 Nov 29, 2022
fb3249c
CDRIVER-4394 refactor testing code to allow new data types
galon1 Nov 29, 2022
b0f9688
CDRIVER-4394 finish integer tests and add new data types
galon1 Nov 29, 2022
967de08
CDRIVER-4394 error tests for types and tests for double with precision
galon1 Nov 29, 2022
b7ae8a8
CDRIVER-4394 add tests for long integer
galon1 Nov 29, 2022
dd499ff
CDRIVER-4394 add precision tests and destroy calls
galon1 Nov 29, 2022
d6f2e82
CDRIVER-4394 finish tests for all types
galon1 Nov 30, 2022
f291c53
add static to function definition
galon1 Nov 30, 2022
f129fe0
CDRIVER-4394 fix for evergreen tests to run
galon1 Nov 30, 2022
734bfb5
CDRIVER-4394 fix integer max to 200 to match prose tests
galon1 Nov 30, 2022
2ed6e7b
CDRIVER-4394 add tmp_bson, fix variable names and add copy function
galon1 Dec 1, 2022
7f01782
CDRIVER-4394 add $expr tests
galon1 Dec 1, 2022
eb0e74f
CDRIVER-4394 add null check
galon1 Dec 1, 2022
bb340c5
CDRIVER-4394 null check fix
galon1 Dec 1, 2022
9befcad
Merge branch 'master' of github.com:galon1/mongo-c-driver into CDRIVE…
galon1 Dec 1, 2022
546772f
CDRIVER-4394 add cursor destroy and remove unused variable
galon1 Dec 1, 2022
3b8e179
CDRIVER-4394 add destroy calls
galon1 Dec 1, 2022
f4ee42d
CDRIVER-4394 destroy intermediate payloads
galon1 Dec 1, 2022
a394794
CDRIVER-4394 remove unintended line breaks
galon1 Dec 1, 2022
ed2e670
CDRIVER-4394 documentation additions
galon1 Dec 2, 2022
b2b668b
CDRIVER-4394 update comment
galon1 Dec 2, 2022
f58c35f
CDRIVER-4394 update warning message
galon1 Dec 2, 2022
2e498ca
CDRIVER-4394 fix numbering
galon1 Dec 2, 2022
7f5a18a
CDRIVER-4394 fix type of sparsity and update test to match prose tests
galon1 Dec 2, 2022
1abf657
CDRIVER-4394 update precision to use max 200 and match prose decrypt …
galon1 Dec 2, 2022
93ac0bf
CDRIVER-4394 format document
galon1 Dec 2, 2022
98b76df
fix macro warning
kevinAlbs Dec 13, 2022
092ecd1
format
kevinAlbs Dec 13, 2022
615cb8c
ignore NULL in _state_machine_destroy
kevinAlbs Dec 13, 2022
c1c6cc8
add _mongoc_crypt_explicit_encrypt_expression
kevinAlbs Dec 13, 2022
f858302
require libmongocrypt 1.7.0-alpha1
kevinAlbs Dec 13, 2022
7da8514
format
kevinAlbs Dec 13, 2022
9322e44
update prose tests
kevinAlbs Dec 14, 2022
86bb81c
add ASSERT_BSONVALUE_EQ
kevinAlbs Dec 16, 2022
15eb170
fix compile without cse
kevinAlbs Dec 16, 2022
ee302e8
add TODOs to update libmongocrypt version
kevinAlbs Dec 16, 2022
0a20f50
add note to encrypt_expression consistent with other range API
kevinAlbs Dec 16, 2022
62520c6
quote JSON examples
kevinAlbs Dec 16, 2022
7454a4f
fix grammar typo
kevinAlbs Dec 16, 2022
f42ee13
fix header length
kevinAlbs Dec 16, 2022
00cedb4
link to encrypt_expression from encrypt
kevinAlbs Dec 16, 2022
5eae604
assert on NULL args in option setters
kevinAlbs Dec 16, 2022
5ca480f
do not error if range options are not set
kevinAlbs Dec 16, 2022
b00395c
rename expr_encrypted to expr_out
kevinAlbs Dec 19, 2022
54a35a2
remove duplicate note
kevinAlbs Dec 19, 2022
63b1afb
add missing quotes
kevinAlbs Dec 19, 2022
939bfa7
make range_opts a const arg
kevinAlbs Dec 19, 2022
12eb432
remove unnecessary if
kevinAlbs Dec 19, 2022
8b2311f
destroy bson value before copy
kevinAlbs Dec 19, 2022
9dacf27
use const in append_bson_range_opts
kevinAlbs Dec 19, 2022
cfc028f
revert whitespace change
kevinAlbs Dec 19, 2022
2aaf992
pass NULL range_opts if unset
kevinAlbs Dec 19, 2022
9b2d369
add more const in mongoc-crypt-private API
kevinAlbs Dec 19, 2022
d7a8d5c
do not require non-NULL error
kevinAlbs Dec 19, 2022
7008c77
do not bump compile dependency of libmongocrypt
kevinAlbs Dec 19, 2022
acddc7b
Merge branch 'master' into CDRIVER-4394
kevinAlbs Dec 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .evergreen/compile-test-azurekms.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ ROOT=$(pwd)
INSTALL_DIR=$ROOT/install
. .evergreen/find-cmake.sh
echo "Installing libmongocrypt ... begin"
git clone https://github.com/mongodb/libmongocrypt --branch 1.6.0
# TODO(CDRIVER-4394) update to use libmongocrypt 1.7.0 once there is a stable 1.7.0 release.
git clone https://github.com/mongodb/libmongocrypt --branch 1.7.0-alpha1
$CMAKE -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" \
-DBUILD_TESTING=OFF \
"-H$ROOT/libmongocrypt" \
Expand Down
3 changes: 2 additions & 1 deletion .evergreen/compile-unix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ pkg-config --modversion libssl || true

if [ "$COMPILE_LIBMONGOCRYPT" = "ON" ]; then
# Build libmongocrypt, using the previously fetched installed source.
git clone https://github.com/mongodb/libmongocrypt --branch 1.6.0
# TODO(CDRIVER-4394) update to use libmongocrypt 1.7.0 once there is a stable 1.7.0 release.
git clone https://github.com/mongodb/libmongocrypt --branch 1.7.0-alpha1

mkdir libmongocrypt/cmake-build
cd libmongocrypt/cmake-build
Expand Down
3 changes: 2 additions & 1 deletion .evergreen/compile-windows.sh
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ fi

if [ "$COMPILE_LIBMONGOCRYPT" = "ON" ]; then
# Build libmongocrypt, using the previously fetched installed source.
git clone https://github.com/mongodb/libmongocrypt --branch 1.6.0
# TODO(CDRIVER-4394) update to use libmongocrypt 1.7.0 once there is a stable 1.7.0 release.
git clone https://github.com/mongodb/libmongocrypt --branch 1.7.0-alpha1
mkdir libmongocrypt/cmake-build
cd libmongocrypt/cmake-build
"$CMAKE" -G "$CC" "-DCMAKE_PREFIX_PATH=${INSTALL_DIR}/lib/cmake" -DENABLE_SHARED_BSON=ON -DCMAKE_INSTALL_PREFIX="$INSTALL_DIR" ../
Expand Down
1 change: 1 addition & 0 deletions src/libmongoc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ elseif (NOT ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL OFF)
find_package (mongocrypt QUIET)
endif ()

# TODO(CDRIVER-4394) update to use libmongocrypt 1.7.0 once there is a stable 1.7.0 release.
if (mongocrypt_FOUND AND "${mongocrypt_VERSION}" VERSION_LESS 1.6.0)
message ("-- libmongocrypt found at ${mongocrypt_DIR}")
message ("-- libmongocrypt version ${mongocrypt_VERSION} found")
Expand Down
1 change: 1 addition & 0 deletions src/libmongoc/doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ API Reference
mongoc_client_encryption_datakey_opts_t
mongoc_client_encryption_rewrap_many_datakey_result_t
mongoc_client_encryption_encrypt_opts_t
mongoc_client_encryption_encrypt_range_opts_t
mongoc_client_encryption_opts_t
mongoc_client_pool_t
mongoc_client_session_t
Expand Down
4 changes: 4 additions & 0 deletions src/libmongoc/doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@

This API |qenc:is-experimental|

.. |qenc:range-is-experimental| replace::

Range algorithm is experimental only and not intended for public use. It is subject to breaking changes.

'''


Expand Down
12 changes: 10 additions & 2 deletions src/libmongoc/doc/mongoc_client_encryption_encrypt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,22 @@ Performs explicit encryption.

``ciphertext`` is always initialized (even on failure). Caller must call :symbol:`bson_value_destroy()` to free.

To insert or query with an "Indexed" encrypted payload, use a
To insert or query with an "Indexed" or "RangePreview" encrypted payload, use a
:symbol:`mongoc_client_t` configured with
:symbol:`mongoc_auto_encryption_opts_t`. The
:symbol:`mongoc_auto_encryption_opts_t` may be configured to bypass query
analysis with :symbol:`mongoc_auto_encryption_opts_set_bypass_query_analysis`.
The :symbol:`mongoc_auto_encryption_opts_t` must not be configured to bypass
automatic encryption with
:symbol:`mongoc_auto_encryption_opts_set_bypass_auto_encryption`. **Note** that
the ``"Indexed"`` payload type |qenc:is-experimental|
the ``"Indexed"`` and ``"RangePreview"`` payload type |qenc:is-experimental|. The |qenc:range-is-experimental|

To insert with a ``RangePreview`` payload
:symbol:`mongoc_client_encryption_encrypt_range_opts_t` must be set in ``opts``.

To query with a ``RangePreview`` payload, use :symbol:`mongoc_client_encryption_encrypt_expression()`

**NOTE** that the |qenc:range-is-experimental|

Parameters
----------
Expand All @@ -52,3 +59,4 @@ Returns ``true`` if successful. Returns ``false`` and sets ``error`` otherwise.

| :symbol:`mongoc_client_encryption_decrypt()`

| :symbol:`mongoc_client_encryption_encrypt_expression()`
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
:man_page: mongoc_client_encryption_encrypt_expression

mongoc_client_encryption_encrypt_expression()
=============================================

Synopsis
--------

.. code-block:: c

bool
mongoc_client_encryption_encrypt_expression (
mongoc_client_encryption_t *client_encryption,
const bson_t *expr,
mongoc_client_encryption_encrypt_opts_t *opts,
bson_t *expr_out,
bson_error_t *error);

.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
.. versionadded:: 1.24.0

Encrypts a Match Expression or Aggregate Expression to query a range index.

To query with a ``RangePreview`` encrypted payload, use a
:symbol:`mongoc_client_t` configured with
:symbol:`mongoc_auto_encryption_opts_t`. The
:symbol:`mongoc_auto_encryption_opts_t` may be configured to bypass query
analysis with :symbol:`mongoc_auto_encryption_opts_set_bypass_query_analysis`.
The :symbol:`mongoc_auto_encryption_opts_t` must not be configured to bypass
automatic encryption with
:symbol:`mongoc_auto_encryption_opts_set_bypass_auto_encryption`.

To query with a ``RangePreview`` payload, ``expr`` must be one of the following forms:

#. A Match Expression of the following form:

.. code-block:: javascript

// $gt may also be $gte. $lt may also be $lte.
// Can include one of $gt/$gte/$lt/$lte. It is not required to include both.
{"$and": [{"<field>": {"$gt": "<value1>"}}, {"<field>": {"$lt": "<value2>" }}]}

#. An Aggregation Expression of this form:

.. code-block:: javascript

// $gt may also be $gte. $lt may also be $lte
// Can include one of $gt/$gte/$lt/$lte. It is not required to include both.
{"$and": [{"$gt": ["<fieldpath>", "<value1>"]}, {"$lt": ["<fieldpath>", "<value2>"]}]

Parameters
----------

* ``client_encryption``: A :symbol:`mongoc_client_encryption_t`
* ``expr``: The expression to encrypt.
* ``opts``: A :symbol:`mongoc_client_encryption_encrypt_opts_t`.
* ``expr_out``: A :symbol:`bson_t` for the resulting encrypted expression. ``expr_out`` is always initialized (even on failure). Caller must call :symbol:`bson_destroy()` to free.
* ``error``: A :symbol:`bson_error_t` set on failure.

Returns
-------

Returns ``true`` if successful. Returns ``false`` and sets ``error`` otherwise.

.. seealso::

| :symbol:`mongoc_client_encryption_encrypt_opts_t`

| :symbol:`mongoc_client_enable_auto_encryption()`

| :symbol:`mongoc_client_encryption_decrypt()`

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Synopsis
#define MONGOC_ENCRYPT_ALGORITHM_INDEXED "Indexed"
// (Experimental: See below)
#define MONGOC_ENCRYPT_ALGORITHM_UNINDEXED "Unindexed"
// (Experimental: See below)
#define MONGOC_ENCRYPT_ALGORITHM_RANGEPREVIEW "RangePreview"

Identifies the algorithm to use for encryption. Valid values of ``algorithm`` are:

Expand All @@ -41,6 +43,12 @@ Identifies the algorithm to use for encryption. Valid values of ``algorithm`` ar

.. note:: |qenc:opt-is-experimental|

``"RangePreview"``

for range encryption.

.. note:: The |qenc:range-is-experimental| |qenc:opt-is-experimental|

Parameters
----------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Synopsis
.. versionadded:: 1.22.0

Sets a contention factor for explicit encryption.
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "Indexed".
It is an error to set the contention factor when algorithm is not "Indexed".
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "Indexed" or "RangePreview".
It is an error to set the contention factor when algorithm is not "Indexed" or "RangePreview". **Note** that the |qenc:range-is-experimental|
If contention factor is not supplied, it defaults to a value of 0.

Parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Synopsis
.. code-block:: c

#define MONGOC_ENCRYPT_QUERY_TYPE_EQUALITY "equality"
#define MONGOC_ENCRYPT_QUERY_TYPE_RANGEPREVIEW "rangePreview"

MONGOC_EXPORT (void)
mongoc_client_encryption_encrypt_opts_set_query_type (
Expand All @@ -17,11 +18,11 @@ Synopsis
.. important:: |qenc:api-is-experimental|
.. versionadded:: 1.22.0

Sets a query type for explicit encryption. Currently, the only supported value
for ``query_type`` is ``"equality"``.
Sets a query type for explicit encryption. Currently, the supported values
for ``query_type`` are ``"equality"`` and ``"rangePreview"``. **NOTE** that the |qenc:range-is-experimental|

Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "Indexed".
It is an error to set the query type when algorithm is not "Indexed".
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "Indexed" or "RangePreview".
It is an error to set the query type when algorithm is not "Indexed" or "RangePreview".

Parameters
----------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
:man_page: mongoc_client_encryption_encrypt_opts_set_range_opts

mongoc_client_encryption_encrypt_opts_set_range_opts()
======================================================

Synopsis
--------

.. code-block:: c

void
mongoc_client_encryption_encrypt_opts_set_range_opts (
mongoc_client_encryption_encrypt_opts_t *opts,
const mongoc_client_encryption_encrypt_range_opts_t *range_opts);

.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
.. versionadded:: 1.24.0

Sets the ``range_opts`` for explicit encryption.
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "RangePreview".
It is an error to set ``range_opts`` when algorithm is not "RangePreview".

Parameters
----------

* ``opts``: A :symbol:`mongoc_client_encryption_encrypt_opts_t`
* ``range_opts``: A :symbol:`mongoc_client_encryption_encrypt_range_opts_t`

.. seealso::

| :symbol:`mongoc_client_encryption_encrypt_range_opts_new`
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Used to set options for :symbol:`mongoc_client_encryption_encrypt()`.
mongoc_client_encryption_encrypt_opts_set_algorithm
mongoc_client_encryption_encrypt_opts_set_contention_factor
mongoc_client_encryption_encrypt_opts_set_query_type
mongoc_client_encryption_encrypt_opts_set_range_opts

.. seealso::

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
:man_page: mongoc_client_encryption_encrypt_range_opts_destroy

mongoc_client_encryption_encrypt_range_opts_destroy()
=====================================================

Synopsis
--------

.. code-block:: c

void
mongoc_client_encryption_encrypt_range_opts_destroy (mongoc_client_encryption_encrypt_range_opts_t *range_opts);

.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
.. versionadded:: 1.24.0

Frees resources of a :symbol:`mongoc_client_encryption_encrypt_range_opts_t` created with :symbol:`mongoc_client_encryption_encrypt_range_opts_new()`. Does nothing if ``NULL`` is passed.

Parameters
----------

* ``range_opts``: A :symbol:`mongoc_client_encryption_encrypt_range_opts_t`.

.. seealso::
| :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
:man_page: mongoc_client_encryption_encrypt_range_opts_new

mongoc_client_encryption_encrypt_range_opts_new()
=================================================

Synopsis
--------

.. code-block:: c

mongoc_client_encryption_encrypt_range_opts_t *
mongoc_client_encryption_encrypt_range_opts_new (void);

.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
.. versionadded:: 1.24.0

Returns
-------

A new :symbol:`mongoc_client_encryption_encrypt_range_opts_t` that must be freed with :symbol:`mongoc_client_encryption_encrypt_range_opts_destroy()`.


.. seealso::
| :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
| :symbol:`mongoc_client_encryption_encrypt_range_opts_destroy`
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
:man_page: mongoc_client_encryption_encrypt_range_opts_set_min_max

mongoc_client_encryption_encrypt_range_opts_set_min_max()
=========================================================

Synopsis
--------

.. code-block:: c

void
mongoc_client_encryption_encrypt_opts_set_min_max (
mongoc_client_encryption_encrypt_range_opts_t *range_opts,
const bson_value_t *min,
const bson_value_t *max);

.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
.. versionadded:: 1.24.0

Sets the minimum and maximum values of the range for explicit encryption.
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "RangePreview".
It is an error to set minimum and maximum when algorithm is not "RangePreview".

The minimum and maximum must match the values set in the encryptedFields of the destination collection.
It is an error to set a different value.

For double and decimal128 fields, min/max/precision must all be set, or all be unset.

Parameters
----------

* ``range_opts``: A :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
* ``min``: The minimum bson value of the range.
* ``max``: The maximum bson value of the range.

.. seealso::

| :symbol:`mongoc_client_encryption_encrypt_range_opts_set_precision`
| :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
:man_page: mongoc_client_encryption_encrypt_range_opts_set_precision

mongoc_client_encryption_encrypt_range_opts_set_precision()
===========================================================

Synopsis
--------

.. code-block:: c

void
mongoc_client_encryption_encrypt_opts_set_precision (
mongoc_client_encryption_encrypt_range_opts_t *range_opts, int32_t precision);

.. important:: The |qenc:range-is-experimental| |qenc:api-is-experimental|
.. versionadded:: 1.24.0

Sets precision for explicit encryption.
Only applies when the algorithm set by :symbol:`mongoc_client_encryption_encrypt_opts_set_algorithm()` is "RangePreview".
It is an error to set precision when algorithm is not "RangePreview".

Precision can only be set with double or decimal128 fields.
It is an error to set precision if the type of the encryptedFields in the destination collection is not double or decimal128.

For double and decimal128 fields, min/max/precision must all be set, or all be unset.

Precision must match the value set in the encryptedFields of the destination collection.
It is an error to set a different value.

Parameters
----------

* ``range_opts``: A :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
* ``precision``: A non-negative precision.

.. seealso::

| :symbol:`mongoc_client_encryption_encrypt_range_opts_set_min_max`
| :symbol:`mongoc_client_encryption_encrypt_range_opts_t`
Loading