Skip to content

Commit 6ea53f1

Browse files
committed
Merge pull request #399
2 parents 53e7677 + 56d8b77 commit 6ea53f1

File tree

6 files changed

+106
-21
lines changed

6 files changed

+106
-21
lines changed

php_phongo.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,29 @@ void php_phongo_read_concern_to_zval(zval *retval, const mongoc_read_concern_t *
936936
}
937937
} /* }}} */
938938

939+
/* Checks if tags is valid to set on a mongoc_read_prefs_t. It may be null or an
940+
* array of one or more documents. */
941+
bool php_phongo_read_preference_tags_are_valid(const bson_t *tags) /* {{{ */
942+
{
943+
bson_iter_t iter;
944+
945+
if (bson_empty0(tags)) {
946+
return true;
947+
}
948+
949+
if (!bson_iter_init(&iter, tags)) {
950+
return false;
951+
}
952+
953+
while (bson_iter_next(&iter)) {
954+
if (!BSON_ITER_HOLDS_DOCUMENT(&iter) && !BSON_ITER_HOLDS_ARRAY(&iter)) {
955+
return false;
956+
}
957+
}
958+
959+
return true;
960+
} /* }}} */
961+
939962
void php_phongo_read_preference_to_zval(zval *retval, const mongoc_read_prefs_t *read_prefs) /* {{{ */
940963
{
941964
const bson_t *tags = mongoc_read_prefs_get_tags(read_prefs);
@@ -1143,9 +1166,21 @@ static bool php_phongo_apply_rp_options_to_uri(mongoc_uri_t *uri, bson_t *option
11431166

11441167
bson_iter_array(&iter, &len, &data);
11451168

1146-
if (bson_init_static(&tags, data, len)) {
1147-
mongoc_read_prefs_set_tags(new_rp, &tags);
1169+
if (!bson_init_static(&tags, data, len)) {
1170+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Could not initialize BSON structure for read preference tags");
1171+
mongoc_read_prefs_destroy(new_rp);
1172+
1173+
return false;
1174+
}
1175+
1176+
if (!php_phongo_read_preference_tags_are_valid(&tags)) {
1177+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference tags must be an array of zero or more documents");
1178+
mongoc_read_prefs_destroy(new_rp);
1179+
1180+
return false;
11481181
}
1182+
1183+
mongoc_read_prefs_set_tags(new_rp, &tags);
11491184
}
11501185

11511186
if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY &&

php_phongo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ const mongoc_write_concern_t* phongo_write_concern_from_zval (zval *zwrite_conc
129129

130130
php_phongo_server_description_type_t php_phongo_server_description_type(mongoc_server_description_t *sd);
131131

132+
bool php_phongo_read_preference_tags_are_valid(const bson_t *tags);
133+
132134
void php_phongo_server_to_zval(zval *retval, mongoc_server_description_t *sd);
133135
void php_phongo_read_concern_to_zval(zval *retval, const mongoc_read_concern_t *read_concern);
134136
void php_phongo_read_preference_to_zval(zval *retval, const mongoc_read_prefs_t *read_prefs);

src/MongoDB/ReadPreference.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ PHP_METHOD(ReadPreference, __construct)
5252
{
5353
php_phongo_readpreference_t *intern;
5454
zend_error_handling error_handling;
55-
long mode;
55+
phongo_long mode;
5656
zval *tagSets = NULL;
5757
SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used)
5858

@@ -74,22 +74,39 @@ PHP_METHOD(ReadPreference, __construct)
7474
case MONGOC_READ_SECONDARY_PREFERRED:
7575
case MONGOC_READ_NEAREST:
7676
intern->read_preference = mongoc_read_prefs_new(mode);
77+
break;
78+
default:
79+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid mode: %" PHONGO_LONG_FORMAT, mode);
80+
return;
81+
}
7782

83+
switch(ZEND_NUM_ARGS()) {
84+
case 2:
7885
if (tagSets) {
7986
bson_t *tags = bson_new();
8087

8188
phongo_zval_to_bson(tagSets, PHONGO_BSON_NONE, (bson_t *)tags, NULL TSRMLS_CC);
82-
mongoc_read_prefs_set_tags(intern->read_preference, tags);
83-
bson_destroy(tags);
84-
if (!mongoc_read_prefs_is_valid(intern->read_preference)) {
85-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid tagSets");
89+
90+
if (!php_phongo_read_preference_tags_are_valid(tags)) {
91+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "tagSets must be an array of zero or more documents");
92+
bson_destroy(tags);
93+
return;
94+
}
95+
96+
if (!bson_empty(tags) && mode == MONGOC_READ_PRIMARY) {
97+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "tagSets may not be used with primary mode");
98+
bson_destroy(tags);
8699
return;
87100
}
101+
102+
mongoc_read_prefs_set_tags(intern->read_preference, tags);
103+
bson_destroy(tags);
88104
}
89-
break;
90-
default:
91-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid mode: %ld", mode);
92-
return;
105+
}
106+
107+
if (!mongoc_read_prefs_is_valid(intern->read_preference)) {
108+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference is not valid");
109+
return;
93110
}
94111
}
95112
/* }}} */

tests/manager/manager-ctor_error-003.phpt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@ echo throws(function() {
1111
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
1212

1313
echo throws(function() {
14-
$manager = new MongoDB\Driver\Manager(STANDALONE, array('readPreference' => 'nothing'));
14+
$manager = new MongoDB\Driver\Manager(STANDALONE, ['readPreference' => 'nothing']);
1515
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
1616

1717
echo throws(function() {
18-
$manager = new MongoDB\Driver\Manager(STANDALONE . '/?readPreference=primary', array('readPreferenceTags' => array(array())));
18+
$manager = new MongoDB\Driver\Manager(STANDALONE . '/?readPreference=primary', ['readPreferenceTags' => [[]]]);
19+
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
20+
21+
echo throws(function() {
22+
$manager = new MongoDB\Driver\Manager(STANDALONE . '/?readPreference=primary', ['readPreferenceTags' => ['invalid']]);
1923
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
2024

2125
?>
@@ -28,4 +32,6 @@ OK: Got MongoDB\Driver\Exception\InvalidArgumentException
2832
Unsupported readPreference value: 'nothing'
2933
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
3034
Primary read preference mode conflicts with tags
35+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
36+
Read preference tags must be an array of zero or more documents
3137
===DONE===
Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
11
--TEST--
2-
MongoDB\Driver\ReadPreference construction (invalid arguments)
2+
MongoDB\Driver\ReadPreference construction (invalid mode)
33
--SKIPIF--
44
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
55
--FILE--
66
<?php
77
require_once __DIR__ . "/../utils/basic.inc";
88

9-
echo throws(function() {
10-
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY, array(array("tag" => "one")));
11-
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
12-
139
echo throws(function() {
1410
new MongoDB\Driver\ReadPreference(42);
1511
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
1612

1713
?>
1814
===DONE===
1915
<?php exit(0); ?>
20-
--EXPECTF--
21-
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
22-
Invalid tagSets
16+
--EXPECT--
2317
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
2418
Invalid mode: 42
2519
===DONE===
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
MongoDB\Driver\ReadPreference construction (invalid tagSets)
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
5+
--FILE--
6+
<?php
7+
require_once __DIR__ . "/../utils/basic.inc";
8+
9+
echo throws(function() {
10+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY, [['tag' => 'one']]);
11+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
12+
13+
echo throws(function() {
14+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY, ['invalid']);
15+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
16+
17+
echo throws(function() {
18+
new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY, ['invalid']);
19+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
20+
21+
?>
22+
===DONE===
23+
<?php exit(0); ?>
24+
--EXPECT--
25+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
26+
tagSets may not be used with primary mode
27+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
28+
tagSets must be an array of zero or more documents
29+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
30+
tagSets must be an array of zero or more documents
31+
===DONE===

0 commit comments

Comments
 (0)