Skip to content

Commit 98a7aba

Browse files
committed
PHPC-1216: Always validate and apply wtimeoutMS in URI options array
1 parent e273c2e commit 98a7aba

File tree

5 files changed

+45
-19
lines changed

5 files changed

+45
-19
lines changed

php_phongo.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,7 +1788,6 @@ static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t* uri, bson_t* option
17881788
static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* options TSRMLS_DC) /* {{{ */
17891789
{
17901790
bson_iter_t iter;
1791-
int32_t wtimeoutms;
17921791
mongoc_write_concern_t* new_wc;
17931792
const mongoc_write_concern_t* old_wc;
17941793

@@ -1811,8 +1810,6 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* option
18111810
return true;
18121811
}
18131812

1814-
wtimeoutms = mongoc_write_concern_get_wtimeout(old_wc);
1815-
18161813
new_wc = mongoc_write_concern_copy(old_wc);
18171814

18181815
if (bson_iter_init_find_case(&iter, options, MONGOC_URI_SAFE)) {
@@ -1827,14 +1824,25 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* option
18271824
}
18281825

18291826
if (bson_iter_init_find_case(&iter, options, MONGOC_URI_WTIMEOUTMS)) {
1827+
int32_t wtimeout;
1828+
18301829
if (!BSON_ITER_HOLDS_INT32(&iter)) {
18311830
PHONGO_URI_INVALID_TYPE(iter, "32-bit integer");
18321831
mongoc_write_concern_destroy(new_wc);
18331832

18341833
return false;
18351834
}
18361835

1837-
wtimeoutms = bson_iter_int32(&iter);
1836+
wtimeout = bson_iter_int32(&iter);
1837+
1838+
if (wtimeout < 0) {
1839+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected wtimeoutMS to be >= 0, %d given", wtimeout);
1840+
mongoc_write_concern_destroy(new_wc);
1841+
1842+
return false;
1843+
}
1844+
1845+
mongoc_write_concern_set_wtimeout(new_wc, wtimeout);
18381846
}
18391847

18401848
if (bson_iter_init_find_case(&iter, options, MONGOC_URI_JOURNAL)) {
@@ -1872,7 +1880,8 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* option
18721880
const char* str = bson_iter_utf8(&iter, NULL);
18731881

18741882
if (0 == strcasecmp(PHONGO_WRITE_CONCERN_W_MAJORITY, str)) {
1875-
mongoc_write_concern_set_wmajority(new_wc, wtimeoutms);
1883+
/* wtimeoutMS is set independently, so preserve its value here */
1884+
mongoc_write_concern_set_wmajority(new_wc, mongoc_write_concern_get_wtimeout(new_wc));
18761885
} else {
18771886
mongoc_write_concern_set_wtag(new_wc, str);
18781887
}
@@ -1884,15 +1893,6 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* option
18841893
}
18851894
}
18861895

1887-
/* Only set wtimeout if it's still applicable; otherwise, clear it. */
1888-
if (mongoc_write_concern_get_w(new_wc) > 1 ||
1889-
mongoc_write_concern_get_wmajority(new_wc) ||
1890-
mongoc_write_concern_get_wtag(new_wc)) {
1891-
mongoc_write_concern_set_wtimeout(new_wc, wtimeoutms);
1892-
} else {
1893-
mongoc_write_concern_set_wtimeout(new_wc, 0);
1894-
}
1895-
18961896
if (mongoc_write_concern_get_journal(new_wc)) {
18971897
int32_t w = mongoc_write_concern_get_w(new_wc);
18981898

tests/manager/manager-ctor-write_concern-002.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ MongoDB\Driver\Manager::__construct(): write concern options (wtimeoutms)
44
<?php
55

66
$tests = [
7-
// wtimeoutms does not get applied unless w > 1, w = majority, or tag sets are used
87
['mongodb://127.0.0.1/?wtimeoutms=1000', []],
98
['mongodb://127.0.0.1/?w=2&wtimeoutms=1000', []],
109
['mongodb://127.0.0.1/?w=majority&wtimeoutms=1000', []],
@@ -27,6 +26,8 @@ foreach ($tests as $test) {
2726
<?php exit(0); ?>
2827
--EXPECTF--
2928
object(MongoDB\Driver\WriteConcern)#%d (%d) {
29+
["wtimeout"]=>
30+
int(1000)
3031
}
3132
object(MongoDB\Driver\WriteConcern)#%d (%d) {
3233
["w"]=>
@@ -47,6 +48,8 @@ object(MongoDB\Driver\WriteConcern)#%d (%d) {
4748
int(1000)
4849
}
4950
object(MongoDB\Driver\WriteConcern)#%d (%d) {
51+
["wtimeout"]=>
52+
int(1000)
5053
}
5154
object(MongoDB\Driver\WriteConcern)#%d (%d) {
5255
["w"]=>

tests/manager/manager-ctor-write_concern-error-004.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
--TEST--
2-
MongoDB\Driver\Manager::__construct(): invalid write concern (wtimeoutms range)
2+
MongoDB\Driver\Manager::__construct(): invalid write concern (wtimeoutms range exceeds INT32_MAX)
33
--SKIPIF--
44
<?php if (8 !== PHP_INT_SIZE) { die('skip Only for 64-bit platform'); } ?>
55
--FILE--
66
<?php
77

88
require_once __DIR__ . '/../utils/tools.php';
99

10-
/* Note: libmongoc does not check wTimeoutMS's range in the URI string. 64-bit
11-
* integers will be truncated by strtol() */
10+
/* Note: libmongoc does not check wTimeoutMS's upper bounds in the URI string.
11+
* 64-bit integers will be truncated by strtol(). */
1212

1313
echo throws(function() {
1414
new MongoDB\Driver\Manager(null, ['wTimeoutMS' => 2147483648]);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
MongoDB\Driver\Manager::__construct(): invalid write concern (wtimeoutms range)
3+
--SKIPIF--
4+
<?php if (8 !== PHP_INT_SIZE) { die('skip Only for 64-bit platform'); } ?>
5+
--FILE--
6+
<?php
7+
8+
require_once __DIR__ . '/../utils/tools.php';
9+
10+
echo throws(function() {
11+
new MongoDB\Driver\Manager(null, ['wTimeoutMS' => -1]);
12+
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
13+
14+
?>
15+
===DONE===
16+
<?php exit(0); ?>
17+
--EXPECT--
18+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
19+
Expected wtimeoutMS to be >= 0, -1 given
20+
===DONE===

tests/manager/manager-getwriteconcern-001.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ $tests = array(
1010
array(null, array('w' => 1, 'journal' => true)),
1111
array(null, array('w' => 'majority', 'journal' => true)),
1212
array('mongodb://127.0.0.1/?w=majority&journal=true', array('w' => 1, 'journal' => false)),
13-
// wtimeoutms does not get applied unless w > 1, w = majority, or tag sets are used
1413
array('mongodb://127.0.0.1/?wtimeoutms=1000', array()),
1514
array(null, array('wtimeoutms' => 1000)),
1615
array('mongodb://127.0.0.1/?w=2', array('wtimeoutms' => 1000)),
@@ -61,8 +60,12 @@ object(MongoDB\Driver\WriteConcern)#%d (%d) {
6160
bool(false)
6261
}
6362
object(MongoDB\Driver\WriteConcern)#%d (%d) {
63+
["wtimeout"]=>
64+
int(1000)
6465
}
6566
object(MongoDB\Driver\WriteConcern)#%d (%d) {
67+
["wtimeout"]=>
68+
int(1000)
6669
}
6770
object(MongoDB\Driver\WriteConcern)#%d (%d) {
6871
["w"]=>

0 commit comments

Comments
 (0)