summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions.c18
-rw-r--r--src/slist.c42
2 files changed, 52 insertions, 8 deletions
diff --git a/src/actions.c b/src/actions.c
index e9c70ae52..c9ca020a0 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -134,6 +134,7 @@ void common_unban(ChannelInfo * ci, char *nick)
char *av[3], **bans;
User *u;
char *host;
+ int matchfound = 0;
if (!ci || !ci->c || !nick) {
return;
@@ -158,19 +159,34 @@ void common_unban(ChannelInfo * ci, char *nick)
anope_cmd_mode(whosends(ci), ci->name, "-b %s", bans[i]);
av[2] = bans[i];
do_cmode(whosends(ci), 3, av);
+ matchfound++;
}
if (host) {
- if (match_userip(bans[i], u, host)) {
+ /* prevent multiple unbans if the first one was successful in
+ locating the ban for us. This is due to match_userip() checks
+ the vhost again, and thus can return false positive results
+ for the function. but won't prevent thus from clearing out
+ the bans against an IP address since the first would fail and
+ the second would match - TSL
+ */
+ if (!matchfound) {
+ if (match_userip(bans[i], u, host)) {
anope_cmd_mode(whosends(ci), ci->name, "-b %s",
bans[i]);
av[2] = bans[i];
do_cmode(whosends(ci), 3, av);
+ }
}
}
+ matchfound = 0;
}
free(bans);
free(av[1]);
}
+ /* host_resolve() sstrdup us this info so we gotta free it */
+ if (host) {
+ free(host);
+ }
}
/*************************************************************************/
diff --git a/src/slist.c b/src/slist.c
index 81bd62ab0..a154cc47e 100644
--- a/src/slist.c
+++ b/src/slist.c
@@ -131,7 +131,7 @@ int slist_delete_range(SList * slist, char *range, slist_delcheckcb_t cb,
...)
{
int count = 0, i, n1, n2;
- va_list args;
+ va_list args, preserve;
va_start(args, cb);
@@ -149,15 +149,26 @@ int slist_delete_range(SList * slist, char *range, slist_delcheckcb_t cb,
}
for (i = n1; i <= n2 && i > 0 && i <= slist->count; i++) {
+
if (!slist->list[i - 1])
continue;
- if (cb && !cb(slist, slist->list[i - 1], args))
+
+ /* copy this off the stack for safety's sake --nenolod */
+ VA_COPY(preserve, args);
+
+ if (cb && !cb(slist, slist->list[i - 1], preserve)) {
+ va_end(preserve);
return -1;
+ }
+ /* if it's to be freed, lets free it */
if (slist->opts && slist->opts->freeitem)
slist->opts->freeitem(slist, slist->list[i - 1]);
slist->list[i - 1] = NULL;
+ /* and release the copied list */
+ va_end(preserve);
+
count++;
}
@@ -193,7 +204,7 @@ int slist_delete_range(SList * slist, char *range, slist_delcheckcb_t cb,
int slist_enum(SList * slist, char *range, slist_enumcb_t cb, ...)
{
int count = 0, i, res;
- va_list args;
+ va_list args, preserve;
va_start(args, cb);
@@ -204,9 +215,18 @@ int slist_enum(SList * slist, char *range, slist_enumcb_t cb, ...)
continue;
}
- res = cb(slist, i + 1, slist->list[i], args);
- if (res < 0)
+ /* copy off stack for safety */
+ VA_COPY(preserve, args);
+
+ res = cb(slist, i + 1, slist->list[i], preserve);
+ if (res < 0) {
+ va_end(preserve);
break;
+ }
+
+ /* and release our copy */
+ va_end(preserve);
+
count += res;
}
} else {
@@ -230,10 +250,18 @@ int slist_enum(SList * slist, char *range, slist_enumcb_t cb, ...)
continue;
}
- res = cb(slist, i, slist->list[i - 1], args);
- if (res < 0)
+ /* copy off stack for safety */
+ VA_COPY(preserve, args);
+
+ res = cb(slist, i, slist->list[i - 1], preserve);
+ if (res < 0) {
+ va_end(preserve);
break;
+ }
count += res;
+
+ /* and release our copy */
+ va_end(preserve);
}
if (res < -1)
break;