Skip to content

Conversation

jmikola
Copy link
Member

@jmikola jmikola commented Jul 13, 2016

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:

@jmikola jmikola force-pushed the phpc-741 branch 3 times, most recently from 8f48b84 to 54accba Compare July 13, 2016 17:40
@jmikola jmikola changed the title [WIP] PHPC-741: Consistent exceptions for BSON init methods PHPC-741: Consistent exceptions for BSON init methods Jul 13, 2016
* 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. */
Copy link
Member Author

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() if HAVE_ATOLL is defined, which doesn't support error reporting at all
  • strtoll() otherwise, which supports error reporting and endptr 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.

@jmikola jmikola force-pushed the phpc-741 branch 2 times, most recently from 58d6af9 to af575c8 Compare July 14, 2016 03:09
{
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);
Copy link
Member Author

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.

Copy link
Member Author

@jmikola jmikola Jul 14, 2016

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");
Copy link
Member Author

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
Copy link
Member Author

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.

@derickr
Copy link
Contributor

derickr commented Jul 14, 2016

LGTM

@jmikola jmikola merged commit 66822bf into mongodb:master Jul 14, 2016
jmikola added a commit that referenced this pull request Jul 14, 2016
@jmikola jmikola deleted the phpc-741 branch July 14, 2016 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants