Skip to content

Commit

Permalink
Fix strtotime for specific arguments (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
zeriyoshi authored Sep 17, 2024
1 parent 88a2747 commit ca49de0
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 24 deletions.
37 changes: 23 additions & 14 deletions ext/hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -679,27 +692,23 @@ 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) {
CALL_ORIGINAL_FUNCTION(strtotime);
return;
}

/* Call original function with params. */
zval *params = NULL;
uint32_t param_count = 0;
zend_parse_parameters(ZEND_NUM_ARGS(), "+", &params, &param_count);
ZVAL_LONG(&params[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(), "+", &params, &param_count);
ZVAL_LONG(&params[1], get_shifted_time(NULL));
CALL_ORIGINAL_FUNCTION_WITH_PARAMS(strtotime, params, param_count);
}

/* Apply interval. */
timelib_time *t = timelib_time_ctor();
Expand Down
40 changes: 40 additions & 0 deletions ext/tests/gh12.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--TEST--
Check GitHub PR - #12 (wrong strtotime)
--EXTENSIONS--
colopl_timeshifter
--SKIPIF--
<?php
if (posix_getuid() !== 0) die('skip require root');
if (!is_string(($result = shell_exec('date')))) die ('skip cannot set current date');
?>
--FILE--
<?php

$current_date = trim(shell_exec('date "+%Y-%m-%d %H:%M:%S"'));

shell_exec('date -s "2024-09-17 17:00:00"');

\Colopl\ColoplTimeShifter\register_hook(new DateInterval('P1D'));

echo (new \DateTime('@' . strtotime('now')))->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
17 changes: 7 additions & 10 deletions ext/tests/gh9.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ colopl_timeshifter
--SKIPIF--
<?php
if (posix_getuid() !== 0) die('skip require root');
if (! is_string(($result = shell_exec('date -s "2024-09-01"')))) die ('skip cannot set current date');
try {
$dt = new \DateTimeImmutable($result);
if (!($dt instanceof \DateTimeImmutable)) {
throw new Exception("construction failed: {$result}");
}
} catch (\Exception $e) {
die("skip {$e->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--
<?php

$current_date = trim(shell_exec('date "+%Y-%m-%d %H:%M:%S"'));

shell_exec('date -s "2024-09-01"');

$interval = new DateInterval('P1D');

$first = new \DateTime();
Expand All @@ -28,6 +23,8 @@ echo (new \DateTime())->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
Expand Down

0 comments on commit ca49de0

Please sign in to comment.