From ca49de07ee137226fca0e5f2088c771fef017ce5 Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Tue, 17 Sep 2024 19:10:26 +0900 Subject: [PATCH] Fix strtotime for specific arguments (#12) --- ext/hook.c | 37 +++++++++++++++++++++++-------------- ext/tests/gh12.phpt | 40 ++++++++++++++++++++++++++++++++++++++++ ext/tests/gh9.phpt | 17 +++++++---------- 3 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 ext/tests/gh12.phpt diff --git a/ext/hook.c b/ext/hook.c index f97d2a5..1f2af89 100644 --- a/ext/hook.c +++ b/ext/hook.c @@ -285,11 +285,24 @@ static inline void apply_interval(timelib_time **time, timelib_rel_time *interva static inline int is_fixed_time_str(zend_string *datetime, zval *timezone) { + zend_string *datetime_lower; zval before_zv, after_zv; php_date_obj *before, *after; zend_class_entry *ce = php_date_get_immutable_ce(); bool is_fixed_time_str; + datetime_lower = zend_string_tolower(datetime); + if (strncmp(ZSTR_VAL(datetime_lower), "now", 3) == 0 || + strncmp(ZSTR_VAL(datetime_lower), "yesterday", 9) == 0 || + strncmp(ZSTR_VAL(datetime_lower), "today", 5) == 0 || + strncmp(ZSTR_VAL(datetime_lower), "tomorrow", 8) == 0 + ) { + zend_string_release(datetime_lower); + return 2; + } + + zend_string_release(datetime_lower); + php_date_instantiate(ce, &before_zv); before = Z_PHPDATE_P(&before_zv); if (!php_date_initialize(before, ZSTR_VAL(datetime), ZSTR_LEN(datetime), NULL, timezone, 0)) { @@ -679,14 +692,6 @@ static void hook_strtotime(INTERNAL_FUNCTION_PARAMETERS) Z_PARAM_LONG_OR_NULL(preset_ts, preset_ts_is_null); ZEND_PARSE_PARAMETERS_END(); - /* "now" special case */ - times_lower = zend_string_tolower(times); - if (strncmp(ZSTR_VAL(times_lower), "now", 3) == 0) { - zend_string_release(times_lower); - RETURN_LONG((zend_long) get_shifted_time(NULL)); - } - zend_string_release(times_lower); - is_fixed_ret = is_fixed_time_str(times, NULL); if (!preset_ts_is_null || is_fixed_ret == 1 || is_fixed_ret == FAILURE) { @@ -694,12 +699,16 @@ static void hook_strtotime(INTERNAL_FUNCTION_PARAMETERS) return; } - /* Call original function with params. */ - zval *params = NULL; - uint32_t param_count = 0; - zend_parse_parameters(ZEND_NUM_ARGS(), "+", ¶ms, ¶m_count); - ZVAL_LONG(¶ms[1], get_shifted_time(NULL)); - CALL_ORIGINAL_FUNCTION_WITH_PARAMS(strtotime, params, param_count); + if (is_fixed_ret == 2) { + CALL_ORIGINAL_FUNCTION(strtotime); + } else { + /* Call original function with params. */ + zval *params = NULL; + uint32_t param_count = 0; + zend_parse_parameters(ZEND_NUM_ARGS(), "+", ¶ms, ¶m_count); + ZVAL_LONG(¶ms[1], get_shifted_time(NULL)); + CALL_ORIGINAL_FUNCTION_WITH_PARAMS(strtotime, params, param_count); + } /* Apply interval. */ timelib_time *t = timelib_time_ctor(); diff --git a/ext/tests/gh12.phpt b/ext/tests/gh12.phpt new file mode 100644 index 0000000..f8e0ab0 --- /dev/null +++ b/ext/tests/gh12.phpt @@ -0,0 +1,40 @@ +--TEST-- +Check GitHub PR - #12 (wrong strtotime) +--EXTENSIONS-- +colopl_timeshifter +--SKIPIF-- + +--FILE-- +format('Y-m-d H:i:s.u'), \PHP_EOL; +echo (new \DateTime('@' . strtotime('today')))->format('Y-m-d H:i:s.u'), \PHP_EOL; +echo (new \DateTime('@' . strtotime('tomorrow')))->format('Y-m-d H:i:s.u'), \PHP_EOL; +echo (new \DateTime('@' . strtotime('yesterday')))->format('Y-m-d H:i:s.u'), \PHP_EOL; + +echo (new \DateTime('now'))->format('Y-m-d H:i:s.u'), \PHP_EOL; +echo (new \DateTime('today'))->format('Y-m-d H:i:s.u'), \PHP_EOL; +echo (new \DateTime('tomorrow'))->format('Y-m-d H:i:s.u'), \PHP_EOL; +echo (new \DateTime('yesterday'))->format('Y-m-d H:i:s.u'), \PHP_EOL; + +shell_exec("date -s \"{$current_date}\""); + +?> +--EXPECTF-- +2024-09-16 17:00:00.%d +2024-09-16 00:00:00.%d +2024-09-17 00:00:00.%d +2024-09-15 00:00:00.%d +2024-09-16 17:00:00.%d +2024-09-16 00:00:00.%d +2024-09-17 00:00:00.%d +2024-09-15 00:00:00.%d diff --git a/ext/tests/gh9.phpt b/ext/tests/gh9.phpt index 6fa399b..ac0923b 100644 --- a/ext/tests/gh9.phpt +++ b/ext/tests/gh9.phpt @@ -5,20 +5,15 @@ colopl_timeshifter --SKIPIF-- getmessage()}"); -} -if ($dt->format('d') !== '01') die('skip not start of month'); +if (!is_string(($result = shell_exec('date')))) die ('skip cannot set current date'); ?> --FILE-- format('Y-m-d H:i:s.u'), \PHP_EOL; $second = date_create_from_format('d', '10'); echo $second->format('Y-m-d H:i:s.u'), \PHP_EOL; +shell_exec("date -s \"{$current_date}\""); + ?> --EXPECTF-- 2024-09-01 %d:%d:%d.%d