Skip to content

Commit e38c21d

Browse files
committed
PHPC-741: Consistent exceptions for Decimal128 init methods
1 parent 7d3dadb commit e38c21d

7 files changed

+115
-20
lines changed

src/BSON/Decimal128.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,34 +46,39 @@ PHONGO_API zend_class_entry *php_phongo_decimal128_ce;
4646

4747
zend_object_handlers php_phongo_handler_decimal128;
4848

49-
/* Initialize the object from a string and return whether it was successful. */
50-
static bool php_phongo_decimal128_init(php_phongo_decimal128_t *intern, const char *value)
49+
/* Initialize the object and return whether it was successful. An exception will
50+
* be thrown on error. */
51+
static bool php_phongo_decimal128_init(php_phongo_decimal128_t *intern, const char *value TSRMLS_DC)
5152
{
52-
if (bson_decimal128_from_string(value, &intern->decimal)) {
53-
intern->initialized = true;
54-
55-
return true;
53+
if (!bson_decimal128_from_string(value, &intern->decimal)) {
54+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing decimal string: %s", value);
55+
return false;
5656
}
5757

58-
return false;
58+
intern->initialized = true;
59+
60+
return true;
5961
}
6062

61-
/* Initialize the object from a HashTable and return whether it was successful. */
62-
static bool php_phongo_decimal128_init_from_hash(php_phongo_decimal128_t *intern, HashTable *props)
63+
/* Initialize the object from a HashTable and return whether it was successful.
64+
* An exception will be thrown on error. */
65+
static bool php_phongo_decimal128_init_from_hash(php_phongo_decimal128_t *intern, HashTable *props TSRMLS_DC)
6366
{
6467
#if PHP_VERSION_ID >= 70000
6568
zval *dec;
6669

6770
if ((dec = zend_hash_str_find(props, "dec", sizeof("dec")-1)) && Z_TYPE_P(dec) == IS_STRING) {
68-
return php_phongo_decimal128_init(intern, Z_STRVAL_P(dec));
71+
return php_phongo_decimal128_init(intern, Z_STRVAL_P(dec) TSRMLS_CC);
6972
}
7073
#else
7174
zval **dec;
7275

7376
if (zend_hash_find(props, "dec", sizeof("dec"), (void**) &dec) == SUCCESS && Z_TYPE_PP(dec) == IS_STRING) {
74-
return php_phongo_decimal128_init(intern, Z_STRVAL_PP(dec));
77+
return php_phongo_decimal128_init(intern, Z_STRVAL_PP(dec) TSRMLS_CC);
7578
}
7679
#endif
80+
81+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s initialization requires \"dec\" string field", ZSTR_VAL(php_phongo_decimal128_ce->name));
7782
return false;
7883
}
7984

@@ -96,9 +101,7 @@ PHP_METHOD(Decimal128, __construct)
96101
}
97102
zend_restore_error_handling(&error_handling TSRMLS_CC);
98103

99-
if (!php_phongo_decimal128_init(intern, value)) {
100-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Error parsing decimal string: %s", value);
101-
}
104+
php_phongo_decimal128_init(intern, value TSRMLS_CC);
102105
}
103106
/* }}} */
104107

@@ -119,9 +122,7 @@ PHP_METHOD(Decimal128, __set_state)
119122
intern = Z_DECIMAL128_OBJ_P(return_value);
120123
props = Z_ARRVAL_P(array);
121124

122-
if (!php_phongo_decimal128_init_from_hash(intern, props)) {
123-
php_error(E_ERROR, "Invalid serialization data for Decimal128 object");
124-
}
125+
php_phongo_decimal128_init_from_hash(intern, props TSRMLS_CC);
125126
}
126127
/* }}} */
127128

@@ -158,9 +159,7 @@ PHP_METHOD(Decimal128, __wakeup)
158159
intern = Z_DECIMAL128_OBJ_P(getThis());
159160
props = zend_std_get_properties(getThis() TSRMLS_CC);
160161

161-
if (!php_phongo_decimal128_init_from_hash(intern, props)) {
162-
php_error(E_ERROR, "Invalid serialization data for Decimal128 object");
163-
}
162+
php_phongo_decimal128_init_from_hash(intern, props TSRMLS_CC);
164163
}
165164
/* }}} */
166165

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
MongoDB\BSON\Decimal128 unserialization requires "dec" string field
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+
unserialize('O:23:"MongoDB\BSON\Decimal128":1:{s:3:"dec";i:0;}');
11+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
12+
13+
?>
14+
===DONE===
15+
<?php exit(0); ?>
16+
--EXPECT--
17+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
18+
MongoDB\BSON\Decimal128 initialization requires "dec" string field
19+
===DONE===
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
MongoDB\BSON\Decimal128 unserialization requires valid decimal string
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+
unserialize('O:23:"MongoDB\BSON\Decimal128":1:{s:3:"dec";s:7:"INVALID";}');
11+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
12+
13+
?>
14+
===DONE===
15+
<?php exit(0); ?>
16+
--EXPECT--
17+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
18+
Error parsing decimal string: INVALID
19+
===DONE===
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
MongoDB\BSON\Decimal128::__set_state() requires "dec" string field
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+
MongoDB\BSON\Decimal128::__set_state(['dec' => 0]);
11+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
12+
13+
?>
14+
===DONE===
15+
<?php exit(0); ?>
16+
--EXPECT--
17+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
18+
MongoDB\BSON\Decimal128 initialization requires "dec" string field
19+
===DONE===
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
MongoDB\BSON\Decimal128::__set_state() requires valid decimal string
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+
MongoDB\BSON\Decimal128::__set_state(['dec' => 'INVALID']);
11+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
12+
13+
?>
14+
===DONE===
15+
<?php exit(0); ?>
16+
--EXPECT--
17+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
18+
Error parsing decimal string: INVALID
19+
===DONE===
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
MongoDB\BSON\Decimal128 requires valid decimal string
3+
--SKIPIF--
4+
<?php if (defined("HHVM_VERSION_ID")) exit("skip HHVM handles parameter parsing differently"); ?>
5+
<?php require __DIR__ . '/../utils/basic-skipif.inc'?>
6+
--FILE--
7+
<?php
8+
require_once __DIR__ . '/../utils/basic.inc';
9+
10+
echo throws(function() {
11+
new MongoDB\BSON\Decimal128([]);
12+
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n";
13+
14+
?>
15+
===DONE===
16+
<?php exit(0); ?>
17+
--EXPECT--
18+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
19+
MongoDB\BSON\Decimal128::__construct() expects parameter 1 to be string, array given
20+
===DONE===

0 commit comments

Comments
 (0)