From: Derick Rethans Date: Wed, 10 Feb 2010 16:23:30 +0000 (+0000) Subject: - Added a test case for bug #45866 X-Git-Tag: php-5.2.13RC2~5 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=16b232737db7e2fb20c42b420400c4c522df7b16;p=php - Added a test case for bug #45866 - Fixed tests: oo_002, bug46268 - Fixed bug #50930 (Wrong date by php_date.c patch with ancient gcc/glibc versions). - Make sure faulty strings passed to DateTime::modify() notify the user. - Revert fix for bug #50392 as it was fixed wrongly without a proper test case. - Fixed a bug with the 'r' formatting function as the default buffer size that was allocated only fit 4 digit years. --- diff --git a/ext/date/config0.m4 b/ext/date/config0.m4 index 62a086bc08..cbd732f4ed 100644 --- a/ext/date/config0.m4 +++ b/ext/date/config0.m4 @@ -16,8 +16,6 @@ PHP_ADD_INCLUDE([$ext_srcdir/lib]) PHP_INSTALL_HEADERS([ext/date], [php_date.h lib/timelib.h lib/timelib_structs.h lib/timelib_config.h]) -AC_CHECK_FUNCS([llabs]) - cat > $ext_builddir/lib/timelib_config.h < -#ifndef HAVE_LLABS -# ifdef PHP_WIN32 -static __inline __int64 llabs( __int64 i ) { return i >= 0? i: -i; } -# elif defined(__GNUC__) && __GNUC__ < 3 -static __inline __int64_t llabs( __int64_t i ) { return i >= 0 ? i : -i; } -# elif defined(NETWARE) && defined(__MWERKS__) -static __inline long long llabs( long long i ) { return i >= 0 ? i : -i; } -# endif +#ifdef PHP_WIN32 +# include "win32/php_stdint.h" #endif +static __inline long long php_date_llabs( long long i ) { return i >= 0 ? i : -i; } + /* {{{ arginfo */ static ZEND_BEGIN_ARG_INFO_EX(arginfo_date, 0, 0, 1) @@ -752,7 +748,7 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca { smart_str string = {0}; int i, length; - char buffer[33]; + char buffer[97]; timelib_time_offset *offset = NULL; timelib_sll isoweek, isoyear; int rfc_colon; @@ -811,7 +807,7 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca /* year */ case 'L': length = slprintf(buffer, 32, "%d", timelib_is_leap((int) t->y)); break; case 'y': length = slprintf(buffer, 32, "%02d", (int) t->y % 100); break; - case 'Y': length = slprintf(buffer, 32, "%s%04lld", t->y < 0 ? "-" : "", llabs(t->y)); break; + case 'Y': length = slprintf(buffer, 32, "%s%04lld", t->y < 0 ? "-" : "", php_date_llabs((timelib_sll) t->y)); break; /* time */ case 'a': length = slprintf(buffer, 32, "%s", t->h >= 12 ? "pm" : "am"); break; @@ -875,7 +871,7 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca localtime ? abs((offset->offset % 3600) / 60) : 0 ); break; - case 'r': length = slprintf(buffer, 32, "%3s, %02d %3s %04d %02d:%02d:%02d %c%02d%02d", + case 'r': length = slprintf(buffer, 96, "%3s, %02d %3s %04d %02d:%02d:%02d %c%02d%02d", php_date_short_day_name(t->y, t->m, t->d), (int) t->d, mon_short_names[t->m - 1], (int) t->y, (int) t->h, (int) t->i, (int) t->s, @@ -1936,6 +1932,7 @@ PHP_FUNCTION(date_modify) char *modify; int modify_len; timelib_time *tmp_time; + timelib_error_container *err = NULL; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &modify, &modify_len) == FAILURE) { RETURN_FALSE; @@ -1943,7 +1940,16 @@ PHP_FUNCTION(date_modify) dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); DATE_CHECK_INITIALIZED(dateobj->time, DateTime); - tmp_time = timelib_strtotime(modify, modify_len, NULL, DATE_TIMEZONEDB); + tmp_time = timelib_strtotime(modify, modify_len, &err, DATE_TIMEZONEDB); + + if (err && err->error_count) { + /* spit out the first library error message, at least */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", modify, + err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message); + timelib_time_dtor(tmp_time); + RETURN_FALSE; + } + memcpy(&dateobj->time->relative, &tmp_time->relative, sizeof(struct timelib_rel_time)); dateobj->time->have_relative = tmp_time->have_relative; dateobj->time->have_weekday_relative = tmp_time->have_weekday_relative; diff --git a/ext/date/tests/bug45866.phpt b/ext/date/tests/bug45866.phpt new file mode 100644 index 0000000000..a8407a6341 --- /dev/null +++ b/ext/date/tests/bug45866.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #45866 (decimal values fed to DateTime->modify() causes long execution times) +--INI-- +date.timezone=UTC +--FILE-- +modify( "+1.61538461538 day" ); +echo $date->format( 'r' ), "\n"; + +$date = new DateTime( '2009-07-29 16:44:23 Europe/London' ); +$date->modify( "61538461538 day" ); +echo $date->format( 'r' ), "\n"; + +$date = new DateTime( '2009-07-29 16:44:23 Europe/London' ); +$date->modify( "£61538461538 day" ); +echo $date->format( 'r' ), "\n"; +?> +--EXPECTF-- +Thu, 14 Aug 168488594 16:44:23 +0000 +Thu, 14 Aug 168488594 16:44:23 +0000 + +Warning: DateTime::modify(): Failed to parse time string (£61538461538 day) at position 0 (%s): Unexpected character in %sbug45866.php on line 11 +Wed, 29 Jul 2009 16:44:23 +0100 diff --git a/ext/date/tests/bug46268.phpt b/ext/date/tests/bug46268.phpt index dd2d4a3ca5..808fd856a9 100644 --- a/ext/date/tests/bug46268.phpt +++ b/ext/date/tests/bug46268.phpt @@ -7,10 +7,10 @@ date_default_timezone_set('Asia/Tokyo'); $now = new DateTime('2008-10-10 01:02:03'); echo $now->format("Y-m-d H:i:s") . PHP_EOL; -$now->modify("1 day after"); +$now->modify("1 day"); echo $now->format("Y-m-d H:i:s") . PHP_EOL; -$now->modify("1 hour after"); +$now->modify("1 hour"); echo $now->format("Y-m-d H:i:s") . PHP_EOL; $now->setTime(0, 0, 0); diff --git a/ext/date/tests/oo_002.phpt b/ext/date/tests/oo_002.phpt index 0cd9187b1e..fd61388b6a 100644 --- a/ext/date/tests/oo_002.phpt +++ b/ext/date/tests/oo_002.phpt @@ -10,7 +10,7 @@ $d = new _d("1pm Aug 1 GMT 2007"); var_dump($d->format(DateTime::RFC822)); $c = clone $d; var_dump($c->format(DateTime::RFC822)); -$d->modify("1 hour after"); +$d->modify("1 hour"); $c->modify("1 second ago"); var_dump($d->format(DateTime::RFC822)); var_dump($c->format(DateTime::RFC822));