hst/dbus: validate interface strings
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m12s
Test / Hakurei (push) Successful in 3m3s
Test / Hpkg (push) Successful in 3m58s
Test / Sandbox (race detector) (push) Successful in 4m24s
Test / Hakurei (race detector) (push) Successful in 5m11s
Test / Flake checks (push) Successful in 1m22s

This is relocated to hst to validate early.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2025-10-08 04:57:22 +09:00
parent 12ab7ea3b4
commit 9b507715d4
7 changed files with 215 additions and 79 deletions

View File

@@ -1,74 +1,12 @@
package dbus
import (
"strings"
"hakurei.app/hst"
)
// ProxyPair is an upstream dbus address and a downstream socket path.
type ProxyPair [2]string
// interfacesAll returns an iterator over all interfaces specified in c.
func interfacesAll(c *hst.BusConfig) func(yield func(string) bool) {
return func(yield func(string) bool) {
for _, iface := range c.See {
if !yield(iface) {
return
}
}
for _, iface := range c.Talk {
if !yield(iface) {
return
}
}
for _, iface := range c.Own {
if !yield(iface) {
return
}
}
for iface := range c.Call {
if !yield(iface) {
return
}
}
for iface := range c.Broadcast {
if !yield(iface) {
return
}
}
}
}
// checkInterfaces checks [hst.BusConfig] for invalid interfaces based on an undocumented check in xdg-dbus-error,
// returning [BadInterfaceError] if one is encountered.
func checkInterfaces(c *hst.BusConfig, segment string) error {
for iface := range interfacesAll(c) {
/*
xdg-dbus-proxy fails without output when this condition is not met:
char *dot = strrchr (filter->interface, '.');
if (dot != NULL)
{
*dot = 0;
if (strcmp (dot + 1, "*") != 0)
filter->member = g_strdup (dot + 1);
}
trim ".*" since they are removed before searching for '.':
if (g_str_has_suffix (name, ".*"))
{
name[strlen (name) - 2] = 0;
wildcard = TRUE;
}
*/
if strings.IndexByte(strings.TrimSuffix(iface, ".*"), '.') == -1 {
return &BadInterfaceError{iface, segment}
}
}
return nil
}
// Args returns the xdg-dbus-proxy arguments equivalent of [hst.BusConfig].
func Args(c *hst.BusConfig, bus ProxyPair) (args []string) {
argc := 2 + len(c.See) + len(c.Talk) + len(c.Own) + len(c.Call) + len(c.Broadcast)

View File

@@ -10,7 +10,7 @@ import (
"hakurei.app/system/dbus"
)
func TestConfig_Args(t *testing.T) {
func TestConfigArgs(t *testing.T) {
for _, tc := range testCasesExt {
if tc.wantErr {
// args does not check for nulls
@@ -19,9 +19,7 @@ func TestConfig_Args(t *testing.T) {
t.Run("build arguments for "+tc.id, func(t *testing.T) {
if got := dbus.Args(tc.c, tc.bus); !slices.Equal(got, tc.want) {
t.Errorf("Args(%q) = %v, want %v",
tc.bus,
got, tc.want)
t.Errorf("Args: %v, want %v", got, tc.want)
}
})
}

View File

@@ -2,7 +2,6 @@ package dbus
import (
"context"
"fmt"
"io"
"sync"
"syscall"
@@ -16,15 +15,6 @@ import (
// Overriding ProxyName will only affect Proxy instance created after the change.
var ProxyName = "xdg-dbus-proxy"
type BadInterfaceError struct {
Interface string
Segment string
}
func (e *BadInterfaceError) Error() string {
return fmt.Sprintf("bad interface string %q in %s bus configuration", e.Interface, e.Segment)
}
// Proxy holds the state of a xdg-dbus-proxy process, and should never be copied.
type Proxy struct {
helper helper.Helper
@@ -74,13 +64,13 @@ func Finalise(sessionBus, systemBus ProxyPair, session, system *hst.BusConfig) (
var args []string
if session != nil {
if err = checkInterfaces(session, "session"); err != nil {
if err = session.CheckInterfaces("session"); err != nil {
return
}
args = append(args, Args(session, sessionBus)...)
}
if system != nil {
if err = checkInterfaces(system, "system"); err != nil {
if err = system.CheckInterfaces("system"); err != nil {
return
}
args = append(args, Args(system, systemBus)...)