Skip to content

Commit c343384

Browse files
committed
Merge pull request #471
2 parents 850d8ce + 8b173d9 commit c343384

17 files changed

+354
-28
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;

src/BSON/Javascript.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,17 @@ phongo_create_object_retval php_phongo_javascript_create_object(zend_class_entry
439439
#endif
440440
} /* }}} */
441441

442+
static int php_phongo_javascript_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
443+
{
444+
php_phongo_javascript_t *intern1, *intern2;
445+
446+
intern1 = Z_JAVASCRIPT_OBJ_P(o1);
447+
intern2 = Z_JAVASCRIPT_OBJ_P(o2);
448+
449+
/* Do not consider the scope document for comparisons */
450+
return strcmp(intern1->code, intern2->code);
451+
} /* }}} */
452+
442453
HashTable *php_phongo_javascript_get_properties(zval *object TSRMLS_DC) /* {{{ */
443454
{
444455
php_phongo_javascript_t *intern;
@@ -533,6 +544,7 @@ PHP_MINIT_FUNCTION(Javascript)
533544
zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, zend_ce_serializable);
534545

535546
memcpy(&php_phongo_handler_javascript, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
547+
php_phongo_handler_javascript.compare_objects = php_phongo_javascript_compare_objects;
536548
php_phongo_handler_javascript.get_properties = php_phongo_javascript_get_properties;
537549
#if PHP_VERSION_ID >= 70000
538550
php_phongo_handler_javascript.free_obj = php_phongo_javascript_free_object;

src/BSON/Regex.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -402,25 +402,22 @@ phongo_create_object_retval php_phongo_regex_create_object(zend_class_entry *cla
402402
#endif
403403
} /* }}} */
404404

405-
HashTable *php_phongo_regex_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
405+
static int php_phongo_regex_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
406406
{
407-
php_phongo_regex_t *intern;
408-
#if PHP_VERSION_ID >= 70000
409-
zval retval;
410-
#else
411-
zval retval = zval_used_for_init;
412-
#endif
413-
407+
php_phongo_regex_t *intern1, *intern2;
408+
int retval;
414409

415-
*is_temp = 1;
416-
intern = Z_REGEX_OBJ_P(object);
410+
intern1 = Z_REGEX_OBJ_P(o1);
411+
intern2 = Z_REGEX_OBJ_P(o2);
417412

418-
array_init(&retval);
413+
/* MongoDB compares the pattern string before the flags. */
414+
retval = strcmp(intern1->pattern, intern2->pattern);
419415

420-
ADD_ASSOC_STRINGL(&retval, "pattern", intern->pattern, intern->pattern_len);
421-
ADD_ASSOC_STRINGL(&retval, "flags", intern->flags, intern->flags_len);
416+
if (retval != 0) {
417+
return retval;
418+
}
422419

423-
return Z_ARRVAL(retval);
420+
return strcmp(intern1->flags, intern2->flags);
424421
} /* }}} */
425422

426423
HashTable *php_phongo_regex_get_properties(zval *object TSRMLS_DC) /* {{{ */
@@ -479,6 +476,7 @@ PHP_MINIT_FUNCTION(Regex)
479476
zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_json_serializable_ce);
480477

481478
memcpy(&php_phongo_handler_regex, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
479+
php_phongo_handler_regex.compare_objects = php_phongo_regex_compare_objects;
482480
php_phongo_handler_regex.get_properties = php_phongo_regex_get_properties;
483481
#if PHP_VERSION_ID >= 70000
484482
php_phongo_handler_regex.free_obj = php_phongo_regex_free_object;

src/BSON/Timestamp.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -427,25 +427,23 @@ phongo_create_object_retval php_phongo_timestamp_create_object(zend_class_entry
427427
#endif
428428
} /* }}} */
429429

430-
HashTable *php_phongo_timestamp_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
430+
static int php_phongo_timestamp_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
431431
{
432-
php_phongo_timestamp_t *intern;
433-
#if PHP_VERSION_ID >= 70000
434-
zval retval;
435-
#else
436-
zval retval = zval_used_for_init;
437-
#endif
432+
php_phongo_timestamp_t *intern1, *intern2;
438433

434+
intern1 = Z_TIMESTAMP_OBJ_P(o1);
435+
intern2 = Z_TIMESTAMP_OBJ_P(o2);
439436

440-
*is_temp = 1;
441-
intern = Z_TIMESTAMP_OBJ_P(object);
442-
443-
array_init(&retval);
437+
/* MongoDB compares the timestamp before the increment. */
438+
if (intern1->timestamp != intern2->timestamp) {
439+
return intern1->timestamp < intern2->timestamp ? -1 : 1;
440+
}
444441

445-
ADD_ASSOC_LONG_EX(&retval, "increment", intern->increment);
446-
ADD_ASSOC_LONG_EX(&retval, "timestamp", intern->timestamp);
442+
if (intern1->increment != intern2->increment) {
443+
return intern1->increment < intern2->increment ? -1 : 1;
444+
}
447445

448-
return Z_ARRVAL(retval);
446+
return 0;
449447
} /* }}} */
450448

451449
HashTable *php_phongo_timestamp_get_properties(zval *object TSRMLS_DC) /* {{{ */
@@ -511,6 +509,7 @@ PHP_MINIT_FUNCTION(Timestamp)
511509
zend_class_implements(php_phongo_timestamp_ce TSRMLS_CC, 1, zend_ce_serializable);
512510

513511
memcpy(&php_phongo_handler_timestamp, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
512+
php_phongo_handler_timestamp.compare_objects = php_phongo_timestamp_compare_objects;
514513
php_phongo_handler_timestamp.get_properties = php_phongo_timestamp_get_properties;
515514
#if PHP_VERSION_ID >= 70000
516515
php_phongo_handler_timestamp.free_obj = php_phongo_timestamp_free_object;

src/BSON/UTCDateTime.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,20 @@ phongo_create_object_retval php_phongo_utcdatetime_create_object(zend_class_entr
487487
#endif
488488
} /* }}} */
489489

490+
static int php_phongo_utcdatetime_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
491+
{
492+
php_phongo_utcdatetime_t *intern1, *intern2;
493+
494+
intern1 = Z_UTCDATETIME_OBJ_P(o1);
495+
intern2 = Z_UTCDATETIME_OBJ_P(o2);
496+
497+
if (intern1->milliseconds != intern2->milliseconds) {
498+
return intern1->milliseconds < intern2->milliseconds ? -1 : 1;
499+
}
500+
501+
return 0;
502+
} /* }}} */
503+
490504
HashTable *php_phongo_utcdatetime_get_properties(zval *object TSRMLS_DC) /* {{{ */
491505
{
492506
php_phongo_utcdatetime_t *intern;
@@ -540,6 +554,7 @@ PHP_MINIT_FUNCTION(UTCDateTime)
540554
zend_class_implements(php_phongo_utcdatetime_ce TSRMLS_CC, 1, zend_ce_serializable);
541555

542556
memcpy(&php_phongo_handler_utcdatetime, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
557+
php_phongo_handler_utcdatetime.compare_objects = php_phongo_utcdatetime_compare_objects;
543558
php_phongo_handler_utcdatetime.get_properties = php_phongo_utcdatetime_get_properties;
544559
#if PHP_VERSION_ID >= 70000
545560
php_phongo_handler_utcdatetime.free_obj = php_phongo_utcdatetime_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===
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
MongoDB\BSON\Javascript comparisons (without scope)
3+
--FILE--
4+
<?php
5+
6+
var_dump(new MongoDB\BSON\Javascript('function() { return 1; }') == new MongoDB\BSON\Javascript('function() { return 1; }'));
7+
var_dump(new MongoDB\BSON\Javascript('function() { return 1; }') < new MongoDB\BSON\Javascript('function() { return 2; }'));
8+
var_dump(new MongoDB\BSON\Javascript('function() { return 1; }') > new MongoDB\BSON\Javascript('function() { return 0; }'));
9+
10+
?>
11+
===DONE===
12+
<?php exit(0); ?>
13+
--EXPECTF--
14+
bool(true)
15+
bool(true)
16+
bool(true)
17+
===DONE===
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
MongoDB\BSON\Javascript comparisons (with scope)
3+
--FILE--
4+
<?php
5+
6+
// Comparison does not consider scope document
7+
var_dump(new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 1]) == new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 1]));
8+
var_dump(new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 1]) == new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 0]));
9+
var_dump(new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 1]) == new MongoDB\BSON\Javascript('function() { return 1; }', ['x' => 2]));
10+
11+
?>
12+
===DONE===
13+
<?php exit(0); ?>
14+
--EXPECTF--
15+
bool(true)
16+
bool(true)
17+
bool(true)
18+
===DONE===
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
MongoDB\BSON\MaxKey comparisons
3+
--FILE--
4+
<?php
5+
6+
var_dump(new MongoDB\BSON\MaxKey == new MongoDB\BSON\MaxKey);
7+
var_dump(new MongoDB\BSON\MaxKey < new MongoDB\BSON\MaxKey);
8+
var_dump(new MongoDB\BSON\MaxKey > new MongoDB\BSON\MaxKey);
9+
10+
?>
11+
===DONE===
12+
<?php exit(0); ?>
13+
--EXPECTF--
14+
bool(true)
15+
bool(false)
16+
bool(false)
17+
===DONE===

0 commit comments

Comments
 (0)