Fix undefined overflow behavior when converting double to integer (#3629)
Overflows in conversions from floating-point to integer are undefined behavior in the C99 standard. (Clause 6.3.1.4: "If the value of the integral part cannot be represented by the integer type, the behavior is undefined.") When UBSAN is enabled, this gets reported at `srand()` calls. (The random seed is usually initialized using the date port API, which represents dates as `double`s. But `srand` takes an `unsigned int`. A simple cast from `double` to `unsigned` becomes undefined behavior if the value is too large. And "now" is too large nowadays. So, effectively, all executions start with an undefined behavior.) This patch fixes this by casting the floating-point value of the date to an integer through a union. JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
This commit is contained in:
@@ -1084,7 +1084,8 @@ int
|
|||||||
main (void)
|
main (void)
|
||||||
{
|
{
|
||||||
/* Initialize srand value */
|
/* Initialize srand value */
|
||||||
srand ((unsigned) jerry_port_get_current_time ());
|
union { double d; unsigned u; } now = { .d = jerry_port_get_current_time () };
|
||||||
|
srand (now.u);
|
||||||
|
|
||||||
/* Generate a random number, and print it */
|
/* Generate a random number, and print it */
|
||||||
const jerry_char_t script[] = "var a = Math.random (); print(a)";
|
const jerry_char_t script[] = "var a = Math.random (); print(a)";
|
||||||
|
|||||||
@@ -72,7 +72,12 @@ int
|
|||||||
main (int argc,
|
main (int argc,
|
||||||
char **argv)
|
char **argv)
|
||||||
{
|
{
|
||||||
srand ((unsigned) jerry_port_get_current_time ());
|
union
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
unsigned u;
|
||||||
|
} now = { .d = jerry_port_get_current_time () };
|
||||||
|
srand (now.u);
|
||||||
if (argc <= 1 || (argc == 2 && (!strcmp ("-h", argv[1]) || !strcmp ("--help", argv[1]))))
|
if (argc <= 1 || (argc == 2 && (!strcmp ("-h", argv[1]) || !strcmp ("--help", argv[1]))))
|
||||||
{
|
{
|
||||||
print_help (argv[0]);
|
print_help (argv[0]);
|
||||||
|
|||||||
@@ -467,7 +467,12 @@ int
|
|||||||
main (int argc,
|
main (int argc,
|
||||||
char **argv)
|
char **argv)
|
||||||
{
|
{
|
||||||
srand ((unsigned) jerry_port_get_current_time ());
|
union
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
unsigned u;
|
||||||
|
} now = { .d = jerry_port_get_current_time () };
|
||||||
|
srand (now.u);
|
||||||
JERRY_VLA (const char *, file_names, argc);
|
JERRY_VLA (const char *, file_names, argc);
|
||||||
int files_counter = 0;
|
int files_counter = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,8 @@ void eval_jerry_script (int argc, char *argv[], struct tcmd_handler_ctx *ctx)
|
|||||||
|
|
||||||
void jerry_start ()
|
void jerry_start ()
|
||||||
{
|
{
|
||||||
srand ((unsigned) jerry_port_get_current_time ());
|
union { double d; unsigned u; } now = { .d = jerry_port_get_current_time () };
|
||||||
|
srand (now.u);
|
||||||
jerry_init (JERRY_INIT_EMPTY);
|
jerry_init (JERRY_INIT_EMPTY);
|
||||||
jerry_value_t global_obj_val = jerry_get_global_object ();
|
jerry_value_t global_obj_val = jerry_get_global_object ();
|
||||||
jerry_value_t print_func_name_val = jerry_create_string ((jerry_char_t *) "print");
|
jerry_value_t print_func_name_val = jerry_create_string ((jerry_char_t *) "print");
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ static const char* fn_sys_loop_name = "sysloop";
|
|||||||
|
|
||||||
void js_entry ()
|
void js_entry ()
|
||||||
{
|
{
|
||||||
srand ((unsigned) jerry_port_get_current_time ());
|
union { double d; unsigned u; } now = { .d = jerry_port_get_current_time () };
|
||||||
|
srand (now.u);
|
||||||
|
|
||||||
jerry_init (JERRY_INIT_EMPTY);
|
jerry_init (JERRY_INIT_EMPTY);
|
||||||
js_register_functions ();
|
js_register_functions ();
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ static int load_javascript() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int jsmbed_js_init() {
|
int jsmbed_js_init() {
|
||||||
srand ((unsigned) jerry_port_get_current_time());
|
union { double d; unsigned u; } now = { .d = jerry_port_get_current_time () };
|
||||||
|
srand (now.u);
|
||||||
jerry_init_flag_t flags = JERRY_INIT_EMPTY;
|
jerry_init_flag_t flags = JERRY_INIT_EMPTY;
|
||||||
jerry_init(flags);
|
jerry_init(flags);
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ const shell_command_t shell_commands[] = {
|
|||||||
|
|
||||||
int main (void)
|
int main (void)
|
||||||
{
|
{
|
||||||
srand ((unsigned) jerry_port_get_current_time ());
|
union { double d; unsigned u; } now = { .d = jerry_port_get_current_time () };
|
||||||
|
srand (now.u);
|
||||||
printf ("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
|
printf ("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
|
||||||
printf ("This board features a(n) %s MCU.\n", RIOT_MCU);
|
printf ("This board features a(n) %s MCU.\n", RIOT_MCU);
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ static int shell_cmd_handler (char *source_buffer)
|
|||||||
|
|
||||||
void main (void)
|
void main (void)
|
||||||
{
|
{
|
||||||
srand ((unsigned) jerry_port_get_current_time ());
|
union { double d; unsigned u; } now = { .d = jerry_port_get_current_time () };
|
||||||
|
srand (now.u);
|
||||||
uint32_t zephyr_ver = sys_kernel_version_get ();
|
uint32_t zephyr_ver = sys_kernel_version_get ();
|
||||||
printf ("JerryScript build: " __DATE__ " " __TIME__ "\n");
|
printf ("JerryScript build: " __DATE__ " " __TIME__ "\n");
|
||||||
printf ("JerryScript API %d.%d.%d\n", JERRY_API_MAJOR_VERSION, JERRY_API_MINOR_VERSION, JERRY_API_PATCH_VERSION);
|
printf ("JerryScript API %d.%d.%d\n", JERRY_API_MAJOR_VERSION, JERRY_API_MINOR_VERSION, JERRY_API_PATCH_VERSION);
|
||||||
|
|||||||
@@ -49,7 +49,8 @@
|
|||||||
#define TEST_INIT() \
|
#define TEST_INIT() \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
srand ((unsigned) jerry_port_get_current_time ()); \
|
union { double d; unsigned u; } now = { .d = jerry_port_get_current_time () }; \
|
||||||
|
srand (now.u); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user