ssahani / rpms / freeradius

Forked from rpms/freeradius 5 years ago
Clone
61475b9
commit c0f670c233e9562118648af641d4f8d182350f31
61475b9
Author: Arran Cudbard-Bell <a.cudbardb@freeradius.org>
61475b9
Date:   Fri May 16 11:38:22 2014 +0100
61475b9
61475b9
    Make the foreach code slightly more sane. Reliably reproduces the issue described by #639
61475b9
61475b9
diff --git a/src/main/modcall.c b/src/main/modcall.c
61475b9
index 3dd0828..7a44bf2 100644
61475b9
--- a/src/main/modcall.c
61475b9
+++ b/src/main/modcall.c
61475b9
@@ -608,9 +608,9 @@ redo:
61475b9
 	 */
61475b9
 	if (c->type == MOD_FOREACH) {
61475b9
 		int i, foreach_depth = -1;
61475b9
-		VALUE_PAIR *vps, **tail, *vp;
61475b9
+		VALUE_PAIR *vps, *vp;
61475b9
 		modcall_stack_entry_t *next = NULL;
61475b9
-		vp_cursor_t cursor;
61475b9
+		vp_cursor_t cursor, copy;
61475b9
 		modgroup *g = mod_callabletogroup(c);
61475b9
 
61475b9
 		if (depth >= MODCALL_STACK_MAX) {
61475b9
@@ -645,31 +645,35 @@ redo:
61475b9
 		}
61475b9
 
61475b9
 		/*
61475b9
-		 *	Copy the VPs from the original request.
61475b9
+		 *	Copy the VPs from the original request, this ensures deterministic
61475b9
+		 *	behaviour if someone decides to add or remove VPs in the set were
61475b9
+		 *	iterating over.
61475b9
 		 */
61475b9
-		fr_cursor_init(&cursor, &vp);
61475b9
-		/* Prime the cursor. */
61475b9
-		cursor.found = cursor.current;
61475b9
-
61475b9
 		vps = NULL;
61475b9
-		tail = &vps;
61475b9
 
61475b9
-		while (vp) {
61475b9
-			*tail = paircopyvp(request, vp);
61475b9
-			if (!*tail) break;
61475b9
+		fr_cursor_init(&cursor, &vp);
61475b9
 
61475b9
-			tail = &((*tail)->next); /* really should be using cursors... */
61475b9
+		/* Prime the cursor. */
61475b9
+		cursor.found = cursor.current;
61475b9
+		for (fr_cursor_init(&copy, &vps;;
61475b9
+		     vp;
61475b9
+		     vp = fr_cursor_next_by_da(&cursor, vp->da, g->vpt->attribute.tag)) {
61475b9
+		     VALUE_PAIR *tmp;
61475b9
 
61475b9
-			vp = fr_cursor_next_by_da(&cursor, vp->da, g->vpt->attribute.tag);
61475b9
+		     MEM(tmp = paircopyvp(request, vp));
61475b9
+		     fr_cursor_insert(&copy, tmp);
61475b9
 		}
61475b9
 
61475b9
-		RDEBUG2("%.*sforeach %s ", depth + 1, modcall_spaces,
61475b9
-			c->name);
61475b9
+		RDEBUG2("%.*sforeach %s ", depth + 1, modcall_spaces, c->name);
61475b9
+
61475b9
 		rad_assert(vps != NULL);
61475b9
 
61475b9
-		for (vp = fr_cursor_init(&cursor, &vps;;
61475b9
+		/*
61475b9
+		 *	This is the actual body of the foreach loop
61475b9
+		 */
61475b9
+		for (vp = fr_cursor_first(©);
61475b9
 		     vp != NULL;
61475b9
-		     vp = fr_cursor_next(&cursor)) {
61475b9
+		     vp = fr_cursor_next(&copy)) {
61475b9
 #ifndef NDEBUG
61475b9
 			if (fr_debug_flag >= 2) {
61475b9
 				char buffer[1024];
61475b9
@@ -709,7 +713,7 @@ redo:
61475b9
 			}
61475b9
 		} /* loop over VPs */
61475b9
 
61475b9
-		talloc_free(vps);
61475b9
+		pairfree(&vps;;
61475b9
 
61475b9
 		rad_assert(next != NULL);
61475b9
 		result = next->result;
61475b9
61475b9
commit 860f645668b9604c897c4ee1338ecfeb88cdd75a
61475b9
Author: Arran Cudbard-Bell <a.cudbardb@freeradius.org>
61475b9
Date:   Fri May 16 12:32:12 2014 +0100
61475b9
61475b9
    Don't free foreach VPs on break #639
61475b9
    
61475b9
    Wwe go back up the stack in an orderly way and don't need this hack anymore
61475b9
61475b9
diff --git a/src/main/modcall.c b/src/main/modcall.c
61475b9
index 7a44bf2..5785643 100644
61475b9
--- a/src/main/modcall.c
61475b9
+++ b/src/main/modcall.c
61475b9
@@ -732,9 +732,7 @@ redo:
61475b9
 		for (i = 8; i >= 0; i--) {
61475b9
 			copy_p = request_data_get(request, radius_get_vp, i);
61475b9
 			if (copy_p) {
61475b9
-				RDEBUG2("%.*s # break Foreach-Variable-%d", depth + 1,
61475b9
-					modcall_spaces, i);
61475b9
-				pairfree(copy_p);
61475b9
+				RDEBUG2("%.*s # break Foreach-Variable-%d", depth + 1, modcall_spaces, i);
61475b9
 				break;
61475b9
 			}
61475b9
 		}
61475b9