Skip to content

Commit 994a1da

Browse files
committed
PHPC-654: Binary comparison handler
1 parent 9466683 commit 994a1da

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

src/BSON/Binary.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <ext/standard/base64.h>
3636
#include <ext/standard/info.h>
3737
#include <Zend/zend_interfaces.h>
38+
#include <Zend/zend_operators.h>
3839
#include <ext/spl/spl_iterators.h>
3940
#include <ext/standard/php_var.h>
4041
#if PHP_VERSION_ID >= 70000
@@ -387,6 +388,26 @@ phongo_create_object_retval php_phongo_binary_create_object(zend_class_entry *cl
387388
#endif
388389
} /* }}} */
389390

391+
static int php_phongo_binary_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
392+
{
393+
php_phongo_binary_t *intern1, *intern2;
394+
395+
intern1 = Z_BINARY_OBJ_P(o1);
396+
intern2 = Z_BINARY_OBJ_P(o2);
397+
398+
/* MongoDB compares binary types first by the data length, then by the type
399+
* byte, and finally by the binary data itself. */
400+
if (intern1->data_len != intern2->data_len) {
401+
return intern1->data_len < intern2->data_len ? -1 : 1;
402+
}
403+
404+
if (intern1->type != intern2->type) {
405+
return intern1->type < intern2->type ? -1 : 1;
406+
}
407+
408+
return zend_binary_strcmp(intern1->data, intern1->data_len, intern2->data, intern2->data_len);
409+
} /* }}} */
410+
390411
HashTable *php_phongo_binary_get_properties(zval *object TSRMLS_DC) /* {{{ */
391412
{
392413
php_phongo_binary_t *intern;
@@ -443,6 +464,7 @@ PHP_MINIT_FUNCTION(Binary)
443464
zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, zend_ce_serializable);
444465

445466
memcpy(&php_phongo_handler_binary, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
467+
php_phongo_handler_binary.compare_objects = php_phongo_binary_compare_objects;
446468
php_phongo_handler_binary.get_properties = php_phongo_binary_get_properties;
447469
#if PHP_VERSION_ID >= 70000
448470
php_phongo_handler_binary.free_obj = php_phongo_binary_free_object;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
MongoDB\BSON\Binary comparisons
3+
--FILE--
4+
<?php
5+
6+
var_dump(new MongoDB\BSON\Binary('foobar', 1) == new MongoDB\BSON\Binary('foobar', 1));
7+
var_dump(new MongoDB\BSON\Binary('foobar', 1) < new MongoDB\BSON\Binary('foobar', 1));
8+
var_dump(new MongoDB\BSON\Binary('foobar', 1) > new MongoDB\BSON\Binary('foobar', 1));
9+
10+
// Data length is compared first
11+
var_dump(new MongoDB\BSON\Binary('c', 1) < new MongoDB\BSON\Binary('aa', 0));
12+
var_dump(new MongoDB\BSON\Binary('bb', 0) > new MongoDB\BSON\Binary('a', 1));
13+
14+
// Type is compared second
15+
var_dump(new MongoDB\BSON\Binary('foobar', 1) < new MongoDB\BSON\Binary('foobar', 2));
16+
var_dump(new MongoDB\BSON\Binary('foobar', 1) > new MongoDB\BSON\Binary('foobar', 0));
17+
18+
// Data is compared last
19+
var_dump(new MongoDB\BSON\Binary('foobar', 1) < new MongoDB\BSON\Binary('foobat', 1));
20+
var_dump(new MongoDB\BSON\Binary('foobar', 1) > new MongoDB\BSON\Binary('foobap', 1));
21+
22+
?>
23+
===DONE===
24+
<?php exit(0); ?>
25+
--EXPECTF--
26+
bool(true)
27+
bool(false)
28+
bool(false)
29+
bool(true)
30+
bool(true)
31+
bool(true)
32+
bool(true)
33+
bool(true)
34+
bool(true)
35+
===DONE===
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
MongoDB\BSON\Binary comparisons with null bytes
3+
--FILE--
4+
<?php
5+
6+
var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) == new MongoDB\BSON\Binary("foo\x00bar", 1));
7+
var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) < new MongoDB\BSON\Binary("foo\x00bar", 1));
8+
var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) > new MongoDB\BSON\Binary("foo\x00bar", 1));
9+
10+
// Data length is compared first
11+
var_dump(new MongoDB\BSON\Binary("c\x00", 1) < new MongoDB\BSON\Binary("a\x00a", 0));
12+
var_dump(new MongoDB\BSON\Binary("b\x00b", 0) > new MongoDB\BSON\Binary("a\x00", 1));
13+
14+
// Type is compared second
15+
var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) < new MongoDB\BSON\Binary("foo\x00bar", 2));
16+
var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) > new MongoDB\BSON\Binary("foo\x00bar", 0));
17+
18+
// Data is compared last
19+
var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) < new MongoDB\BSON\Binary("foo\x00bat", 1));
20+
var_dump(new MongoDB\BSON\Binary("foo\x00bar", 1) > new MongoDB\BSON\Binary("foo\x00bap", 1));
21+
22+
?>
23+
===DONE===
24+
<?php exit(0); ?>
25+
--EXPECTF--
26+
bool(true)
27+
bool(false)
28+
bool(false)
29+
bool(true)
30+
bool(true)
31+
bool(true)
32+
bool(true)
33+
bool(true)
34+
bool(true)
35+
===DONE===

0 commit comments

Comments
 (0)