Skip to content

Commit

Permalink
Fixed SEGV occurring when passing an invalid value to strtotime (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
zeriyoshi authored Sep 13, 2024
1 parent 3f444bd commit 65a2b56
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
24 changes: 17 additions & 7 deletions ext/hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ static inline void apply_interval(timelib_time **time, timelib_rel_time *interva
return; \
} \
\
if (datetime && is_fixed_time_str(datetime, timezone)) { \
if (datetime && is_fixed_time_str(datetime, timezone) == 1) { \
return; \
} \
\
Expand Down Expand Up @@ -283,7 +283,7 @@ static inline void apply_interval(timelib_time **time, timelib_rel_time *interva
COLOPL_TS_G(orig_##name) = NULL; \
} while (0);

static inline bool is_fixed_time_str(zend_string *datetime, zval *timezone)
static inline int is_fixed_time_str(zend_string *datetime, zval *timezone)
{
zval before_zv, after_zv;
php_date_obj *before, *after;
Expand All @@ -292,13 +292,20 @@ static inline bool is_fixed_time_str(zend_string *datetime, zval *timezone)

php_date_instantiate(ce, &before_zv);
before = Z_PHPDATE_P(&before_zv);
php_date_initialize(before, ZSTR_VAL(datetime), ZSTR_LEN(datetime), NULL, timezone, 0);
if (!php_date_initialize(before, ZSTR_VAL(datetime), ZSTR_LEN(datetime), NULL, timezone, 0)) {
zval_ptr_dtor(&before_zv);
return FAILURE;
}

usleep(((uint32_t) COLOPL_TS_G(usleep_sec)) > 0 ? (uint32_t) COLOPL_TS_G(usleep_sec) : 1);

php_date_instantiate(ce, &after_zv);
after = Z_PHPDATE_P(&after_zv);
php_date_initialize(after, ZSTR_VAL(datetime), ZSTR_LEN(datetime), NULL, timezone, 0);
if (!php_date_initialize(after, ZSTR_VAL(datetime), ZSTR_LEN(datetime), NULL, timezone, 0)) {
zval_ptr_dtor(&before_zv);
zval_ptr_dtor(&after_zv);
return FAILURE;
}

is_fixed_time_str = before->time->y == after->time->y
&& before->time->m == after->time->m
Expand All @@ -312,7 +319,7 @@ static inline bool is_fixed_time_str(zend_string *datetime, zval *timezone)
zval_ptr_dtor(&before_zv);
zval_ptr_dtor(&after_zv);

return is_fixed_time_str;
return (int) is_fixed_time_str;
}

static inline timelib_time *get_current_timelib_time(timelib_tzinfo *tzi)
Expand Down Expand Up @@ -518,7 +525,7 @@ static inline void date_create_common(INTERNAL_FUNCTION_PARAMETERS, zend_class_e
RETVAL_FALSE;
}

if (time_str && is_fixed_time_str(time_str, timezone_object)) {
if (time_str && is_fixed_time_str(time_str, timezone_object) == 1) {
return;
}

Expand Down Expand Up @@ -664,6 +671,7 @@ static void hook_strtotime(INTERNAL_FUNCTION_PARAMETERS)
zend_string *times, *times_lower;
zend_long preset_ts;
bool preset_ts_is_null = true;
int is_fixed_ret;

ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_QUIET, 1, 2)
Z_PARAM_STR(times);
Expand All @@ -679,7 +687,9 @@ static void hook_strtotime(INTERNAL_FUNCTION_PARAMETERS)
}
zend_string_release(times_lower);

if (!preset_ts_is_null || is_fixed_time_str(times, NULL) ) {
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;
}
Expand Down
17 changes: 17 additions & 0 deletions ext/tests/gh10.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--TEST--
Check GitHub PR - #10 (if invalid argument passed to strtotime to SEGV)
--EXTENSIONS--
colopl_timeshifter
--FILE--
<?php

echo 'before:', strtotime('invalid'), \PHP_EOL;
\Colopl\ColoplTimeShifter\register_hook(new DateInterval('P1D'));
echo 'after:', strtotime('invalid'), \PHP_EOL;
die('Success');

?>
--EXPECT--
before:
after:
Success

0 comments on commit 65a2b56

Please sign in to comment.