瀏覽代碼

fix critical bugs in RENAME

Channel rename (both of registered and unregistered channels) would leave
the old name unreclaimable.
tags/v2.5.0-rc1
Shivaram Lingamneni 3 年之前
父節點
當前提交
cc2b6d27a0
共有 2 個檔案被更改,包括 39 行新增29 行删除
  1. 38
    28
      irc/channelmanager.go
  2. 1
    1
      irc/handlers.go

+ 38
- 28
irc/channelmanager.go 查看文件

@@ -106,7 +106,7 @@ func (cm *ChannelManager) Join(client *Client, name string, key string, isSajoin
106 106
 				return nil, errInsufficientPrivs
107 107
 			}
108 108
 			// enforce confusables
109
-			if cm.chansSkeletons.Has(skeleton) || (!registered && cm.registeredSkeletons.Has(skeleton)) {
109
+			if !registered && (cm.chansSkeletons.Has(skeleton) || cm.registeredSkeletons.Has(skeleton)) {
110 110
 				return nil, errConfusableIdentifier
111 111
 			}
112 112
 			entry = &channelManagerEntry{
@@ -219,10 +219,13 @@ func (cm *ChannelManager) SetRegistered(channelName string, account string) (err
219 219
 	if err != nil {
220 220
 		return err
221 221
 	}
222
+	// transfer the skeleton from chansSkeletons to registeredSkeletons
223
+	skeleton := entry.skeleton
224
+	delete(cm.chansSkeletons, skeleton)
225
+	entry.skeleton = ""
226
+	cm.chans[cfname] = entry
222 227
 	cm.registeredChannels.Add(cfname)
223
-	if skel, err := Skeleton(channel.Name()); err == nil {
224
-		cm.registeredSkeletons.Add(skel)
225
-	}
228
+	cm.registeredSkeletons.Add(skeleton)
226 229
 	return nil
227 230
 }
228 231
 
@@ -252,8 +255,12 @@ func (cm *ChannelManager) SetUnregistered(channelName string, account string) (e
252 255
 	if entry != nil {
253 256
 		entry.channel.SetUnregistered(account)
254 257
 		delete(cm.registeredChannels, cfname)
258
+		// transfer the skeleton from registeredSkeletons to chansSkeletons
255 259
 		if skel, err := Skeleton(entry.channel.Name()); err == nil {
256 260
 			delete(cm.registeredSkeletons, skel)
261
+			cm.chansSkeletons.Add(skel)
262
+			entry.skeleton = skel
263
+			cm.chans[cfname] = entry
257 264
 		}
258 265
 	}
259 266
 	return nil
@@ -261,7 +268,7 @@ func (cm *ChannelManager) SetUnregistered(channelName string, account string) (e
261 268
 
262 269
 // Rename renames a channel (but does not notify the members)
263 270
 func (cm *ChannelManager) Rename(name string, newName string) (err error) {
264
-	cfname, err := CasefoldChannel(name)
271
+	oldCfname, err := CasefoldChannel(name)
265 272
 	if err != nil {
266 273
 		return errNoSuchChannel
267 274
 	}
@@ -289,41 +296,44 @@ func (cm *ChannelManager) Rename(name string, newName string) (err error) {
289 296
 	cm.Lock()
290 297
 	defer cm.Unlock()
291 298
 
292
-	if newCfname == cfname {
293
-		entry := cm.chans[cfname]
294
-		if entry == nil || !entry.channel.IsLoaded() {
295
-			return errNoSuchChannel
296
-		}
297
-		entry.channel.Rename(newName, cfname)
298
-		return nil
299
-	}
300
-	if cm.chans[newCfname] != nil || cm.registeredChannels.Has(newCfname) {
301
-		return errChannelNameInUse
302
-	}
303
-	if cm.chansSkeletons.Has(newSkeleton) || cm.registeredSkeletons.Has(newSkeleton) {
304
-		return errChannelNameInUse
305
-	}
306
-	entry := cm.chans[cfname]
299
+	entry := cm.chans[oldCfname]
307 300
 	if entry == nil || !entry.channel.IsLoaded() {
308 301
 		return errNoSuchChannel
309 302
 	}
310 303
 	channel = entry.channel
311 304
 	info = channel.ExportRegistration(IncludeInitial)
312 305
 	registered := info.Founder != ""
313
-	delete(cm.chans, cfname)
306
+
307
+	oldSkeleton, err := Skeleton(info.Name)
308
+	if err != nil {
309
+		return errNoSuchChannel // ugh
310
+	}
311
+
312
+	if newCfname != oldCfname {
313
+		if cm.chans[newCfname] != nil || cm.registeredChannels.Has(newCfname) {
314
+			return errChannelNameInUse
315
+		}
316
+	}
317
+
318
+	if oldSkeleton != newSkeleton {
319
+		if cm.chansSkeletons.Has(newSkeleton) || cm.registeredSkeletons.Has(newSkeleton) {
320
+			return errConfusableIdentifier
321
+		}
322
+	}
323
+
324
+	delete(cm.chans, oldCfname)
325
+	if !registered {
326
+		entry.skeleton = newSkeleton
327
+	}
314 328
 	cm.chans[newCfname] = entry
315 329
 	if registered {
316
-		delete(cm.registeredChannels, cfname)
317
-		if oldSkeleton, err := Skeleton(info.Name); err == nil {
318
-			delete(cm.registeredSkeletons, oldSkeleton)
319
-		}
330
+		delete(cm.registeredChannels, oldCfname)
320 331
 		cm.registeredChannels.Add(newCfname)
332
+		delete(cm.registeredSkeletons, oldSkeleton)
321 333
 		cm.registeredSkeletons.Add(newSkeleton)
322 334
 	} else {
323
-		delete(cm.chansSkeletons, entry.skeleton)
335
+		delete(cm.chansSkeletons, oldSkeleton)
324 336
 		cm.chansSkeletons.Add(newSkeleton)
325
-		entry.skeleton = newSkeleton
326
-		cm.chans[cfname] = entry
327 337
 	}
328 338
 	entry.channel.Rename(newName, newCfname)
329 339
 	return nil

+ 1
- 1
irc/handlers.go 查看文件

@@ -2643,7 +2643,7 @@ func renameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
2643 2643
 	err := server.channels.Rename(oldName, newName)
2644 2644
 	if err == errInvalidChannelName {
2645 2645
 		rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, client.Nick(), utils.SafeErrorParam(newName), client.t(err.Error()))
2646
-	} else if err == errChannelNameInUse {
2646
+	} else if err == errChannelNameInUse || err == errConfusableIdentifier {
2647 2647
 		rb.Add(nil, server.name, "FAIL", "RENAME", "CHANNEL_NAME_IN_USE", oldName, utils.SafeErrorParam(newName), client.t(err.Error()))
2648 2648
 	} else if err != nil {
2649 2649
 		rb.Add(nil, server.name, "FAIL", "RENAME", "CANNOT_RENAME", oldName, utils.SafeErrorParam(newName), client.t("Cannot rename channel"))

Loading…
取消
儲存