]> granicus.if.org Git - php/commitdiff
Convert UNKNOWN default values to null in ext/date
authorMáté Kocsis <kocsismate@woohoolabs.com>
Fri, 1 May 2020 19:45:30 +0000 (21:45 +0200)
committerMáté Kocsis <kocsismate@woohoolabs.com>
Sat, 2 May 2020 09:05:37 +0000 (11:05 +0200)
Closes GH-5509

Zend/zend_API.h
ext/date/php_date.c
ext/date/php_date.stub.php
ext/date/php_date_arginfo.h
ext/date/tests/bug36988.phpt
ext/date/tests/bug70245.phpt

index fe6ec000e9d081a108a33016a86c4b55786bdceb..76355090e9fa2ddf61371a7da6e24357991621ad 100644 (file)
@@ -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); \
index 67a9d66f635db236f8b0d31856b479355f494cb9..e71699ecbfa1415f5d786820df76df7a2a51c748 100644 (file)
@@ -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;
        }
 
index 533eb455feb23e283f855cc0ca79f83b51fcdfcd..f360eeee0ac9040e4dd356aebcdc5a29251545ec 100644 (file)
@@ -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 {}
index 4115a5a789e89a9a2412ab90aa9294873479e92e..e3fa98281127ff1bd5bf4f9df1882e6e5bdea885 100644 (file)
@@ -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()
 
index 275dc80a0d50539493128907a60dc6724f859e28..32359808517b1ccf6c2f268d2fc2f994a4f42436 100644 (file)
@@ -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
index 9fd566de9a9963870c894c647e3ae0779bb8f923..b45e8be931163f03cde57088a4e3a337c2c5889d 100644 (file)
@@ -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