[vlc-devel] [PATCH] playlist: fix vlc_playlist_RequestMove()
Romain Vimont
rom1v at videolabs.io
Wed Jul 3 17:50:19 CEST 2019
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.
---
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 911d831e73..7616021a77 100644
--- a/src/playlist/test.c
+++ b/src/playlist/test.c
@@ -1782,6 +1782,107 @@ test_request_move_adapt(void)
vlc_playlist_Delete(playlist);
}
+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)
{
@@ -2275,6 +2376,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();
--
2.20.1
More information about the vlc-devel
mailing list