Galène videoconferencing server discussion list archives
 help / color / mirror / Atom feed
From: Juliusz Chroboczek <jch@irif.fr>
To: Z0T <zot@mochela.it>
Cc: galene@lists.galene.org
Subject: [Galene] Re: forbid presenting probably bug
Date: Thu, 22 Oct 2026 01:48:58 +0200	[thread overview]
Message-ID: <87wlraty1h.wl-jch@irif.fr> (raw)
In-Reply-To: <179258447150.1137.1616866743788355246@gauss>

> Cause: remove() in rtpconn/webclient.go does append(l[:i], l[i+1:]...),
> which modifies the backing array in place. But c.permissions is not always
> a private slice

Good catch.

What do you think of the following?

diff --git a/rtpconn/webclient.go b/rtpconn/webclient.go
index ed22403..ad40095 100644
--- a/rtpconn/webclient.go
+++ b/rtpconn/webclient.go
@@ -939,22 +939,25 @@ type kickAction struct {
 
 var errEmptyId = group.ProtocolError("empty id")
 
-func remove(v string, l []string) []string {
-	for i, w := range l {
-		if v == w {
-			l = append(l[:i], l[i+1:]...)
-			return l
-		}
+// remove removes an element from a slice.  In order to avoid sharing
+// issues, it performs a deep copy if the list changes.
+func remove(l *[]string, v string) {
+	if !slices.Contains(*l, v) {
+		return
 	}
-	return l
+	ll := slices.Clone(*l)
+	ll = slices.DeleteFunc(ll, func(w string) bool { return v == w })
+	*l = ll
 }
 
-func addnew(v string, l []string) []string {
-	if slices.Contains(l, v) {
-		return l
+// addnew is like remove, but it adds an element.
+func addnew(l *[]string, v string) {
+	if slices.Contains(*l, v) {
+		return
 	}
-	l = append(l, v)
-	return l
+	ll := slices.Clone(*l)
+	ll = append(ll, v)
+	*l = ll
 }
 
 func clientLoop(c *webClient, ws *websocket.Conn, versionError bool) error {
@@ -1218,22 +1221,22 @@ func handleAction(c *webClient, a any) error {
 	case changePermissionsAction:
 		switch a.kind {
 		case "op":
-			c.permissions = addnew("op", c.permissions)
+			addnew(&c.permissions, "op")
 			g := c.Group()
 			if g != nil && g.Description().AllowRecording {
-				c.permissions = addnew("record", c.permissions)
+				addnew(&c.permissions, "record")
 			}
 		case "unop":
-			c.permissions = remove("op", c.permissions)
-			c.permissions = remove("record", c.permissions)
+			remove(&c.permissions, "op")
+			remove(&c.permissions, "record")
 		case "present":
-			c.permissions = addnew("present", c.permissions)
+			addnew(&c.permissions, "present")
 		case "unpresent":
-			c.permissions = remove("present", c.permissions)
+			remove(&c.permissions, "present")
 		case "shutup":
-			c.permissions = remove("message", c.permissions)
+			remove(&c.permissions, "message")
 		case "unshutup":
-			c.permissions = addnew("message", c.permissions)
+			addnew(&c.permissions, "message")
 		default:
 			return group.UserError("unknown permission")
 		}

           reply	other threads:[~2026-10-21 23:49 UTC|newest]

Thread overview: expand[flat|nested]  mbox.gz  Atom feed
 [parent not found: <179258447150.1137.1616866743788355246@gauss>]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.galene.org/postorius/lists/galene.lists.galene.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wlraty1h.wl-jch@irif.fr \
    --to=jch@irif.fr \
    --cc=galene@lists.galene.org \
    --cc=zot@mochela.it \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox