Skip to content

Commit

Permalink
C++: fix a bug in which a substraction could overflow
Browse files Browse the repository at this point in the history
There was an image like this:
```slint
height: 40px
Image {
     width: parent.width;
     height: self.source.height * 1px;
     source: @image-url("....");
}
```

The `y` propery ended inlined like so:
`(40 - the_image.source.get().size().height)/float(2)`
but since height was `unsigned` the C++ rules means that the operation
happens as unsigned and we have an overflow. and `y` turned out to be
very big instead of slightly negative (for image whose height was larger
than 40)
  • Loading branch information
ogoffart committed Mar 5, 2025
1 parent da33ffa commit a6a142f
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 1 deletion.
1 change: 1 addition & 0 deletions internal/compiler/generator/cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3268,6 +3268,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
'&' => "&&",
'|' => "||",
'/' => "/(float)",
'-' => "-(float)", // conversion to float to avoid overflow between unsigned
_ => op.encode_utf8(&mut buffer),
},
)
Expand Down
3 changes: 2 additions & 1 deletion tests/cases/elements/image.slint
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ TestCase := Rectangle {

property <length> img_width: img.width;
property <length> img_height: img.height;
in-out property <float> test_no_overflow: (21 - img.source.width) / 2; // (21 - 320)/2 = -149.5
property <bool> test: img2.source-clip-height * 1px == img2.height && img2.source-clip-width * 1px == img2.width &&
img2.width/1px == img2.source.width - 20 && img3.source.width == 0 && img3.source.height == 0;
img2.width/1px == img2.source.width - 20 && img3.source.width == 0 && img3.source.height == 0 && test_no_overflow == -149.5;
}

/*
Expand Down

0 comments on commit a6a142f

Please sign in to comment.