-
Notifications
You must be signed in to change notification settings - Fork 209
PHPC-741: Consistent exceptions for BSON init methods #346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
8f48b84
to
54accba
Compare
* Note: bson_ascii_strtoll() does not properly detect out-of-range values | ||
* (see: CDRIVER-1377). strtoll() would be preferable, but it is not | ||
* available on all platforms (e.g. HP-UX), and atoll() provides no error | ||
* reporting at all. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original STRTOLL()
macro we had uses three possible functions:
_atoi64()
on Windows, which supports error reporting (may not detect extra data)atoll()
ifHAVE_ATOLL
is defined, which doesn't support error reporting at allstrtoll()
otherwise, which supports error reporting andendptr
for detecting extra data
Support for atoll()
appears to be a concession for HP-UX's broken strtoll()
implementation (see: PHP bug #33433). If we care about HP-UX portability, I suggest we use bson_ascii_strtoll()
, which is a strtoll()
polyfill in libbson. It does have an issue with detecting out-of-range integers (see: CDRIVER-1377), but I think this is an improvement over the current use of atoll()
and reporting no errors at all.
58d6af9
to
af575c8
Compare
{ | ||
if (type < 0 || type > UINT8_MAX) { | ||
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected type to be an unsigned 8-bit integer, %" PHONGO_LONG_FORMAT " given", type); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message was previously only used in the constructor; however, the exception may now be thrown from __set_state()
or unserialize()
. What do you think about putting the class name in the message?
I've started doing this with other new messages (e.g. Javascript now allowing null bytes in its code argument) for added clarity, but did not want to change existing messages before discussing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, my main concern was with unserialize()
, as I expected that would be the only function in the stack trace. After further testing, it appears that the appropriate __wakeup()
method is included in the backtrace as "[internal function]". I tested this by unserializing a Javascript object with an invalid Regex in its scope document, just to see how nesting is handled.
<?php
unserialize('O:23:"MongoDB\BSON\Javascript":2:{s:4:"code";s:33:"function foo(bar) { return bar; }";s:5:"scope";O:8:"stdClass":1:{s:1:"r";O:18:"MongoDB\BSON\Regex":2:{s:7:"pattern";s:6:"regexp";s:5:"flags";s:1:"'. "\0" .'";}}}');
Output:
Fatal error: Uncaught exception 'MongoDB\Driver\Exception\InvalidArgumentException' with message 'MongoDB\BSON\Regex flags should not contain null bytes' in tests/bson/bson-regex-serialization_error-002.php:15
Stack trace:
#0 [internal function]: MongoDB\BSON\Regex->__wakeup()
#1 tests/bson/bson-regex-serialization_error-002.php(15): unserialize('O:23:"MongoDB\\B...')
#2 {main}
thrown in tests/bson/bson-regex-serialization_error-002.php on line 15
Given this behavior, I think we're OK with not having the class name in every message.
@@ -75,28 +77,33 @@ static bool php_phongo_objectid_init_from_hex_string(php_phongo_objectid_t *inte | |||
return true; | |||
} | |||
|
|||
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid BSON ID provided"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the same error message used in HHVM (see: here), but I think there's room for improvement. We should at least show the offending value.
Let's discuss and create a new ticket if needed.
@@ -147,7 +136,7 @@ | |||
# define phongo_long long | |||
# define PHONGO_LONG_FORMAT "ld" | |||
# define SIZEOF_PHONGO_LONG SIZEOF_LONG | |||
# define phongo_str(str) str | |||
# define ZSTR_VAL(str) str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A number of the exception messages for PHPC-741 involved reporting zend_class_entry->name
. On PHP 7, this required accessing zend_string->val
. Digging a little deeper, I found that we were inconsistently using either the phongo_str()
macro or using #if
blocks to conditionally use ZSTR_VAL()
for PHP 7. Simply backporting ZSTR_VAL()
to PHP 5.x allowed me to remove our custom macro and delete those #if
blocks.
LGTM |
Even though "code" is not a cstring in the BSON spec, libbson does not support null bytes. Throw early to avoid unexpected truncation during BSON encoding.
These fields are cstrings in the BSON spec, so any null bytes would result in unexpected truncation.
https://jira.mongodb.org/browse/PHPC-741
Due to overlap, I've also included the PRs for disallowing null bytes in Javascript's code and Regex's pattern and flags fields: