-
Notifications
You must be signed in to change notification settings - Fork 208
PHPC-788: Timestamp on 32-bit platforms breaks #435
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
@@ -54,7 +54,7 @@ zend_object_handlers php_phongo_handler_timestamp; | |||
|
|||
/* Initialize the object and return whether it was successful. An exception will | |||
* be thrown on error. */ | |||
static bool php_phongo_timestamp_init(php_phongo_timestamp_t *intern, phongo_long increment, phongo_long timestamp TSRMLS_DC) | |||
static bool php_phongo_timestamp_init(php_phongo_timestamp_t *intern, int64_t increment, int64_t timestamp TSRMLS_DC) |
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 needs to be int64_t, as that's what the original arguments that were passed in here are as well. phongo_long is also not 64-bit on 32-bit platforms, and hence the comparison with UINT32_MIN would fail for some values.
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.
I assume you mean the < 0
comparisons would fail?
Since php_phongo_timestamp_init_from_string()
was always parsing the strings into int64_t
values, I suppose there was possible degredation there. The other code path is php_phongo_timestamp_init_from_hash()
picking up IS_LONG
values. In that case, would a negative int32_t
value expand to a negative int64_t
value (essentially the sign bit relocates) and still yield an exception?
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.
Yes, the < 0
would fail. And a sign bit doesn't change when you cast.
s_increment_len = snprintf(s_increment, sizeof(s_increment), "%" PRId64, intern->increment); | ||
s_timestamp_len = snprintf(s_timestamp, sizeof(s_timestamp), "%" PRId64, intern->timestamp); | ||
s_increment_len = snprintf(s_increment, sizeof(s_increment), "%" PRIu32, intern->increment); | ||
s_timestamp_len = snprintf(s_timestamp, sizeof(s_timestamp), "%" PRIu32, intern->timestamp); |
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 value in "increment" and "timestamp" is 32bit unsigned, so using a 64bit formatting would add a random 32bit value to the start of each formatted string, resulting in test failures.
@@ -10,15 +10,15 @@ echo throws(function() { | |||
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; | |||
|
|||
echo throws(function() { | |||
MongoDB\BSON\Timestamp::__set_state(['increment' => -2147483648, 'timestamp' => 5678]); | |||
MongoDB\BSON\Timestamp::__set_state(['increment' => -2147483647, 'timestamp' => 5678]); |
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.
PHP's parser parses "-" and "2147483648" separately. And as "2147483648" is over the int-32 limit, it gets converted to a double. -2147483647 is therefore the highest 32bit number PHP itself can represent.
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.
In that case, this isn't really testing a boundary condition, is it? I was testing -2147483648
because it should have been equal to 4294967295
in unsigned form.
I'd be OK with remove these test cases unless you really want to keep them.
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.
It's still a boundary check. Just one for PHP. I'll just keep it.
["x"]=> | ||
string(10) "4294967294" | ||
} | ||
|
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 test had missing output sections, and the warning formatting was wrong too. This test was always broken.
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.
LGTM with some questions and possible test changes.
@@ -54,7 +54,7 @@ zend_object_handlers php_phongo_handler_timestamp; | |||
|
|||
/* Initialize the object and return whether it was successful. An exception will | |||
* be thrown on error. */ | |||
static bool php_phongo_timestamp_init(php_phongo_timestamp_t *intern, phongo_long increment, phongo_long timestamp TSRMLS_DC) | |||
static bool php_phongo_timestamp_init(php_phongo_timestamp_t *intern, int64_t increment, int64_t timestamp TSRMLS_DC) |
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.
I assume you mean the < 0
comparisons would fail?
Since php_phongo_timestamp_init_from_string()
was always parsing the strings into int64_t
values, I suppose there was possible degredation there. The other code path is php_phongo_timestamp_init_from_hash()
picking up IS_LONG
values. In that case, would a negative int32_t
value expand to a negative int64_t
value (essentially the sign bit relocates) and still yield an exception?
intern->increment = increment; | ||
intern->timestamp = timestamp; | ||
intern->increment = (uint32_t) increment; | ||
intern->timestamp = (uint32_t) timestamp; |
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.
Do we have to worry about endianness here?
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.
No.
@@ -10,15 +10,15 @@ echo throws(function() { | |||
}, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; | |||
|
|||
echo throws(function() { | |||
MongoDB\BSON\Timestamp::__set_state(['increment' => -2147483648, 'timestamp' => 5678]); | |||
MongoDB\BSON\Timestamp::__set_state(['increment' => -2147483647, 'timestamp' => 5678]); |
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.
In that case, this isn't really testing a boundary condition, is it? I was testing -2147483648
because it should have been equal to 4294967295
in unsigned form.
I'd be OK with remove these test cases unless you really want to keep them.
@@ -32,6 +32,7 @@ foreach ($tests as $json) { | |||
===DONE=== | |||
<?php exit(0); ?> | |||
--EXPECTF-- | |||
%a |
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.
What is being printed before the first test case? It may make more sense to simply enable and disable mongodb.debug=stderr
around the foreach
that executes all of the test cases, instead of having the INI setting on for the entire process. We really only want to check for the overflow warnings.
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 reading of /etc/issue and something.
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.
I'll make the debug=stderr changes, but the other PR will just remove them again...
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.
If you're going to clean this up in the other PR, don't worry about duplicating that work here.
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.
LGTM. mongodb.debug
will be cleaned up in #436.
829a08c
to
eb35da1
Compare
No description provided.