From: Máté Kocsis Date: Fri, 1 May 2020 19:45:30 +0000 (+0200) Subject: Convert UNKNOWN default values to null in ext/date X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ffcc8135e2acb563262f3fe03e629448d2d4d321;p=php Convert UNKNOWN default values to null in ext/date Closes GH-5509 --- diff --git a/Zend/zend_API.h b/Zend/zend_API.h index fe6ec000e9..76355090e9 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -1354,6 +1354,9 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num #define Z_PARAM_DOUBLE(dest) \ Z_PARAM_DOUBLE_EX(dest, _dummy, 0, 0) +#define Z_PARAM_DOUBLE_OR_NULL(dest, is_null) \ + Z_PARAM_DOUBLE_EX(dest, is_null, 1, 0) + /* old "f" */ #define Z_PARAM_FUNC_EX2(dest_fci, dest_fcc, check_null, deref, separate) \ Z_PARAM_PROLOGUE(deref, separate); \ diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 67a9d66f63..e71699ecbf 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -782,14 +782,15 @@ static void php_date(INTERNAL_FUNCTION_PARAMETERS, int localtime) { zend_string *format; zend_long ts; + zend_bool ts_is_null = 1; ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(format) Z_PARAM_OPTIONAL - Z_PARAM_LONG(ts) + Z_PARAM_LONG_OR_NULL(ts, ts_is_null) ZEND_PARSE_PARAMETERS_END(); - if (ZEND_NUM_ARGS() == 1) { + if (ts_is_null) { ts = php_time(); } @@ -940,13 +941,14 @@ PHP_FUNCTION(gmdate) PHP_FUNCTION(idate) { zend_string *format; - zend_long ts = 0; + zend_long ts; + zend_bool ts_is_null = 1; int ret; ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(format) Z_PARAM_OPTIONAL - Z_PARAM_LONG(ts) + Z_PARAM_LONG_OR_NULL(ts, ts_is_null) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(format) != 1) { @@ -954,7 +956,7 @@ PHP_FUNCTION(idate) RETURN_FALSE; } - if (ZEND_NUM_ARGS() == 1) { + if (ts_is_null) { ts = php_time(); } @@ -1011,14 +1013,15 @@ PHP_FUNCTION(strtotime) zend_string *times; int error1, error2; timelib_error_container *error; - zend_long preset_ts = 0, ts; + zend_long preset_ts, ts; + zend_bool preset_ts_is_null = 1; timelib_time *t, *now; timelib_tzinfo *tzi; ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(times) Z_PARAM_OPTIONAL - Z_PARAM_LONG(preset_ts) + Z_PARAM_LONG_OR_NULL(preset_ts, preset_ts_is_null) ZEND_PARSE_PARAMETERS_END(); tzi = get_timezone_info(); @@ -1027,7 +1030,7 @@ PHP_FUNCTION(strtotime) now->tz_info = tzi; now->zone_type = TIMELIB_ZONETYPE_ID; timelib_unixtime2local(now, - (ZEND_NUM_ARGS() == 2) ? (timelib_sll) preset_ts : (timelib_sll) php_time()); + !preset_ts_is_null ? (timelib_sll) preset_ts : (timelib_sll) php_time()); t = timelib_strtotime(ZSTR_VAL(times), ZSTR_LEN(times), &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); @@ -1051,7 +1054,8 @@ PHP_FUNCTION(strtotime) /* {{{ php_mktime - (gm)mktime helper */ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt) { - zend_long hou = 0, min = 0, sec = 0, mon = 0, day = 0, yea = 0; + zend_long hou, min, sec, mon, day, yea; + zend_bool min_is_null = 1, sec_is_null = 1, mon_is_null = 1, day_is_null = 1, yea_is_null = 1; timelib_time *now; timelib_tzinfo *tzi = NULL; zend_long ts, adjust_seconds = 0; @@ -1060,11 +1064,11 @@ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt) ZEND_PARSE_PARAMETERS_START(1, 6) Z_PARAM_LONG(hou) Z_PARAM_OPTIONAL - Z_PARAM_LONG(min) - Z_PARAM_LONG(sec) - Z_PARAM_LONG(mon) - Z_PARAM_LONG(day) - Z_PARAM_LONG(yea) + Z_PARAM_LONG_OR_NULL(min, min_is_null) + Z_PARAM_LONG_OR_NULL(sec, sec_is_null) + Z_PARAM_LONG_OR_NULL(mon, mon_is_null) + Z_PARAM_LONG_OR_NULL(day, day_is_null) + Z_PARAM_LONG_OR_NULL(yea, yea_is_null) ZEND_PARSE_PARAMETERS_END(); /* Initialize structure with current time */ @@ -1077,33 +1081,34 @@ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt) now->zone_type = TIMELIB_ZONETYPE_ID; timelib_unixtime2local(now, (timelib_sll) php_time()); } - /* Fill in the new data */ - switch (ZEND_NUM_ARGS()) { - case 6: - if (yea >= 0 && yea < 70) { - yea += 2000; - } else if (yea >= 70 && yea <= 100) { - yea += 1900; - } - now->y = yea; - /* break intentionally missing again */ - case 5: - now->d = day; - /* break missing intentionally here too */ - case 4: - now->m = mon; - /* and here */ - case 3: - now->s = sec; - /* yup, this break isn't here on purpose too */ - case 2: - now->i = min; - /* last intentionally missing break */ - case 1: - now->h = hou; - break; - EMPTY_SWITCH_DEFAULT_CASE() + + now->h = hou; + + if (!min_is_null) { + now->i = min; + } + + if (!sec_is_null) { + now->s = sec; + } + + if (!mon_is_null) { + now->m = mon; } + + if (!day_is_null) { + now->d = day; + } + + if (!yea_is_null) { + if (yea >= 0 && yea < 70) { + yea += 2000; + } else if (yea >= 70 && yea <= 100) { + yea += 1900; + } + now->y = yea; + } + /* Update the timestamp */ if (gmt) { timelib_update_ts(now, NULL); @@ -1163,7 +1168,8 @@ PHP_FUNCTION(checkdate) PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt) { zend_string *format; - zend_long timestamp = 0; + zend_long timestamp; + zend_bool timestamp_is_null = 1; struct tm ta; int max_reallocs = 5; size_t buf_len = 256, real_len; @@ -1172,18 +1178,20 @@ PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt) timelib_time_offset *offset = NULL; zend_string *buf; - timestamp = (zend_long) php_time(); - ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(format) Z_PARAM_OPTIONAL - Z_PARAM_LONG(timestamp) + Z_PARAM_LONG_OR_NULL(timestamp, timestamp_is_null) ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(format) == 0) { RETURN_FALSE; } + if (timestamp_is_null) { + timestamp = (zend_long) php_time(); + } + ts = timelib_time_ctor(); if (gmt) { tzi = NULL; @@ -1286,17 +1294,18 @@ PHP_FUNCTION(time) PHP_FUNCTION(localtime) { zend_long timestamp; + zend_bool timestamp_is_null = 1; zend_bool associative = 0; timelib_tzinfo *tzi; timelib_time *ts; ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_LONG(timestamp) + Z_PARAM_LONG_OR_NULL(timestamp, timestamp_is_null) Z_PARAM_BOOL(associative) ZEND_PARSE_PARAMETERS_END(); - if (ZEND_NUM_ARGS() == 0) { + if (timestamp_is_null) { timestamp = (zend_long) php_time(); } @@ -1339,15 +1348,16 @@ PHP_FUNCTION(localtime) PHP_FUNCTION(getdate) { zend_long timestamp; + zend_bool timestamp_is_null = 1; timelib_tzinfo *tzi; timelib_time *ts; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_LONG(timestamp) + Z_PARAM_LONG_OR_NULL(timestamp, timestamp_is_null) ZEND_PARSE_PARAMETERS_END(); - if (ZEND_NUM_ARGS() == 0) { + if (timestamp_is_null) { timestamp = (zend_long) php_time(); } @@ -4511,10 +4521,11 @@ PHP_FUNCTION(date_default_timezone_get) */ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, int calc_sunset) { - double latitude = 0.0, longitude = 0.0, zenith = 0.0, gmt_offset = 0, altitude; + double latitude, longitude, zenith, gmt_offset, altitude; + zend_bool latitude_is_null = 1, longitude_is_null = 1, zenith_is_null = 1, gmt_offset_is_null = 1; double h_rise, h_set, N; timelib_sll rise, set, transit; - zend_long time, retformat = 0; + zend_long time, retformat = SUNFUNCS_RET_STRING; int rs; timelib_time *t; timelib_tzinfo *tzi; @@ -4524,33 +4535,28 @@ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, int calc_su Z_PARAM_LONG(time) Z_PARAM_OPTIONAL Z_PARAM_LONG(retformat) - Z_PARAM_DOUBLE(latitude) - Z_PARAM_DOUBLE(longitude) - Z_PARAM_DOUBLE(zenith) - Z_PARAM_DOUBLE(gmt_offset) + Z_PARAM_DOUBLE_OR_NULL(latitude, latitude_is_null) + Z_PARAM_DOUBLE_OR_NULL(longitude, longitude_is_null) + Z_PARAM_DOUBLE_OR_NULL(zenith, zenith_is_null) + Z_PARAM_DOUBLE_OR_NULL(gmt_offset, gmt_offset_is_null) ZEND_PARSE_PARAMETERS_END(); - switch (ZEND_NUM_ARGS()) { - case 1: - retformat = SUNFUNCS_RET_STRING; - case 2: - latitude = INI_FLT("date.default_latitude"); - case 3: - longitude = INI_FLT("date.default_longitude"); - case 4: - if (calc_sunset) { - zenith = INI_FLT("date.sunset_zenith"); - } else { - zenith = INI_FLT("date.sunrise_zenith"); - } - case 5: - case 6: - break; - default: - php_error_docref(NULL, E_WARNING, "Invalid format"); - RETURN_FALSE; - break; + if (latitude_is_null) { + latitude = INI_FLT("date.default_latitude"); + } + + if (longitude_is_null) { + latitude = INI_FLT("date.default_longitude"); + } + + if (zenith_is_null) { + if (calc_sunset) { + zenith = INI_FLT("date.sunset_zenith"); + } else { + zenith = INI_FLT("date.sunrise_zenith"); + } } + if (retformat != SUNFUNCS_RET_TIMESTAMP && retformat != SUNFUNCS_RET_STRING && retformat != SUNFUNCS_RET_DOUBLE) @@ -4566,7 +4572,7 @@ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, int calc_su t->tz_info = tzi; t->zone_type = TIMELIB_ZONETYPE_ID; - if (ZEND_NUM_ARGS() <= 5) { + if (gmt_offset_is_null) { gmt_offset = timelib_get_current_offset(t) / 3600; } diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index 533eb455fe..f360eeee0a 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -2,33 +2,33 @@ /** @generate-function-entries */ -function strtotime(string $time, int $now = UNKNOWN): int|false {} +function strtotime(string $time, ?int $now = null): int|false {} -function date(string $format, int $timestamp = UNKNOWN): string {} +function date(string $format, ?int $timestamp = null): string {} -function idate(string $format, int $timestamp = UNKNOWN): int|false {} +function idate(string $format, ?int $timestamp = null): int|false {} -function gmdate(string $format, int $timestamp = UNKNOWN): string {} +function gmdate(string $format, ?int $timestamp = null): string {} function mktime( - int $hour, int $min = UNKNOWN, int $sec = UNKNOWN, - int $mon = UNKNOWN, int $day = UNKNOWN, int $year = UNKNOWN): int|false {} + int $hour, ?int $min = null, ?int $sec = null, + ?int $mon = null, ?int $day = null, ?int $year = null): int|false {} function gmmktime( - int $hour, int $min = UNKNOWN, int $sec = UNKNOWN, - int $mon = UNKNOWN, int $day = UNKNOWN, int $year = UNKNOWN): int|false {} + int $hour, ?int $min = null, ?int $sec = null, + ?int $mon = null, ?int $day = null, ?int $year = null): int|false {} function checkdate(int $m, int $d, int $y): bool {} -function strftime(string $format, int $timestamp = UNKNOWN): string|false {} +function strftime(string $format, ?int $timestamp = null): string|false {} -function gmstrftime(string $format, int $timestamp = UNKNOWN): string|false {} +function gmstrftime(string $format, ?int $timestamp = null): string|false {} function time(): int {} -function localtime(int $timestamp = UNKNOWN, bool $associative = false): array {} +function localtime(?int $timestamp = null, bool $associative = false): array {} -function getdate(int $timestamp = UNKNOWN): array {} +function getdate(?int $timestamp = null): array {} function date_create(string $time = "now", ?DateTimeZone $timezone = null): DateTime|false {} @@ -104,12 +104,12 @@ function date_default_timezone_get(): string {} function date_sunrise( int $time, int $retformat = SUNFUNCS_RET_STRING, - float $latitude = UNKNOWN, float $longitude = UNKNOWN, float $zenith = UNKNOWN, + ?float $latitude = null, ?float $longitude = null, ?float $zenith = null, float $gmt_offset = 0): string|int|float|false {} function date_sunset( int $time, int $retformat = SUNFUNCS_RET_STRING, - float $latitude = UNKNOWN, float $longitude = UNKNOWN, float $zenith = UNKNOWN, + ?float $latitude = null, ?float $longitude = null, ?float $zenith = null, float $gmt_offset = 0): string|int|float|false {} function date_sun_info(int $time, float $latitude, float $longitude): array {} diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index 4115a5a789..e3fa982811 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -2,28 +2,28 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, time, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, now, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, now, IS_LONG, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_date, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timestamp, IS_LONG, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_idate, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timestamp, IS_LONG, 1, "null") ZEND_END_ARG_INFO() #define arginfo_gmdate arginfo_date ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mktime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, hour, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, min, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, sec, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, mon, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, day, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, year, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, min, IS_LONG, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, sec, IS_LONG, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mon, IS_LONG, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, day, IS_LONG, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, year, IS_LONG, 1, "null") ZEND_END_ARG_INFO() #define arginfo_gmmktime arginfo_mktime @@ -36,7 +36,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strftime, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timestamp, IS_LONG, 1, "null") ZEND_END_ARG_INFO() #define arginfo_gmstrftime arginfo_strftime @@ -45,12 +45,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_time, 0, 0, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_localtime, 0, 0, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timestamp, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, associative, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_getdate, 0, 0, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timestamp, IS_LONG, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create, 0, 0, DateTime, MAY_BE_FALSE) @@ -212,9 +212,9 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_date_sunrise, 0, 1, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, time, IS_LONG, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, retformat, IS_LONG, 0, "SUNFUNCS_RET_STRING") - ZEND_ARG_TYPE_INFO(0, latitude, IS_DOUBLE, 0) - ZEND_ARG_TYPE_INFO(0, longitude, IS_DOUBLE, 0) - ZEND_ARG_TYPE_INFO(0, zenith, IS_DOUBLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, latitude, IS_DOUBLE, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, longitude, IS_DOUBLE, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, zenith, IS_DOUBLE, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, gmt_offset, IS_DOUBLE, 0, "0") ZEND_END_ARG_INFO() diff --git a/ext/date/tests/bug36988.phpt b/ext/date/tests/bug36988.phpt index 275dc80a0d..3235980851 100644 --- a/ext/date/tests/bug36988.phpt +++ b/ext/date/tests/bug36988.phpt @@ -13,4 +13,4 @@ try { } ?> --EXPECT-- -mktime(): Argument #6 ($year) must be of type int, float given +mktime(): Argument #6 ($year) must be of type ?int, float given diff --git a/ext/date/tests/bug70245.phpt b/ext/date/tests/bug70245.phpt index 9fd566de9a..b45e8be931 100644 --- a/ext/date/tests/bug70245.phpt +++ b/ext/date/tests/bug70245.phpt @@ -10,4 +10,4 @@ try { } ?> --EXPECT-- -strtotime(): Argument #2 ($now) must be of type int, object given +strtotime(): Argument #2 ($now) must be of type ?int, object given