summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerick Rethans <github@derickrethans.nl>2016-01-29 15:30:31 +0100
committerDerick Rethans <github@derickrethans.nl>2016-01-29 15:30:31 +0100
commit3523c0a45f51ca2321408e28890e830d902a9409 (patch)
tree1a539b3254f393c9bf53ac04a07eae85a4a45e83
parentd2c752d7e9134c0db1045d3ee244c5d1ee4eaba9 (diff)
parent1a8682568834580b44c448f2e682c704eea626d4 (diff)
downloadphp-git-3523c0a45f51ca2321408e28890e830d902a9409.tar.gz
Merge branch 'PHP-5.6' into PHP-7.0
-rw-r--r--ext/date/lib/interval.c2
-rw-r--r--ext/date/lib/parse_date.re7
-rw-r--r--ext/date/lib/timelib.c17
-rw-r--r--ext/date/lib/timelib.h1
-rw-r--r--ext/date/php_date.c2
-rw-r--r--ext/date/tests/bug68078.phpt19
-rw-r--r--ext/date/tests/bug68078_negative.phpt19
7 files changed, 64 insertions, 3 deletions
diff --git a/ext/date/lib/interval.c b/ext/date/lib/interval.c
index 6a3403fc3e..9c1cc3b273 100644
--- a/ext/date/lib/interval.c
+++ b/ext/date/lib/interval.c
@@ -70,7 +70,7 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
rt->i += dst_m_corr;
}
- rt->days = abs(floor((one->sse - two->sse - (dst_h_corr * 3600) - (dst_m_corr * 60)) / 86400));
+ rt->days = fabs(floor((one->sse - two->sse - (dst_h_corr * 3600) - (dst_m_corr * 60)) / 86400));
timelib_do_rel_normalize(rt->invert ? one : two, rt);
diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re
index 3ff00bec3e..3d4cf6bb61 100644
--- a/ext/date/lib/parse_date.re
+++ b/ext/date/lib/parse_date.re
@@ -1812,6 +1812,11 @@ timelib_time* timelib_strtotime(char *s, size_t len, struct timelib_error_contai
{ \
add_pbf_error(s, "Unexpected data found.", string, begin); \
}
+#define TIMELIB_CHECK_SIGNED_NUMBER \
+ if (strchr("-0123456789", *ptr) == NULL) \
+ { \
+ add_pbf_error(s, "Unexpected data found.", string, begin); \
+ }
static void timelib_time_reset_fields(timelib_time *time)
{
@@ -2016,7 +2021,7 @@ timelib_time *timelib_parse_from_format(char *format, char *string, size_t len,
timelib_eat_spaces((char **) &ptr);
break;
case 'U': /* epoch seconds */
- TIMELIB_CHECK_NUMBER;
+ TIMELIB_CHECK_SIGNED_NUMBER;
TIMELIB_HAVE_RELATIVE();
tmp = timelib_get_unsigned_nr((char **) &ptr, 24);
s->time->y = 1970;
diff --git a/ext/date/lib/timelib.c b/ext/date/lib/timelib.c
index 73cdfa2d85..b938d9f998 100644
--- a/ext/date/lib/timelib.c
+++ b/ext/date/lib/timelib.c
@@ -65,6 +65,23 @@ timelib_time* timelib_time_clone(timelib_time *orig)
return tmp;
}
+int timelib_time_compare(timelib_time *t1, timelib_time *t2)
+{
+ if (t1->sse == t2->sse) {
+ if (t1->f == t2->f) {
+ return 0;
+ }
+
+ if (t1->sse < 0) {
+ return (t1->f < t2->f) ? 1 : -1;
+ } else {
+ return (t1->f < t2->f) ? -1 : 1;
+ }
+ }
+
+ return (t1->sse < t2->sse) ? -1 : 1;
+}
+
timelib_rel_time* timelib_rel_time_clone(timelib_rel_time *rel)
{
timelib_rel_time *tmp = timelib_rel_time_ctor();
diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h
index 125b8b21ad..fe1069bdde 100644
--- a/ext/date/lib/timelib.h
+++ b/ext/date/lib/timelib.h
@@ -138,6 +138,7 @@ timelib_time* timelib_time_ctor(void);
void timelib_time_set_option(timelib_time* tm, int option, void* option_value);
void timelib_time_dtor(timelib_time* t);
timelib_time* timelib_time_clone(timelib_time* orig);
+int timelib_time_compare(timelib_time *t1, timelib_time *t2);
timelib_time_offset* timelib_time_offset_ctor(void);
void timelib_time_offset_dtor(timelib_time_offset* t);
diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index ec1cabc34d..2c548ae6f4 100644
--- a/ext/date/php_date.c
+++ b/ext/date/php_date.c
@@ -2142,7 +2142,7 @@ static int date_object_compare_date(zval *d1, zval *d2) /* {{{ */
timelib_update_ts(o2->time, o2->time->tz_info);
}
- return (o1->time->sse == o2->time->sse) ? 0 : ((o1->time->sse < o2->time->sse) ? -1 : 1);
+ return timelib_time_compare(o1->time, o2->time);
} /* }}} */
static HashTable *date_object_get_gc(zval *object, zval **table, int *n) /* {{{ */
diff --git a/ext/date/tests/bug68078.phpt b/ext/date/tests/bug68078.phpt
new file mode 100644
index 0000000000..20be0a49c8
--- /dev/null
+++ b/ext/date/tests/bug68078.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Comparing datetime objects should account for microseconds
+--FILE--
+<?php
+
+date_default_timezone_set('UTC');
+$date1 = DateTime::createFromFormat('U.u', '1448889063.3531');
+$date2 = DateTime::createFromFormat('U.u', '1448889063.5216');
+$date3 = DateTime::createFromFormat('U.u', '1448889063.5216');
+
+var_dump($date1 == $date2);
+var_dump($date1 < $date2);
+var_dump($date2 > $date1);
+var_dump($date2 == $date3);
+--EXPECT--
+bool(false)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/date/tests/bug68078_negative.phpt b/ext/date/tests/bug68078_negative.phpt
new file mode 100644
index 0000000000..93b7715fe5
--- /dev/null
+++ b/ext/date/tests/bug68078_negative.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Comparing datetime objects with negative timestamps should account for microseconds
+--FILE--
+<?php
+
+date_default_timezone_set('UTC');
+$earlyDate1 = DateTime::createFromFormat('U.u', '1.8642')->modify('-5 seconds');
+$earlyDate2 = DateTime::createFromFormat('U.u', '1.2768')->modify('-5 seconds');
+$earlyDate3 = DateTime::createFromFormat('U.u', '1.2768')->modify('-5 seconds');
+
+var_dump($earlyDate1 == $earlyDate2);
+var_dump($earlyDate1 < $earlyDate2);
+var_dump($earlyDate2 > $earlyDate1);
+var_dump($earlyDate2 == $earlyDate3);
+--EXPECT--
+bool(false)
+bool(true)
+bool(true)
+bool(true)