Fixed Logic conflict between filter_list.js and /admin.php?users/list

PaulB

Well-known member
There's a logic error in the way filter_list.js behaves on /admin.php?users/list that can potentially cause 400 Bad Request errors over time. filter_list.js creates cookies of the form xf_FilterList_{action}, where {action} is the action attribute of the form with all non-alphanumeric characters removed.

If /admin.php?users/list has been reached by submitting /admin.php?users/search, the form action will contain a querystring with the search criteria. This means that each search receives a unique action, and therefore a unique filter cookie.

Over time, as admins search and filter users, this creates an excess of cookies, which could potentially result in an error such as the following:
Code:
400 Bad Request
Request Header Or Cookie Too Large
This issue potentially exists with other forms as well.

Here's a patch that fixes the issue in XenForo 1.5.9 (ensure the mix of tabs and spaces is preserved):
Code:
diff --git a/xenforo/public/js/xenforo/filter_list.js b/xenforo/public/js/xenforo/filter_list.js
index ae1cde31..3cbe171e 100644
--- a/public/js/xenforo/filter_list.js
+++ b/public/js/xenforo/filter_list.js
@@ -13 +13 @@ prefix:c?1:0}},b.context(this,"filterAjax"),{type:"GET"}):(a=this.applyFilter(th
-this.lookUpUrl&&b(".PageNav").hide();this.removeAjaxResults();if(a.length){this.$ajaxResults=a;this.showHideNoResults(!1);this.$list.append(a);a.xfActivate();var a=a.filter(".listItem").add(a.find(".listItem")),c=[];a.each(function(a,e){c[a]=new XenForo.FilterListItem(b(e))});this.applyFilter(c);this.$listCounter.text(a.length)}else this.$listCounter.text(0),this.showHideNoResults(!0);this.handleLast()}},getCookieName:function(){return"FilterList_"+encodeURIComponent(this.$form.attr("action")).replace(/[\.\+\/]|(%([0-9a-f]{2}|u\d+))/gi,
+this.lookUpUrl&&b(".PageNav").hide();this.removeAjaxResults();if(a.length){this.$ajaxResults=a;this.showHideNoResults(!1);this.$list.append(a);a.xfActivate();var a=a.filter(".listItem").add(a.find(".listItem")),c=[];a.each(function(a,e){c[a]=new XenForo.FilterListItem(b(e))});this.applyFilter(c);this.$listCounter.text(a.length)}else this.$listCounter.text(0),this.showHideNoResults(!0);this.handleLast()}},getCookieName:function(){return"FilterList_"+encodeURIComponent(this.$form.attr("action")).replace(/\?.*|[\.\+\/]|(%([0-9a-f]{2}|u\d+))/gi,
diff --git a/xenforo/public/js/xenforo/full/filter_list.js b/xenforo/public/js/xenforo/full/filter_list.js
index eb38d9ab..1ae4b5df 100644
--- a/public/js/xenforo/full/filter_list.js
+++ b/public/js/xenforo/full/filter_list.js
@@ -315 +315 @@
-			return 'FilterList_' + encodeURIComponent(this.$form.attr('action')).replace(/[\.\+\/]|(%([0-9a-f]{2}|u\d+))/gi, '');
+			return 'FilterList_' + encodeURIComponent(this.$form.attr('action')).replace(/\?.*|[\.\+\/]|(%([0-9a-f]{2}|u\d+))/gi, '');
 

Attachments

I've taken a different approach here, but this is roughly fixed. If I read your diff correctly, you are stripping anything after the ?, which means that every form would resolve to "adminphp" which would apply that filtering everywhere. I have adjusted this to pull out the first value after the ? if it's not a key-value pair (like "users/list") and use that if available. If there's nothing available, then we'll use bits from before the query string. This will still create distinct cookies (which is necessary for correct functioning of the system), but the names will generally be much more limited and there won't be distinct entries per search here.
 
Top Bottom