From c1f3c909f11718332cf63e020d474c037e6d4d3d Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Fri, 13 Sep 2019 11:02:07 +0200 Subject: [PATCH 1/3] Remove unnecessary parameter from php_phongo_make_uri --- php_phongo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php_phongo.c b/php_phongo.c index 2344052d2..2ce6f5933 100644 --- a/php_phongo.c +++ b/php_phongo.c @@ -1385,7 +1385,7 @@ void php_phongo_write_concern_to_zval(zval* retval, const mongoc_write_concern_t } /* }}} */ /* }}} */ -static mongoc_uri_t* php_phongo_make_uri(const char* uri_string, bson_t* options TSRMLS_DC) /* {{{ */ +static mongoc_uri_t* php_phongo_make_uri(const char* uri_string TSRMLS_DC) /* {{{ */ { mongoc_uri_t* uri; bson_error_t error = { 0 }; @@ -2654,7 +2654,7 @@ void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string, goto cleanup; } - if (!(uri = php_phongo_make_uri(uri_string, &bson_options TSRMLS_CC))) { + if (!(uri = php_phongo_make_uri(uri_string TSRMLS_CC))) { /* Exception should already have been thrown */ goto cleanup; } From 42a674c9afc1a71b01f124cb9595a91157a90dae Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Mon, 23 Sep 2019 15:37:33 +0200 Subject: [PATCH 2/3] PHPC-991: Handle duplicates in URI options array --- php_phongo.c | 349 +++++++++--------- .../manager-ctor-duplicate-option-001.phpt | 15 + .../manager-ctor-duplicate-option-002.phpt | 15 + .../manager-ctor-duplicate-option-003.phpt | 15 + .../manager-ctor-duplicate-option-004.phpt | 21 ++ 5 files changed, 241 insertions(+), 174 deletions(-) create mode 100644 tests/manager/manager-ctor-duplicate-option-001.phpt create mode 100644 tests/manager/manager-ctor-duplicate-option-002.phpt create mode 100644 tests/manager/manager-ctor-duplicate-option-003.phpt create mode 100644 tests/manager/manager-ctor-duplicate-option-004.phpt diff --git a/php_phongo.c b/php_phongo.c index 2ce6f5933..7cabb497e 100644 --- a/php_phongo.c +++ b/php_phongo.c @@ -1737,25 +1737,25 @@ static bool php_phongo_apply_rc_options_to_uri(mongoc_uri_t* uri, bson_t* option } /* Return early if there are no options to apply */ - if (bson_empty0(options)) { - return true; - } - - if (!bson_iter_init_find_case(&iter, options, MONGOC_URI_READCONCERNLEVEL)) { + if (bson_empty0(options) || !bson_iter_init(&iter, options)) { return true; } new_rc = mongoc_read_concern_copy(old_rc); - if (bson_iter_init_find_case(&iter, options, MONGOC_URI_READCONCERNLEVEL)) { - if (!BSON_ITER_HOLDS_UTF8(&iter)) { - PHONGO_URI_INVALID_TYPE(iter, "string"); - mongoc_read_concern_destroy(new_rc); + while (bson_iter_next(&iter)) { + const char* key = bson_iter_key(&iter); - return false; - } + if (!strcasecmp(key, MONGOC_URI_READCONCERNLEVEL)) { + if (!BSON_ITER_HOLDS_UTF8(&iter)) { + PHONGO_URI_INVALID_TYPE(iter, "string"); + mongoc_read_concern_destroy(new_rc); - mongoc_read_concern_set_level(new_rc, bson_iter_utf8(&iter, NULL)); + return false; + } + + mongoc_read_concern_set_level(new_rc, bson_iter_utf8(&iter, NULL)); + } } mongoc_uri_set_read_concern(uri, new_rc); @@ -1777,144 +1777,149 @@ static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t* uri, bson_t* option } /* Return early if there are no options to apply */ - if (bson_empty0(options)) { - return true; - } - - if (!bson_iter_init_find_case(&iter, options, MONGOC_URI_SLAVEOK) && - !bson_iter_init_find_case(&iter, options, MONGOC_URI_READPREFERENCE) && - !bson_iter_init_find_case(&iter, options, MONGOC_URI_READPREFERENCETAGS) && - !bson_iter_init_find_case(&iter, options, MONGOC_URI_MAXSTALENESSSECONDS)) { + if (bson_empty0(options) || !bson_iter_init(&iter, options)) { return true; } new_rp = mongoc_read_prefs_copy(old_rp); - if (bson_iter_init_find_case(&iter, options, MONGOC_URI_SLAVEOK)) { - if (!BSON_ITER_HOLDS_BOOL(&iter)) { - PHONGO_URI_INVALID_TYPE(iter, "boolean"); - mongoc_read_prefs_destroy(new_rp); + while (bson_iter_next(&iter)) { + const char* key = bson_iter_key(&iter); - return false; - } + if (!strcasecmp(key, MONGOC_URI_SLAVEOK)) { + if (!BSON_ITER_HOLDS_BOOL(&iter)) { + PHONGO_URI_INVALID_TYPE(iter, "boolean"); + mongoc_read_prefs_destroy(new_rp); - if (bson_iter_bool(&iter)) { - mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY_PREFERRED); + return false; + } + + if (bson_iter_bool(&iter)) { + mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY_PREFERRED); + } } - } - if (bson_iter_init_find_case(&iter, options, MONGOC_URI_READPREFERENCE)) { - const char* str; + if (!strcasecmp(key, MONGOC_URI_READPREFERENCE)) { + const char* str; - if (!BSON_ITER_HOLDS_UTF8(&iter)) { - PHONGO_URI_INVALID_TYPE(iter, "string"); - mongoc_read_prefs_destroy(new_rp); + if (!BSON_ITER_HOLDS_UTF8(&iter)) { + PHONGO_URI_INVALID_TYPE(iter, "string"); + mongoc_read_prefs_destroy(new_rp); - return false; - } + return false; + } - str = bson_iter_utf8(&iter, NULL); - - if (0 == strcasecmp("primary", str)) { - mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_PRIMARY); - } else if (0 == strcasecmp("primarypreferred", str)) { - mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_PRIMARY_PREFERRED); - } else if (0 == strcasecmp("secondary", str)) { - mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY); - } else if (0 == strcasecmp("secondarypreferred", str)) { - mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY_PREFERRED); - } else if (0 == strcasecmp("nearest", str)) { - mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_NEAREST); - } else { - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Unsupported %s value: '%s'", bson_iter_key(&iter), str); - mongoc_read_prefs_destroy(new_rp); + str = bson_iter_utf8(&iter, NULL); + + if (0 == strcasecmp("primary", str)) { + mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_PRIMARY); + } else if (0 == strcasecmp("primarypreferred", str)) { + mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_PRIMARY_PREFERRED); + } else if (0 == strcasecmp("secondary", str)) { + mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY); + } else if (0 == strcasecmp("secondarypreferred", str)) { + mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY_PREFERRED); + } else if (0 == strcasecmp("nearest", str)) { + mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_NEAREST); + } else { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Unsupported %s value: '%s'", bson_iter_key(&iter), str); + mongoc_read_prefs_destroy(new_rp); - return false; + return false; + } } - } - if (bson_iter_init_find_case(&iter, options, MONGOC_URI_READPREFERENCETAGS)) { - bson_t tags; - uint32_t len; - const uint8_t* data; + if (!strcasecmp(key, MONGOC_URI_READPREFERENCETAGS)) { + bson_t tags; + uint32_t len; + const uint8_t* data; - if (!BSON_ITER_HOLDS_ARRAY(&iter)) { - PHONGO_URI_INVALID_TYPE(iter, "array"); - mongoc_read_prefs_destroy(new_rp); + if (!BSON_ITER_HOLDS_ARRAY(&iter)) { + PHONGO_URI_INVALID_TYPE(iter, "array"); + mongoc_read_prefs_destroy(new_rp); - return false; - } + return false; + } - bson_iter_array(&iter, &len, &data); + bson_iter_array(&iter, &len, &data); - if (!bson_init_static(&tags, data, len)) { - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Could not initialize BSON structure for read preference tags"); - mongoc_read_prefs_destroy(new_rp); + if (!bson_init_static(&tags, data, len)) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Could not initialize BSON structure for read preference tags"); + mongoc_read_prefs_destroy(new_rp); - return false; - } + return false; + } - if (!php_phongo_read_preference_tags_are_valid(&tags)) { - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference tags must be an array of zero or more documents"); - mongoc_read_prefs_destroy(new_rp); + if (!php_phongo_read_preference_tags_are_valid(&tags)) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference tags must be an array of zero or more documents"); + mongoc_read_prefs_destroy(new_rp); - return false; + return false; + } + + mongoc_read_prefs_set_tags(new_rp, &tags); } - mongoc_read_prefs_set_tags(new_rp, &tags); - } + if (!strcasecmp(key, MONGOC_URI_MAXSTALENESSSECONDS)) { + int64_t max_staleness_seconds; - if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY && - !bson_empty(mongoc_read_prefs_get_tags(new_rp))) { - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with tags"); - mongoc_read_prefs_destroy(new_rp); + if (!BSON_ITER_HOLDS_INT(&iter)) { + PHONGO_URI_INVALID_TYPE(iter, "integer"); + mongoc_read_prefs_destroy(new_rp); - return false; - } + return false; + } - /* Handle maxStalenessSeconds, and make sure it is not combined with primary - * readPreference */ - if (bson_iter_init_find_case(&iter, options, MONGOC_URI_MAXSTALENESSSECONDS)) { - int64_t max_staleness_seconds; + max_staleness_seconds = bson_iter_as_int64(&iter); - if (!BSON_ITER_HOLDS_INT(&iter)) { - PHONGO_URI_INVALID_TYPE(iter, "integer"); - mongoc_read_prefs_destroy(new_rp); + if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) { - return false; - } + if (max_staleness_seconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be >= %d, %" PRId64 " given", MONGOC_SMALLEST_MAX_STALENESS_SECONDS, max_staleness_seconds); + mongoc_read_prefs_destroy(new_rp); - max_staleness_seconds = bson_iter_as_int64(&iter); + return false; + } - if (max_staleness_seconds != MONGOC_NO_MAX_STALENESS) { + if (max_staleness_seconds > INT32_MAX) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be <= %d, %" PRId64 " given", INT32_MAX, max_staleness_seconds); + mongoc_read_prefs_destroy(new_rp); - if (max_staleness_seconds < MONGOC_SMALLEST_MAX_STALENESS_SECONDS) { - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be >= %d, %" PRId64 " given", MONGOC_SMALLEST_MAX_STALENESS_SECONDS, max_staleness_seconds); - mongoc_read_prefs_destroy(new_rp); + return false; + } - return false; + if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with maxStalenessSeconds"); + mongoc_read_prefs_destroy(new_rp); + + return false; + } } - if (max_staleness_seconds > INT32_MAX) { - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected maxStalenessSeconds to be <= %d, %" PRId64 " given", INT32_MAX, max_staleness_seconds); - mongoc_read_prefs_destroy(new_rp); + mongoc_read_prefs_set_max_staleness_seconds(new_rp, max_staleness_seconds); + } + } - return false; - } + if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY && + !bson_empty(mongoc_read_prefs_get_tags(new_rp))) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with tags"); + mongoc_read_prefs_destroy(new_rp); - if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY) { - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with maxStalenessSeconds"); - mongoc_read_prefs_destroy(new_rp); + return false; + } - return false; - } - } + /* Make sure maxStalenessSeconds is not combined with primary readPreference */ + if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY && + mongoc_read_prefs_get_max_staleness_seconds(new_rp) != MONGOC_NO_MAX_STALENESS) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with maxStalenessSeconds"); + mongoc_read_prefs_destroy(new_rp); - mongoc_read_prefs_set_max_staleness_seconds(new_rp, max_staleness_seconds); + return false; } - /* This may be redundant in light of the last check (primary with tags), but - * we'll check anyway in case additional validation is implemented. */ + /* This may be redundant in light of the previous checks (primary with tags + * or maxStalenessSeconds), but we'll check anyway in case additional + * validation is implemented. */ if (!mongoc_read_prefs_is_valid(new_rp)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference is not valid"); mongoc_read_prefs_destroy(new_rp); @@ -1941,99 +1946,95 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* option } /* Return early if there are no options to apply */ - if (bson_empty0(options)) { + if (bson_empty0(options) || !bson_iter_init(&iter, options)) { return true; } - if (!bson_iter_init_find_case(&iter, options, MONGOC_URI_JOURNAL) && - !bson_iter_init_find_case(&iter, options, MONGOC_URI_SAFE) && - !bson_iter_init_find_case(&iter, options, MONGOC_URI_W) && - !bson_iter_init_find_case(&iter, options, MONGOC_URI_WTIMEOUTMS)) { + new_wc = mongoc_write_concern_copy(old_wc); - return true; - } + while (bson_iter_next(&iter)) { + const char* key = bson_iter_key(&iter); - new_wc = mongoc_write_concern_copy(old_wc); + if (!strcasecmp(key, MONGOC_URI_SAFE)) { + if (!BSON_ITER_HOLDS_BOOL(&iter)) { + PHONGO_URI_INVALID_TYPE(iter, "boolean"); + mongoc_write_concern_destroy(new_wc); - if (bson_iter_init_find_case(&iter, options, MONGOC_URI_SAFE)) { - if (!BSON_ITER_HOLDS_BOOL(&iter)) { - PHONGO_URI_INVALID_TYPE(iter, "boolean"); - mongoc_write_concern_destroy(new_wc); + return false; + } - return false; + mongoc_write_concern_set_w(new_wc, bson_iter_bool(&iter) ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); } - mongoc_write_concern_set_w(new_wc, bson_iter_bool(&iter) ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); - } + if (!strcasecmp(key, MONGOC_URI_WTIMEOUTMS)) { + int64_t wtimeout; - if (bson_iter_init_find_case(&iter, options, MONGOC_URI_WTIMEOUTMS)) { - int64_t wtimeout; + /* Although the write concern spec defines wtimeoutMS as 64-bit, PHP has + * historically required 32-bit. This may change with PHPC-1411. */ + if (!BSON_ITER_HOLDS_INT32(&iter)) { + PHONGO_URI_INVALID_TYPE(iter, "32-bit integer"); + mongoc_write_concern_destroy(new_wc); - /* Although the write concern spec defines wtimeoutMS as 64-bit, PHP has - * historically required 32-bit. This may change with PHPC-1411. */ - if (!BSON_ITER_HOLDS_INT32(&iter)) { - PHONGO_URI_INVALID_TYPE(iter, "32-bit integer"); - mongoc_write_concern_destroy(new_wc); + return false; + } - return false; - } + wtimeout = bson_iter_as_int64(&iter); - wtimeout = bson_iter_as_int64(&iter); + if (wtimeout < 0) { + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected wtimeoutMS to be >= 0, %" PRId64 " given", wtimeout); + mongoc_write_concern_destroy(new_wc); - if (wtimeout < 0) { - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected wtimeoutMS to be >= 0, %" PRId64 " given", wtimeout); - mongoc_write_concern_destroy(new_wc); + return false; + } - return false; + mongoc_write_concern_set_wtimeout_int64(new_wc, wtimeout); } - mongoc_write_concern_set_wtimeout_int64(new_wc, wtimeout); - } + if (!strcasecmp(key, MONGOC_URI_JOURNAL)) { + if (!BSON_ITER_HOLDS_BOOL(&iter)) { + PHONGO_URI_INVALID_TYPE(iter, "boolean"); + mongoc_write_concern_destroy(new_wc); - if (bson_iter_init_find_case(&iter, options, MONGOC_URI_JOURNAL)) { - if (!BSON_ITER_HOLDS_BOOL(&iter)) { - PHONGO_URI_INVALID_TYPE(iter, "boolean"); - mongoc_write_concern_destroy(new_wc); + return false; + } - return false; + mongoc_write_concern_set_journal(new_wc, bson_iter_bool(&iter)); } - mongoc_write_concern_set_journal(new_wc, bson_iter_bool(&iter)); - } - - if (bson_iter_init_find_case(&iter, options, MONGOC_URI_W)) { - if (BSON_ITER_HOLDS_INT32(&iter)) { - int32_t value = bson_iter_int32(&iter); - - switch (value) { - case MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED: - case MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED: - mongoc_write_concern_set_w(new_wc, value); - break; + if (!strcasecmp(key, MONGOC_URI_W)) { + if (BSON_ITER_HOLDS_INT32(&iter)) { + int32_t value = bson_iter_int32(&iter); - default: - if (value > 0) { + switch (value) { + case MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED: + case MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED: mongoc_write_concern_set_w(new_wc, value); break; - } - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Unsupported w value: %d", value); - mongoc_write_concern_destroy(new_wc); - return false; - } - } else if (BSON_ITER_HOLDS_UTF8(&iter)) { - const char* str = bson_iter_utf8(&iter, NULL); + default: + if (value > 0) { + mongoc_write_concern_set_w(new_wc, value); + break; + } + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Unsupported w value: %d", value); + mongoc_write_concern_destroy(new_wc); + + return false; + } + } else if (BSON_ITER_HOLDS_UTF8(&iter)) { + const char* str = bson_iter_utf8(&iter, NULL); - if (0 == strcasecmp(PHONGO_WRITE_CONCERN_W_MAJORITY, str)) { - mongoc_write_concern_set_w(new_wc, MONGOC_WRITE_CONCERN_W_MAJORITY); + if (0 == strcasecmp(PHONGO_WRITE_CONCERN_W_MAJORITY, str)) { + mongoc_write_concern_set_w(new_wc, MONGOC_WRITE_CONCERN_W_MAJORITY); + } else { + mongoc_write_concern_set_wtag(new_wc, str); + } } else { - mongoc_write_concern_set_wtag(new_wc, str); - } - } else { - PHONGO_URI_INVALID_TYPE(iter, "32-bit integer or string"); - mongoc_write_concern_destroy(new_wc); + PHONGO_URI_INVALID_TYPE(iter, "32-bit integer or string"); + mongoc_write_concern_destroy(new_wc); - return false; + return false; + } } } diff --git a/tests/manager/manager-ctor-duplicate-option-001.phpt b/tests/manager/manager-ctor-duplicate-option-001.phpt new file mode 100644 index 000000000..1f4e09ac8 --- /dev/null +++ b/tests/manager/manager-ctor-duplicate-option-001.phpt @@ -0,0 +1,15 @@ +--TEST-- +MongoDB\Driver\Manager::__construct() with duplicate read preference option +--FILE-- + 'primary', 'readpreference' => 'secondary']); + +echo $manager->getReadPreference()->getMode(), "\n"; + +?> +===DONE=== + +--EXPECT-- +2 +===DONE=== diff --git a/tests/manager/manager-ctor-duplicate-option-002.phpt b/tests/manager/manager-ctor-duplicate-option-002.phpt new file mode 100644 index 000000000..a54258900 --- /dev/null +++ b/tests/manager/manager-ctor-duplicate-option-002.phpt @@ -0,0 +1,15 @@ +--TEST-- +MongoDB\Driver\Manager::__construct() with duplicate read concern option +--FILE-- + 'majority', 'readconcernlevel' => 'local']); + +echo $manager->getReadConcern()->getLevel(), "\n"; + +?> +===DONE=== + +--EXPECT-- +local +===DONE=== diff --git a/tests/manager/manager-ctor-duplicate-option-003.phpt b/tests/manager/manager-ctor-duplicate-option-003.phpt new file mode 100644 index 000000000..a9b9bee69 --- /dev/null +++ b/tests/manager/manager-ctor-duplicate-option-003.phpt @@ -0,0 +1,15 @@ +--TEST-- +MongoDB\Driver\Manager::__construct() with duplicate write concern option +--FILE-- + 500, 'wTimeoutMs' => 200]); + +echo $manager->getWriteConcern()->getWtimeout(), "\n"; + +?> +===DONE=== + +--EXPECT-- +200 +===DONE=== diff --git a/tests/manager/manager-ctor-duplicate-option-004.phpt b/tests/manager/manager-ctor-duplicate-option-004.phpt new file mode 100644 index 000000000..61d6eb525 --- /dev/null +++ b/tests/manager/manager-ctor-duplicate-option-004.phpt @@ -0,0 +1,21 @@ +--TEST-- +MongoDB\Driver\Manager::__construct() with duplicate read preference tags +--FILE-- + 'secondary', 'readPreferenceTags' => [['dc' => 'ny']], 'readpreferencetags' => [['dc' => 'ca']]]); + +var_dump($manager->getReadPreference()->getTagSets()); + +?> +===DONE=== + +--EXPECT-- +array(1) { + [0]=> + array(1) { + ["dc"]=> + string(2) "ca" + } +} +===DONE=== From 4fa3d850a51a0934b9aa57e59f78cd55cc306180 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Mon, 23 Sep 2019 16:02:15 +0200 Subject: [PATCH 3/3] PHPC-991: Override safe and slaveok options correctly --- php_phongo.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/php_phongo.c b/php_phongo.c index 7cabb497e..f3e102d2e 100644 --- a/php_phongo.c +++ b/php_phongo.c @@ -1769,6 +1769,7 @@ static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t* uri, bson_t* option bson_iter_t iter; mongoc_read_prefs_t* new_rp; const mongoc_read_prefs_t* old_rp; + bool ignore_slaveok = false; if (!(old_rp = mongoc_uri_get_read_prefs_t(uri))) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "mongoc_uri_t does not have a read preference"); @@ -1786,7 +1787,7 @@ static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t* uri, bson_t* option while (bson_iter_next(&iter)) { const char* key = bson_iter_key(&iter); - if (!strcasecmp(key, MONGOC_URI_SLAVEOK)) { + if (!ignore_slaveok && !strcasecmp(key, MONGOC_URI_SLAVEOK)) { if (!BSON_ITER_HOLDS_BOOL(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "boolean"); mongoc_read_prefs_destroy(new_rp); @@ -1827,6 +1828,8 @@ static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t* uri, bson_t* option return false; } + + ignore_slaveok = true; } if (!strcasecmp(key, MONGOC_URI_READPREFERENCETAGS)) { @@ -1938,6 +1941,7 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* option bson_iter_t iter; mongoc_write_concern_t* new_wc; const mongoc_write_concern_t* old_wc; + bool ignore_safe = false; if (!(old_wc = mongoc_uri_get_write_concern(uri))) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "mongoc_uri_t does not have a write concern"); @@ -1955,7 +1959,7 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* option while (bson_iter_next(&iter)) { const char* key = bson_iter_key(&iter); - if (!strcasecmp(key, MONGOC_URI_SAFE)) { + if (!ignore_safe && !strcasecmp(key, MONGOC_URI_SAFE)) { if (!BSON_ITER_HOLDS_BOOL(&iter)) { PHONGO_URI_INVALID_TYPE(iter, "boolean"); mongoc_write_concern_destroy(new_wc); @@ -2035,6 +2039,8 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* option return false; } + + ignore_safe = true; } }