Mir

Merge lp:~vanvugt/mir/cursor-stride into lp:mir

Proposed by Daniel van Vugt
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 2067
Proposed branch: lp:~vanvugt/mir/cursor-stride
Merge into: lp:mir
Diff against target: 68 lines (+24/-12)
2 files modified
src/platform/graphics/mesa/cursor.cpp (+18/-11)
tests/unit-tests/graphics/mesa/test_cursor.cpp (+6/-1)
To merge this branch: bzr merge lp:~vanvugt/mir/cursor-stride
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Cemil Azizoglu (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Robert Carr (community) Approve
Alan Griffiths Needs Fixing
Kevin DuBois (community) Needs Fixing
Review via email: mp+241950@code.launchpad.net

Commit message

Fix cursor stride calculation that could lead to a corrupt cursor
image (LP: #1391975)

To post a comment you must log in.
Revision history for this message
Kevin DuBois (kdub) wrote :

47 + write_buffer_data_locked(lg, padded, padded_size);
48 + delete[] padded;
If write_buffer_data_locked throws (which it can if gbm_bo_write fails), we leak padded.

looks good otherwise

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Lack of exception safety. One solution:

25 + auto padded = new uint8_t[padded_size];

    std::unique_ptr<uint8_t[]> const padded{new uint8_t[padded_size]};

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

Ok with already mentioned fix.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Approved after the aforementioned fixes.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platform/graphics/mesa/cursor.cpp'
2--- src/platform/graphics/mesa/cursor.cpp 2014-10-01 06:25:56 +0000
3+++ src/platform/graphics/mesa/cursor.cpp 2014-11-18 03:28:01 +0000
4@@ -101,28 +101,35 @@
5
6 void mgm::Cursor::pad_and_write_image_data_locked(std::lock_guard<std::mutex> const& lg, CursorImage const& image)
7 {
8- uint32_t const* image_argb = static_cast<uint32_t const*>(image.as_argb_8888());
9+ auto image_argb = static_cast<uint8_t const*>(image.as_argb_8888());
10 auto image_width = image.size().width.as_uint32_t();
11 auto image_height = image.size().height.as_uint32_t();
12+ auto image_stride = image_width * 4;
13
14 if (image_width > buffer_width || image_height > buffer_height)
15 {
16 BOOST_THROW_EXCEPTION(std::logic_error("Image is too big for GBM cursor buffer"));
17 }
18
19- uint32_t pixels[buffer_width*buffer_height] {};
20- // 'pixels' is initialized to transparent so we just need to copy the initial image
21- // in to the top left corner.
22- for (unsigned int i = 0; i < image_height; i++)
23+ size_t buffer_stride = gbm_bo_get_stride(buffer); // in bytes
24+ size_t padded_size = buffer_stride * buffer_height;
25+ auto padded = std::unique_ptr<uint8_t[]>(new uint8_t[padded_size]);
26+ size_t rhs_padding = buffer_stride - image_stride;
27+
28+ uint8_t* dest = &padded[0];
29+ uint8_t const* src = image_argb;
30+
31+ for (unsigned int y = 0; y < image_height; y++)
32 {
33- for (unsigned int j = 0; j < image_width; j++)
34- {
35- pixels[buffer_width*i+j] = image_argb[image_width*i + j];
36- }
37+ memcpy(dest, src, image_stride);
38+ memset(dest + image_stride, 0, rhs_padding);
39+ dest += buffer_stride;
40+ src += image_stride;
41 }
42
43- auto const count = buffer_width * buffer_height * sizeof(uint32_t);
44- write_buffer_data_locked(lg, pixels, count);
45+ memset(dest, 0, buffer_stride * (buffer_height - image_height));
46+
47+ write_buffer_data_locked(lg, &padded[0], padded_size);
48 }
49
50 void mgm::Cursor::show(CursorImage const& cursor_image)
51
52=== modified file 'tests/unit-tests/graphics/mesa/test_cursor.cpp'
53--- tests/unit-tests/graphics/mesa/test_cursor.cpp 2014-10-01 06:25:56 +0000
54+++ tests/unit-tests/graphics/mesa/test_cursor.cpp 2014-11-18 03:28:01 +0000
55@@ -300,7 +300,12 @@
56 };
57
58 // We expect a full 64x64 pixel write as we will pad missing data with transparency.
59- size_t const buffer_size_bytes{64 * 64 * sizeof(uint32_t)};
60+ size_t const height = 64;
61+ size_t const width = 64;
62+ size_t const stride = width * 4;
63+ size_t const buffer_size_bytes{height * stride};
64+ ON_CALL(mock_gbm, gbm_bo_get_stride(_))
65+ .WillByDefault(Return(stride));
66 EXPECT_CALL(mock_gbm, gbm_bo_write(mock_gbm.fake_gbm.bo, ContainsASingleWhitePixel(), buffer_size_bytes));
67
68 cursor.show(SinglePixelCursorImage());

Subscribers

People subscribed via source and target branches