vlc | branch: master | Romain Vimont <[email protected]> | Wed Jul 3 17:50:19 2019 +0200| [d3f8647913607552f077be20ace125fd97532422] | committer: Jean-Baptiste Kempf
playlist: fix vlc_playlist_RequestMove() Requesting to move more than 1 item beyond the end of the list with vlc_playlist_RequestMove() resulted in an assertion failure during the actual vlc_playlist_Move(): "target + count <= playlist->items.size". Fix the target index correctly when moving more than 1 item. Signed-off-by: Jean-Baptiste Kempf <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d3f8647913607552f077be20ace125fd97532422 --- src/playlist/request.c | 9 +++-- src/playlist/test.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/src/playlist/request.c b/src/playlist/request.c index 808b88dbc6..a446745ccf 100644 --- a/src/playlist/request.c +++ b/src/playlist/request.c @@ -214,11 +214,14 @@ vlc_playlist_RequestMove(vlc_playlist_t *playlist, vlc_playlist_FindIndices(playlist, items, count, index_hint, &vector); - if (vector.size > 0) + size_t move_count = vector.size; + if (move_count) { size_t size = vlc_playlist_Count(playlist); - if (target >= size) - target = size - 1; + assert(size >= move_count); + /* move at most to the end of the list */ + if (target + move_count > size) + target = size - move_count; /* keep the items in the same order as the request (do not sort them) */ vlc_playlist_MoveBySlices(playlist, vector.data, vector.size, target); diff --git a/src/playlist/test.c b/src/playlist/test.c index aebcfdb9c8..d908a9f55c 100644 --- a/src/playlist/test.c +++ b/src/playlist/test.c @@ -1782,6 +1782,107 @@ test_request_move_adapt(void) } static void +test_request_move_to_end_adapt(void) +{ + vlc_playlist_t *playlist = vlc_playlist_New(NULL); + assert(playlist); + + input_item_t *media[16]; + CreateDummyMediaArray(media, 16); + + /* initial playlist with 15 items */ + int ret = vlc_playlist_Append(playlist, media, 15); + assert(ret == VLC_SUCCESS); + + struct vlc_playlist_callbacks cbs = { + .on_items_moved = callback_on_items_moved, + }; + + struct callback_ctx ctx = CALLBACK_CTX_INITIALIZER; + vlc_playlist_listener_id *listener = + vlc_playlist_AddListener(playlist, &cbs, &ctx, false); + assert(listener); + + vlc_playlist_item_t *dummy = vlc_playlist_item_New(media[15], 0); + assert(dummy); + + /* move items in a wrong order at wrong position, as if the playlist had + * been sorted/shuffled before the request were applied */ + vlc_playlist_item_t *items_to_move[] = { + vlc_playlist_Get(playlist, 7), + vlc_playlist_Get(playlist, 8), + vlc_playlist_Get(playlist, 5), + vlc_playlist_Get(playlist, 12), + dummy, /* inexistant */ + vlc_playlist_Get(playlist, 3), + vlc_playlist_Get(playlist, 13), + vlc_playlist_Get(playlist, 14), + vlc_playlist_Get(playlist, 1), + }; + + /* target 20 is far beyond the end of the list */ + vlc_playlist_RequestMove(playlist, items_to_move, 9, 20, 2); + + vlc_playlist_item_Release(dummy); + + assert(vlc_playlist_Count(playlist) == 15); + + EXPECT_AT(0, 0); + EXPECT_AT(1, 2); + EXPECT_AT(2, 4); + EXPECT_AT(3, 6); + EXPECT_AT(4, 9); + EXPECT_AT(5, 10); + EXPECT_AT(6, 11); + + EXPECT_AT(7, 7); + EXPECT_AT(8, 8); + EXPECT_AT(9, 5); + EXPECT_AT(10, 12); + EXPECT_AT(11, 3); + EXPECT_AT(12, 13); + EXPECT_AT(13, 14); + EXPECT_AT(14, 1); + + /* there are 6 slices to move: 7-8, 5, 12, 3, 13-14, 1 */ + assert(ctx.vec_items_moved.size == 6); + + struct VLC_VECTOR(int) vec = VLC_VECTOR_INITIALIZER; + for (int i = 0; i < 15; ++i) + vlc_vector_push(&vec, i * 10); + + struct items_moved_report report; + vlc_vector_foreach(report, &ctx.vec_items_moved) + /* apply the changes as reported by the callbacks */ + vlc_vector_move_slice(&vec, report.index, report.count, report.target); + + /* the vector items must have been moved the same way as the playlist */ + assert(vec.size == 15); + assert(vec.data[0] == 0); + assert(vec.data[1] == 20); + assert(vec.data[2] == 40); + assert(vec.data[3] == 60); + assert(vec.data[4] == 90); + assert(vec.data[5] == 100); + assert(vec.data[6] == 110); + assert(vec.data[7] == 70); + assert(vec.data[8] == 80); + assert(vec.data[9] == 50); + assert(vec.data[10] == 120); + assert(vec.data[11] == 30); + assert(vec.data[12] == 130); + assert(vec.data[13] == 140); + assert(vec.data[14] == 10); + + vlc_vector_destroy(&vec); + + callback_ctx_destroy(&ctx); + vlc_playlist_RemoveListener(playlist, listener); + DestroyMediaArray(media, 16); + vlc_playlist_Delete(playlist); +} + +static void test_request_goto_with_matching_hint(void) { vlc_playlist_t *playlist = vlc_playlist_New(NULL); @@ -2274,6 +2375,7 @@ int main(void) test_request_move_with_matching_hint(); test_request_move_without_hint(); test_request_move_adapt(); + test_request_move_to_end_adapt(); test_request_goto_with_matching_hint(); test_request_goto_without_hint(); test_request_goto_adapt(); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
