From 7566f32c194bc4e62e89adc57bfb6104cc99458e Mon Sep 17 00:00:00 2001 From: Zeyla Hellyer Date: Fri, 5 Jan 2018 22:26:47 -0800 Subject: Fix permission overwrites in permission building While building permissions in the `Guild::permissions_in` function - which is relied upon by most model functions to check CurrentUser permissions - the channel overwrites of the given channel were iterated over incorrectly. The channel overwrites were iterated over in a non-specified order, resulting in overwrites being applied in a random order. However, Discord operates by applying permissions from a down-top order: role ID 0 is below role ID 1, which is below role ID 2, etc. This means that prior to applying permissions we must first sort by position so that lower positioned roles are iterated over first. --- src/model/guild/mod.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs index bc97ba8..3226067 100644 --- a/src/model/guild/mod.rs +++ b/src/model/guild/mod.rs @@ -1167,6 +1167,8 @@ impl Guild { // First apply the denied permission overwrites for each, then apply // the allowed. + let mut data = Vec::with_capacity(member.roles.len()); + // Roles for overwrite in &channel.permission_overwrites { if let PermissionOverwriteType::Role(role) = overwrite.kind { @@ -1174,10 +1176,18 @@ impl Guild { continue; } - permissions = (permissions & !overwrite.deny) | overwrite.allow; + if let Some(role) = self.roles.get(&role) { + data.push((role.position, overwrite.deny, overwrite.allow)); + } } } + data.sort_by(|a, b| a.0.cmp(&b.0)); + + for overwrite in data { + permissions = (permissions & !overwrite.1) | overwrite.2; + } + // Member for overwrite in &channel.permission_overwrites { if PermissionOverwriteType::Member(user_id) != overwrite.kind { -- cgit v1.2.3