From: Arran Cudbard-Bell Date: Thu, 25 Jan 2018 03:14:58 +0000 (-0700) Subject: Fix fr_cursor_merge so to_append are always inserted in the correct order X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=38636d6196b0deec28a985ca7148e7f218eb3b1d;p=thirdparty%2Ffreeradius-server.git Fix fr_cursor_merge so to_append are always inserted in the correct order Previously they'd be reversed, which is fine for things that don't care about item ordering, but not fine for attribute lists --- diff --git a/src/lib/util/cursor.c b/src/lib/util/cursor.c index 3fdd08f5e31..ffe95c56af8 100644 --- a/src/lib/util/cursor.c +++ b/src/lib/util/cursor.c @@ -357,14 +357,35 @@ void fr_cursor_insert(fr_cursor_t *cursor, void *v) */ void fr_cursor_merge(fr_cursor_t *cursor, fr_cursor_t *to_append) { - void *v; + void *head = NULL, *next, *v; /* - * We have to do it the expensive way, as to_append - * may use a custom iterator function, and so we only - * merge a subset of the items. + * Build the complete list (in reverse) */ - while ((v = fr_cursor_remove(to_append))) fr_cursor_append(cursor, v); + while ((v = fr_cursor_remove(to_append))) { + *NEXT_PTR(v) = head; + head = v; + } + + if (!head) return; + + /* + * Now insert - The elements end up in + * the correct order without advancing + * the cursor. + */ + v = head; + if (cursor->current) { + do { + next = *NEXT_PTR(v); + fr_cursor_insert(cursor, v); + } while ((v = next)); + } else { + do { + next = *NEXT_PTR(v); + fr_cursor_prepend(cursor, v); + } while ((v = next)); + } } /** Remove the current item