From e1758bc0c5d3c217b32d10b8e3af62d778c29bc2 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 23 Jul 2023 18:18:22 +0800 Subject: [PATCH] cgen: fix infix expr with number overflow (fix #18905) (#18936) --- vlib/time/time_windows.c.v | 6 +++--- vlib/v/gen/c/infix.v | 10 ++++++++++ vlib/v/tests/infix_expr_with_overflow_test.v | 14 ++++++++++++++ vlib/x/ttf/common.v | 2 +- vlib/x/ttf/render_sokol_cpu.v | 6 +++--- vlib/x/ttf/ttf.v | 12 ++++++------ vlib/x/ttf/ttf_test.v | 2 +- 7 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 vlib/v/tests/infix_expr_with_overflow_test.v diff --git a/vlib/time/time_windows.c.v b/vlib/time/time_windows.c.v index 460ed22935..b14e011a15 100644 --- a/vlib/time/time_windows.c.v +++ b/vlib/time/time_windows.c.v @@ -118,7 +118,7 @@ pub fn (t Time) local() Time { hour: st_local.hour minute: st_local.minute second: st_local.second // These are the same - microsecond: st_local.millisecond * 1000 + microsecond: int(st_local.millisecond) * 1000 unix: st_local.unix_time() } return t_local @@ -141,7 +141,7 @@ fn win_now() Time { hour: st_local.hour minute: st_local.minute second: st_local.second - microsecond: st_local.millisecond * 1000 + microsecond: int(st_local.millisecond) * 1000 unix: st_local.unix_time() is_local: true } @@ -163,7 +163,7 @@ fn win_utc() Time { hour: st_utc.hour minute: st_utc.minute second: st_utc.second - microsecond: st_utc.millisecond * 1000 + microsecond: int(st_utc.millisecond) * 1000 unix: st_utc.unix_time() is_local: false } diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index 2e6e28087a..b527ec6cd0 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -1025,6 +1025,13 @@ fn (mut g Gen) gen_is_none_check(node ast.InfixExpr) { // It handles auto dereferencing of variables, as well as automatic casting // (see Gen.expr_with_cast for more details) fn (mut g Gen) gen_plain_infix_expr(node ast.InfixExpr) { + needs_cast := node.left_type.is_number() && node.right_type.is_number() + && node.op in [.plus, .minus, .mul, .div, .mod] && !(g.pref.translated + || g.file.is_translated) + if needs_cast { + typ_str := g.typ(node.promoted_type) + g.write('(${typ_str})(') + } if node.left_type.is_ptr() && node.left.is_auto_deref_var() { g.write('*') } @@ -1036,6 +1043,9 @@ fn (mut g Gen) gen_plain_infix_expr(node ast.InfixExpr) { } else { g.expr_with_cast(node.right, node.right_type, node.left_type) } + if needs_cast { + g.write(')') + } } fn (mut g Gen) op_arg(expr ast.Expr, expected ast.Type, got ast.Type) { diff --git a/vlib/v/tests/infix_expr_with_overflow_test.v b/vlib/v/tests/infix_expr_with_overflow_test.v new file mode 100644 index 0000000000..f3588b46e4 --- /dev/null +++ b/vlib/v/tests/infix_expr_with_overflow_test.v @@ -0,0 +1,14 @@ +fn test_infix_expr_with_overflow() { + a := u8(255) + b := u8(1) + c := a + b + + println(c) + assert c == 0 + + println(a + b) + assert a + b == 0 + + println(a + b < a) + assert a + b < a +} diff --git a/vlib/x/ttf/common.v b/vlib/x/ttf/common.v index 40793b810a..307d6f0662 100644 --- a/vlib/x/ttf/common.v +++ b/vlib/x/ttf/common.v @@ -72,7 +72,7 @@ fn (mut bmp BitMap) format_texture() { x[i + 1] = g x[i + 2] = b // alpha - x[i + 3] = u8(u16(a * data) >> 8) + x[i + 3] = u8(u16(u16(a) * data) >> 8) } else { x[i + 0] = b_r x[i + 1] = b_g diff --git a/vlib/x/ttf/render_sokol_cpu.v b/vlib/x/ttf/render_sokol_cpu.v index 6379d5434c..673f78f9ef 100644 --- a/vlib/x/ttf/render_sokol_cpu.v +++ b/vlib/x/ttf/render_sokol_cpu.v @@ -42,13 +42,13 @@ pub fn (mut tf_skl TTF_render_Sokol) create_text(in_txt string, in_font_size f32 // Formula: (font_size * device dpi) / (72dpi * em_unit) // scale := ((1.0 * devide_dpi )/ f32(72 * tf_skl.bmp.tf.units_per_em))* font_size - scale := f32(font_size * device_dpi) / f32(72 * tf_skl.bmp.tf.units_per_em) + scale := f32(font_size * device_dpi) / f32(72 * int(tf_skl.bmp.tf.units_per_em)) // dprintln("Scale: $scale") tf_skl.bmp.scale = scale * scale_reduct w, h := tf_skl.bmp.get_bbox(in_txt) tf_skl.bmp.width = int(w) - tf_skl.bmp.height = int((h + 8)) + tf_skl.bmp.height = int(h + 8) sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp // RAM buffer @@ -77,7 +77,7 @@ pub fn (mut tf_skl TTF_render_Sokol) create_text_block(in_txt string, in_w int, font_size := in_font_size //* scale_reduct // Formula: (font_size * device dpi) / (72dpi * em_unit) // scale := ((1.0 * devide_dpi )/ f32(72 * tf_skl.bmp.tf.units_per_em))* font_size - scale := f32(font_size * device_dpi) / f32(72 * tf_skl.bmp.tf.units_per_em) + scale := f32(font_size * device_dpi) / f32(72 * int(tf_skl.bmp.tf.units_per_em)) // dprintln("Scale: $scale") tf_skl.bmp.scale = scale * scale_reduct diff --git a/vlib/x/ttf/ttf.v b/vlib/x/ttf/ttf.v index 505c548f3a..513ef30a4c 100644 --- a/vlib/x/ttf/ttf.v +++ b/vlib/x/ttf/ttf.v @@ -162,17 +162,17 @@ pub fn (mut tf TTF_File) get_horizontal_metrics(glyph_index u16) (int, int) { mut advance_width := 0 mut left_side_bearing := 0 if glyph_index < tf.num_of_long_hor_metrics { - offset += glyph_index * 4 + offset += u32(glyph_index) * 4 tf.pos = offset advance_width = tf.get_u16() left_side_bearing = tf.get_i16() // dprintln("${glyph_index} aw:${advance_width} lsb:${left_side_bearing}") } else { // read the last entry of the hMetrics array - tf.pos = offset + (tf.num_of_long_hor_metrics - 1) * 4 + tf.pos = offset + u32(tf.num_of_long_hor_metrics - 1) * 4 advance_width = tf.get_u16() - tf.pos = offset + tf.num_of_long_hor_metrics * 4 + - 2 * (glyph_index - tf.num_of_long_hor_metrics) + tf.pos = offset + u32(tf.num_of_long_hor_metrics) * 4 + + 2 * u32(glyph_index - tf.num_of_long_hor_metrics) left_side_bearing = tf.get_fword() } tf.pos = old_pos @@ -757,7 +757,7 @@ fn (mut tf TTF_File) read_name_table() { offset := tf.get_u16() old_pos := tf.pos - tf.pos = table_offset + string_offset + offset + tf.pos = u32(table_offset) + u32(string_offset) + u32(offset) mut name := '' if platform_id == 0 || platform_id == 3 { @@ -929,7 +929,7 @@ fn (mut tm TrueTypeCmap) map_4(char_code int, mut tf TTF_File) int { if segment.start_code <= char_code && segment.end_code >= char_code { mut index := (segment.id_delta + char_code) & 0xffff if segment.id_range_offset > 0 { - glyph_index_address := segment.id_range_offset + + glyph_index_address := u32(segment.id_range_offset) + 2 * u32(char_code - segment.start_code) tf.pos = glyph_index_address index = tf.get_u16() diff --git a/vlib/x/ttf/ttf_test.v b/vlib/x/ttf/ttf_test.v index a64ba6e2ac..6f1b54bbe8 100644 --- a/vlib/x/ttf/ttf_test.v +++ b/vlib/x/ttf/ttf_test.v @@ -179,7 +179,7 @@ fn test_main() { font_size := 20 device_dpi := 72 - scale := f32(font_size * device_dpi) / f32(72 * tf.units_per_em) + scale := f32(font_size * device_dpi) / f32(72 * int(tf.units_per_em)) mut bmp := ttf.BitMap{ tf: &tf