mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-28 12:57:50 +00:00
Convert from time in minutes to timespec directly instead of
converting to double via strtod(). This makes it easier to catch overflow.
This commit is contained in:
parent
eb8b5c7964
commit
bcfb092a4e
@ -165,9 +165,9 @@ dump_defaults(void)
|
|||||||
break;
|
break;
|
||||||
case T_TIMESPEC: {
|
case T_TIMESPEC: {
|
||||||
/* display timespec in minutes as a double */
|
/* display timespec in minutes as a double */
|
||||||
double d = cur->sd_un.tspec.tv_sec / 60.0;
|
double d = cur->sd_un.tspec.tv_sec +
|
||||||
d += cur->sd_un.tspec.tv_nsec / 1000000000.0;
|
(cur->sd_un.tspec.tv_nsec / 1000000000.0);
|
||||||
sudo_printf(SUDO_CONV_INFO_MSG, desc, d);
|
sudo_printf(SUDO_CONV_INFO_MSG, desc, d * 60.0);
|
||||||
sudo_printf(SUDO_CONV_INFO_MSG, "\n");
|
sudo_printf(SUDO_CONV_INFO_MSG, "\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -851,26 +851,61 @@ store_uint(const char *str, union sudo_defs_val *sd_un)
|
|||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TIME_T_MAX
|
||||||
|
# if SIZEOF_TIME_T == 8
|
||||||
|
# define TIME_T_MAX LLONG_MAX
|
||||||
|
# else
|
||||||
|
# define TIME_T_MAX INT_MAX
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
store_timespec(const char *str, union sudo_defs_val *sd_un)
|
store_timespec(const char *str, union sudo_defs_val *sd_un)
|
||||||
{
|
{
|
||||||
char *endp;
|
struct timespec ts;
|
||||||
double d;
|
char sign = '+';
|
||||||
|
int i;
|
||||||
debug_decl(store_timespec, SUDOERS_DEBUG_DEFAULTS)
|
debug_decl(store_timespec, SUDOERS_DEBUG_DEFAULTS)
|
||||||
|
|
||||||
if (str == NULL) {
|
sudo_timespecclear(&ts);
|
||||||
sd_un->tspec.tv_sec = 0;
|
if (str != NULL) {
|
||||||
sd_un->tspec.tv_nsec = 0;
|
/* Convert from minutes to timespec. */
|
||||||
|
if (*str == '+' || *str == '-')
|
||||||
|
sign = *str++;
|
||||||
|
while (*str != '\0' && *str != '.') {
|
||||||
|
if (!isdigit((unsigned char)*str))
|
||||||
|
debug_return_bool(false); /* invalid number */
|
||||||
|
if (ts.tv_sec > TIME_T_MAX / 10)
|
||||||
|
debug_return_bool(false); /* overflow */
|
||||||
|
ts.tv_sec *= 10;
|
||||||
|
ts.tv_sec += *str++ - '0';
|
||||||
|
}
|
||||||
|
if (*str++ == '.') {
|
||||||
|
/* Convert optional fractional component to nanosecs. */
|
||||||
|
for (i = 100000000; i > 0; i /= 10) {
|
||||||
|
if (*str == '\0')
|
||||||
|
break;
|
||||||
|
if (!isdigit((unsigned char)*str))
|
||||||
|
debug_return_bool(false); /* invalid number */
|
||||||
|
ts.tv_nsec += i * (*str++ - '0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Convert from minutes to seconds. */
|
||||||
|
if (ts.tv_sec > TIME_T_MAX / 60)
|
||||||
|
debug_return_bool(false); /* overflow */
|
||||||
|
ts.tv_sec *= 60;
|
||||||
|
ts.tv_nsec *= 60;
|
||||||
|
while (ts.tv_nsec >= 1000000000) {
|
||||||
|
ts.tv_sec++;
|
||||||
|
ts.tv_nsec -= 1000000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sign == '-') {
|
||||||
|
sd_un->tspec.tv_sec = -ts.tv_sec;
|
||||||
|
sd_un->tspec.tv_nsec = -ts.tv_nsec;
|
||||||
} else {
|
} else {
|
||||||
d = strtod(str, &endp);
|
sd_un->tspec.tv_sec = ts.tv_sec;
|
||||||
if (*endp != '\0')
|
sd_un->tspec.tv_nsec = ts.tv_nsec;
|
||||||
debug_return_bool(false);
|
|
||||||
/* XXX - should check against HUGE_VAL */
|
|
||||||
|
|
||||||
/* Convert from minutes to seconds and nanoseconds. */
|
|
||||||
d *= 60.0;
|
|
||||||
sd_un->tspec.tv_sec = (time_t)d;
|
|
||||||
sd_un->tspec.tv_nsec = (long)((d - sd_un->tspec.tv_sec) * 1000000000.0);
|
|
||||||
}
|
}
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user