From 75eda251483ebde1931c09e66592f955537e49ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 24 Sep 2024 23:25:29 +0200 Subject: [PATCH 1/2] PHPC-2457 Fix modifiers and other Query options by reference --- src/MongoDB/Query.c | 2 ++ tests/query/bug2457-001.phpt | 34 +++++++++++++++++++++++++ tests/query/bug2457-002.phpt | 49 ++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 tests/query/bug2457-001.phpt create mode 100644 tests/query/bug2457-002.phpt diff --git a/src/MongoDB/Query.c b/src/MongoDB/Query.c index 362ec622c..bb10a6505 100644 --- a/src/MongoDB/Query.c +++ b/src/MongoDB/Query.c @@ -58,6 +58,7 @@ static bool php_phongo_query_opts_append_document(bson_t* opts, const char* opts zval* value = php_array_fetch(zarr, zarr_key); bson_t b = BSON_INITIALIZER; + ZVAL_DEREF(value); if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" %s to be array or object, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value)); return false; @@ -333,6 +334,7 @@ bool phongo_query_init(zval* return_value, zval* filter, zval* options) if (php_array_existsc(options, "modifiers")) { modifiers = php_array_fetchc(options, "modifiers"); + ZVAL_DEREF(modifiers); if (Z_TYPE_P(modifiers) != IS_ARRAY) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"modifiers\" option to be array, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(modifiers)); return false; diff --git a/tests/query/bug2457-001.phpt b/tests/query/bug2457-001.phpt new file mode 100644 index 000000000..5033ff558 --- /dev/null +++ b/tests/query/bug2457-001.phpt @@ -0,0 +1,34 @@ +--TEST-- +PHPC-2457: Query modifiers can be passed reference +--FILE-- + ['x' => 1]]; + +$query = new MongoDB\Driver\Query([], [ + 'modifiers' => &$modifiers, +]); + +var_dump($query); + +?> +===DONE=== + +--EXPECTF-- +Deprecated: MongoDB\Driver\Query::__construct(): The "modifiers" option is deprecated and will be removed in a future release in %s +object(MongoDB\Driver\Query)#1 (3) { + ["filter"]=> + object(stdClass)#2 (0) { + } + ["options"]=> + object(stdClass)#4 (1) { + ["sort"]=> + object(stdClass)#3 (1) { + ["x"]=> + int(1) + } + } + ["readConcern"]=> + NULL +} +===DONE=== diff --git a/tests/query/bug2457-002.phpt b/tests/query/bug2457-002.phpt new file mode 100644 index 000000000..90a22c246 --- /dev/null +++ b/tests/query/bug2457-002.phpt @@ -0,0 +1,49 @@ +--TEST-- +PHPC-2457: Query options can be passed reference +--FILE-- + 'fr_FR', 'strength' => 2]; +$let = ['x' => 1]; +$sort = ['_id' => 1]; + +$query = new MongoDB\Driver\Query([], [ + 'collation' => &$collation, + 'let' => &$let, + 'sort' => &$sort, +]); + +var_dump($query); + +?> +===DONE=== + +--EXPECT-- +object(MongoDB\Driver\Query)#1 (3) { + ["filter"]=> + object(stdClass)#2 (0) { + } + ["options"]=> + object(stdClass)#6 (3) { + ["collation"]=> + object(stdClass)#3 (2) { + ["locale"]=> + string(5) "fr_FR" + ["strength"]=> + int(2) + } + ["let"]=> + object(stdClass)#4 (1) { + ["x"]=> + int(1) + } + ["sort"]=> + object(stdClass)#5 (1) { + ["_id"]=> + int(1) + } + } + ["readConcern"]=> + NULL +} +===DONE=== From 0252be9f554747881c7bf8965cb887f301df00b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 24 Sep 2024 23:56:27 +0200 Subject: [PATCH 2/2] Move ZVAL_DEREF to php_array_fetch --- src/MongoDB/Query.c | 1 - src/contrib/php_array_api.h | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/MongoDB/Query.c b/src/MongoDB/Query.c index bb10a6505..1c02c4847 100644 --- a/src/MongoDB/Query.c +++ b/src/MongoDB/Query.c @@ -58,7 +58,6 @@ static bool php_phongo_query_opts_append_document(bson_t* opts, const char* opts zval* value = php_array_fetch(zarr, zarr_key); bson_t b = BSON_INITIALIZER; - ZVAL_DEREF(value); if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_ARRAY) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected \"%s\" %s to be array or object, %s given", zarr_key, zarr_key[0] == '$' ? "modifier" : "option", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(value)); return false; diff --git a/src/contrib/php_array_api.h b/src/contrib/php_array_api.h index 17dc74810..e5d8d096a 100644 --- a/src/contrib/php_array_api.h +++ b/src/contrib/php_array_api.h @@ -188,7 +188,12 @@ zval *php_array_fetchl(zval *zarr, const char *key, int key_len) { } static inline zval *php_array_fetch(zval *zarr, const char *key) { - return php_array_fetchl(zarr, key, strlen(key)); + zval *ret = php_array_fetchl(zarr, key, strlen(key)); + if (ret) { + ZVAL_DEREF(ret); + } + + return ret; } #define php_array_fetchc(zarr, litstr) php_array_fetchl(zarr, litstr, sizeof(litstr)-1) static inline