Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions source/actionscript/Common/skyui/filter/IFilter.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
interface skyui.filter.IFilter
Comment thread
zndxcvbn marked this conversation as resolved.
{
// Apply filter on the given array
// public function applyFilter(filteredList: Array);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
161 changes: 95 additions & 66 deletions source/actionscript/Common/skyui/filter/ItemTypeFilter.as
Original file line number Diff line number Diff line change
@@ -1,69 +1,98 @@
class skyui.filter.ItemTypeFilter implements skyui.filter.IFilter
{
var _matcherFunc;
var dispatchEvent;
var _itemFilter = 4294967295;
function ItemTypeFilter()
{
gfx.events.EventDispatcher.initialize(this);
this._matcherFunc = skyui.filter.ItemTypeFilter.entryMatchesFilter;
}
function get itemFilter()
{
return this._itemFilter;
}
function changeFilterFlag(a_newFilter, a_bDoNotUpdate)
{
if(a_bDoNotUpdate == undefined)
{
a_bDoNotUpdate = false;
}
this._itemFilter = a_newFilter;
if(!a_bDoNotUpdate)
{
this.dispatchEvent({type:"filterChange"});
}
}
function setPartitionedFilterMode(a_bPartition)
{
this._matcherFunc = !a_bPartition ? skyui.filter.ItemTypeFilter.entryMatchesFilter : skyui.filter.ItemTypeFilter.entryMatchesPartitionedFilter;
}
function applyFilter(a_filteredList)
{
var _loc2_ = 0;
while(_loc2_ < a_filteredList.length)
{
if(!this._matcherFunc(a_filteredList[_loc2_],this._itemFilter))
{
a_filteredList.splice(_loc2_,1);
_loc2_ = _loc2_ - 1;
}
_loc2_ = _loc2_ + 1;
}
}
function isMatch(a_entry, a_flag)
{
return this._matcherFunc(a_entry,a_flag);
}
static function entryMatchesFilter(a_entry, a_flag)
{
return a_entry != undefined && (a_entry.filterFlag == undefined || (a_entry.filterFlag & a_flag) != 0);
}
static function entryMatchesPartitionedFilter(a_entry, a_flag)
{
if(a_entry == undefined)
{
return false;
}
if(a_flag == 4294967295)
{
return true;
}
var _loc1_ = a_entry.filterFlag;
var _loc4_ = _loc1_ & 0xFF;
var _loc3_ = (_loc1_ & 0xFF00) >>> 8;
var _loc6_ = (_loc1_ & 0xFF0000) >>> 16;
var _loc5_ = (_loc1_ & 0xFF000000) >>> 24;
return _loc4_ == a_flag || _loc3_ == a_flag || _loc6_ == a_flag || _loc5_ == a_flag;
}
/* PRIVATE VARIABLES */

private var _matcherFunc: Function;


/* PROPERTIES */

private var _itemFilter: Number = 0xFFFFFFFF;

function get itemFilter()
Comment thread
zndxcvbn marked this conversation as resolved.
{
return this._itemFilter;
}


/* INITIALIZATION */

public function ItemTypeFilter()
{
gfx.events.EventDispatcher.initialize(this);

this._matcherFunc = skyui.filter.ItemTypeFilter.entryMatchesFilter;
}


/* PUBLIC FUNCTIONS */

// @mixin by gfx.events.EventDispatcher
public var dispatchEvent: Function;
public var dispatchQueue: Function;
public var hasEventListener: Function;
public var addEventListener: Function;
public var removeEventListener: Function;
public var removeAllEventListeners: Function;
public var cleanUpEvents: Function;

public function changeFilterFlag(a_newFilter: Number, a_bDoNotUpdate: Boolean)
{
if (a_bDoNotUpdate == undefined)
a_bDoNotUpdate = false;

this._itemFilter = a_newFilter;

if (!a_bDoNotUpdate)
this.dispatchEvent({type:"filterChange"});
}

public function setPartitionedFilterMode(a_bPartition: Boolean)
{
this._matcherFunc = a_bPartition
? skyui.filter.ItemTypeFilter.entryMatchesPartitionedFilter
: skyui.filter.ItemTypeFilter.entryMatchesFilter;
}

// @override skyui.IFilter
public function applyFilter(a_filteredList: Array)
{
for (var i = 0; i < a_filteredList.length; i++) {
if (!this._matcherFunc(a_filteredList[i], this._itemFilter)) {
a_filteredList.splice(i,1);
i--;
}
}
}

public function isMatch(a_entry: Object, a_flag: Boolean)
{
return this._matcherFunc(a_entry, a_flag);
}


/* PRIVATE FUNCTIONS */

public static function entryMatchesFilter(a_entry: Object, a_flag: Boolean)
Comment thread
zndxcvbn marked this conversation as resolved.
{
return a_entry != undefined &&
(a_entry.filterFlag == undefined || (a_entry.filterFlag & a_flag) != 0);
}

private static function entryMatchesPartitionedFilter(a_entry: Object, a_flag: Boolean)
{
if (a_entry == undefined)
return false;

if (a_flag == 0xFFFFFFFF)
return true;

var flag: Number = a_entry.filterFlag;
var byte0: Number = (flag & 0x000000FF);
var byte1: Number = (flag & 0x0000FF00) >>> 8;
var byte2: Number = (flag & 0x00FF0000) >>> 16;
var byte3: Number = (flag & 0xFF000000) >>> 24;

return byte0 == a_flag || byte1 == a_flag || byte2 == a_flag || byte3 == a_flag;
}
}
109 changes: 64 additions & 45 deletions source/actionscript/Common/skyui/filter/SortFilter.as
Original file line number Diff line number Diff line change
@@ -1,48 +1,67 @@
class skyui.filter.SortFilter implements skyui.filter.IFilter
{
var _sortAttributes;
var _sortOptions;
var dispatchEvent;
function SortFilter()
{
gfx.events.EventDispatcher.initialize(this);
}
function setSortBy(a_sortAttributes, a_sortOptions)
{
if(this._sortAttributes == a_sortAttributes && this._sortOptions == a_sortOptions)
{
return undefined;
}
this._sortAttributes = a_sortAttributes;
this._sortOptions = a_sortOptions;
this.dispatchEvent({type:"filterChange"});
}
function applyFilter(a_filteredList)
{
var _loc5_ = this._sortAttributes[0];
var _loc2_ = 0;
var _loc4_;
while(_loc2_ < a_filteredList.length)
{
_loc4_ = a_filteredList[_loc2_][_loc5_];
if(_loc4_ == null)
{
a_filteredList[_loc2_]._sortFlag = 1;
}
else
{
a_filteredList[_loc2_]._sortFlag = 0;
}
_loc2_ = _loc2_ + 1;
}
this._sortAttributes.unshift("enabled");
this._sortOptions.unshift(Array.NUMERIC | Array.DESCENDING);
this._sortAttributes.unshift("_sortFlag");
this._sortOptions.unshift(Array.NUMERIC);
a_filteredList.sortOn(this._sortAttributes,this._sortOptions);
this._sortAttributes.shift();
this._sortOptions.shift();
this._sortAttributes.shift();
this._sortOptions.shift();
}
/* PRIVATE VARIABLES */

private var _sortAttributes: Array;
private var _sortOptions: Array;


/* INITIALIZATION */

public function SortFilter()
{
gfx.events.EventDispatcher.initialize(this);
}


/* PUBLIC FUNCTIONS */

// @mixin by gfx.events.EventDispatcher
public var dispatchEvent: Function;
public var dispatchQueue: Function;
public var hasEventListener: Function;
public var addEventListener: Function;
public var removeEventListener: Function;
public var removeAllEventListeners: Function;
public var cleanUpEvents: Function;

// Change the filter attributes and options and trigger an update if necessary.
public function setSortBy(a_sortAttributes: Array, a_sortOptions: Array)
{
if (this._sortAttributes == a_sortAttributes && this._sortOptions == a_sortOptions)
return;

this._sortAttributes = a_sortAttributes;
this._sortOptions = a_sortOptions;
Comment on lines +29 to +35

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add defensive guards for unset/null sort config before sorting.

applyFilter assumes _sortAttributes/_sortOptions are initialized and non-empty. If setSortBy is skipped or receives null, this will throw at runtime.

Suggested fix
 public function setSortBy(a_sortAttributes: Array, a_sortOptions: Array)
 {
+    if (a_sortAttributes == null || a_sortOptions == null || a_sortAttributes.length == 0)
+        return;
+
     if (this._sortAttributes == a_sortAttributes && this._sortOptions == a_sortOptions)
         return;
         
     this._sortAttributes = a_sortAttributes;
     this._sortOptions = a_sortOptions;
@@
 public function applyFilter(a_filteredList: Array)
 {
+    if (a_filteredList == null || this._sortAttributes == null || this._sortOptions == null || this._sortAttributes.length == 0)
+        return;
+
     var primaryAttribute = this._sortAttributes[0];

Also applies to: 41-57

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@source/actionscript/Common/skyui/filter/SortFilter.as` around lines 29 - 35,
The sort config can be null/unset causing runtime errors; add defensive guards
in setSortBy and applyFilter to handle null/undefined/empty values: in setSortBy
(function setSortBy) ensure that when a_sortAttributes or a_sortOptions is
null/undefined you assign safe defaults (e.g., empty arrays) and only update
this._sortAttributes/this._sortOptions with validated arrays; in applyFilter
(method applyFilter) early-return or skip sorting when this._sortAttributes or
this._sortOptions are null/empty and ensure any code that iterates or indexes
into these members checks length before use so sorting is only attempted with
valid arrays.


this.dispatchEvent({type: "filterChange"});
}

// @override skyui.filter.IFilter
public function applyFilter(a_filteredList: Array)
{
var primaryAttribute = this._sortAttributes[0];

for (var i = 0; i < a_filteredList.length; i++) {
var t = a_filteredList[i][primaryAttribute];
if (t == null)
a_filteredList[i]._sortFlag = 1;
else
a_filteredList[i]._sortFlag = 0;
}

this._sortAttributes.unshift("enabled");
this._sortOptions.unshift(Array.NUMERIC | Array.DESCENDING);

this._sortAttributes.unshift("_sortFlag");
this._sortOptions.unshift(Array.NUMERIC);

a_filteredList.sortOn(this._sortAttributes, this._sortOptions);

this._sortAttributes.shift();
this._sortOptions.shift();

this._sortAttributes.shift();
this._sortOptions.shift();
}
}