Переглянути джерело

fix #2063

In #2058 we introduced two bugs:

* A nil dereference when an outside user attempts to speak
* Ordinary copy of a modes.ModeSet (which should only be accessed via atomics)

This fixes both issues.
tags/v2.12.0-rc1
Shivaram Lingamneni 1 рік тому
джерело
коміт
e84793d7ee
1 змінених файлів з 10 додано та 4 видалено
  1. 10
    4
      irc/channel.go

+ 10
- 4
irc/channel.go Переглянути файл

@@ -1228,20 +1228,26 @@ func (channel *Channel) CanSpeak(client *Client) (bool, modes.Mode) {
1228 1228
 	channel.stateMutex.RLock()
1229 1229
 	memberData, hasClient := channel.members[client]
1230 1230
 	channel.stateMutex.RUnlock()
1231
-	clientModes := memberData.modes
1231
+
1232
+	highestMode := func() modes.Mode {
1233
+		if !hasClient {
1234
+			return modes.Mode(0)
1235
+		}
1236
+		return memberData.modes.HighestChannelUserMode()
1237
+	}
1232 1238
 
1233 1239
 	if !hasClient && channel.flags.HasMode(modes.NoOutside) {
1234 1240
 		// TODO: enforce regular +b bans on -n channels?
1235 1241
 		return false, modes.NoOutside
1236 1242
 	}
1237
-	if channel.isMuted(client) && clientModes.HighestChannelUserMode() == modes.Mode(0) {
1243
+	if channel.isMuted(client) && highestMode() == modes.Mode(0) {
1238 1244
 		return false, modes.BanMask
1239 1245
 	}
1240
-	if channel.flags.HasMode(modes.Moderated) && clientModes.HighestChannelUserMode() == modes.Mode(0) {
1246
+	if channel.flags.HasMode(modes.Moderated) && highestMode() == modes.Mode(0) {
1241 1247
 		return false, modes.Moderated
1242 1248
 	}
1243 1249
 	if channel.flags.HasMode(modes.RegisteredOnlySpeak) && client.Account() == "" &&
1244
-		clientModes.HighestChannelUserMode() == modes.Mode(0) {
1250
+		highestMode() == modes.Mode(0) {
1245 1251
 		return false, modes.RegisteredOnlySpeak
1246 1252
 	}
1247 1253
 	return true, modes.Mode('?')

Завантаження…
Відмінити
Зберегти