Merge pull request #18394 from containers/renovate/github.com-godbus-dbus-v5-digest

fix(deps): update github.com/godbus/dbus/v5 digest to 6cc540d
This commit is contained in:
OpenShift Merge Robot 2023-05-03 08:17:44 -04:00 committed by GitHub
commit f149d49335
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 247 additions and 143 deletions

2
go.mod
View File

@ -29,7 +29,7 @@ require (
github.com/docker/go-plugins-helpers v0.0.0-20211224144127-6eecb7beb651 github.com/docker/go-plugins-helpers v0.0.0-20211224144127-6eecb7beb651
github.com/docker/go-units v0.5.0 github.com/docker/go-units v0.5.0
github.com/fsnotify/fsnotify v1.6.0 github.com/fsnotify/fsnotify v1.6.0
github.com/godbus/dbus/v5 v5.1.1-0.20221029134443-4b691ce883d5 github.com/godbus/dbus/v5 v5.1.1-0.20230502183206-6cc540df4ec5
github.com/google/gofuzz v1.2.0 github.com/google/gofuzz v1.2.0
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0

4
go.sum
View File

@ -477,8 +477,8 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.1-0.20221029134443-4b691ce883d5 h1:boOtwyhKoC3Aadiw5zbhU54YyCkm9EpZCSN6mOx0KLc= github.com/godbus/dbus/v5 v5.1.1-0.20230502183206-6cc540df4ec5 h1:Nf+zAZaroBWc9zLetbUKzWGLu1xgSa5fTjvtqOLr4ds=
github.com/godbus/dbus/v5 v5.1.1-0.20221029134443-4b691ce883d5/go.mod h1:fXoNnqaUvdKqjJmMGeiBgmRphUg+kO0MT4AhPOP6+Qg= github.com/godbus/dbus/v5 v5.1.1-0.20230502183206-6cc540df4ec5/go.mod h1:fXoNnqaUvdKqjJmMGeiBgmRphUg+kO0MT4AhPOP6+Qg=
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=

10
vendor/github.com/godbus/dbus/v5/.cirrus.yml generated vendored Normal file
View File

@ -0,0 +1,10 @@
freebsd_instance:
image_family: freebsd-13-0
task:
name: Test on FreeBSD
install_script: pkg install -y go119 dbus
test_script: |
/usr/local/etc/rc.d/dbus onestart && \
eval `dbus-launch --sh-syntax` && \
go119 test -v ./...

View File

@ -23,7 +23,7 @@ go get github.com/godbus/dbus/v5
### Usage ### Usage
The complete package documentation and some simple examples are available at The complete package documentation and some simple examples are available at
[godoc.org](http://godoc.org/github.com/godbus/dbus). Also, the [pkg.go.dev](https://pkg.go.dev/github.com/godbus/dbus/v5). Also, the
[_examples](https://github.com/godbus/dbus/tree/master/_examples) directory [_examples](https://github.com/godbus/dbus/tree/master/_examples) directory
gives a short overview over the basic usage. gives a short overview over the basic usage.

View File

@ -484,7 +484,7 @@ func (conn *Conn) Object(dest string, path ObjectPath) BusObject {
return &Object{conn, dest, path} return &Object{conn, dest, path}
} }
func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) { func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) error {
if msg.serial == 0 { if msg.serial == 0 {
msg.serial = conn.getSerial() msg.serial = conn.getSerial()
} }
@ -497,6 +497,7 @@ func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
} else if msg.Type != TypeMethodCall { } else if msg.Type != TypeMethodCall {
conn.serialGen.RetireSerial(msg.serial) conn.serialGen.RetireSerial(msg.serial)
} }
return err
} }
func (conn *Conn) handleSendError(msg *Message, err error) { func (conn *Conn) handleSendError(msg *Message, err error) {
@ -504,6 +505,9 @@ func (conn *Conn) handleSendError(msg *Message, err error) {
conn.calls.handleSendError(msg, err) conn.calls.handleSendError(msg, err)
} else if msg.Type == TypeMethodReply { } else if msg.Type == TypeMethodReply {
if _, ok := err.(FormatError); ok { if _, ok := err.(FormatError); ok {
// Make sure that the caller gets some kind of error response if
// the application code tried to respond, but the resulting message
// was malformed in the end
conn.sendError(err, msg.Headers[FieldDestination].value.(string), msg.Headers[FieldReplySerial].value.(uint32)) conn.sendError(err, msg.Headers[FieldDestination].value.(string), msg.Headers[FieldReplySerial].value.(uint32))
} }
} }
@ -559,7 +563,8 @@ func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call {
<-ctx.Done() <-ctx.Done()
conn.calls.handleSendError(msg, ctx.Err()) conn.calls.handleSendError(msg, ctx.Err())
}() }()
conn.sendMessageAndIfClosed(msg, func() { // error is handled in handleSendError
_ = conn.sendMessageAndIfClosed(msg, func() {
conn.calls.handleSendError(msg, ErrClosed) conn.calls.handleSendError(msg, ErrClosed)
canceler() canceler()
}) })
@ -567,7 +572,8 @@ func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call {
canceler() canceler()
call = &Call{Err: nil, Done: ch} call = &Call{Err: nil, Done: ch}
ch <- call ch <- call
conn.sendMessageAndIfClosed(msg, func() { // error is handled in handleSendError
_ = conn.sendMessageAndIfClosed(msg, func() {
call = &Call{Err: ErrClosed} call = &Call{Err: ErrClosed}
}) })
} }
@ -601,7 +607,8 @@ func (conn *Conn) sendError(err error, dest string, serial uint32) {
if len(e.Body) > 0 { if len(e.Body) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...)) msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...))
} }
conn.sendMessageAndIfClosed(msg, nil) // not much we can do to handle a possible error here
_ = conn.sendMessageAndIfClosed(msg, nil)
} }
// sendReply creates a method reply message corresponding to the parameters and // sendReply creates a method reply message corresponding to the parameters and
@ -618,7 +625,8 @@ func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
if len(values) > 0 { if len(values) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...)) msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
} }
conn.sendMessageAndIfClosed(msg, nil) // not much we can do to handle a possible error here
_ = conn.sendMessageAndIfClosed(msg, nil)
} }
// AddMatchSignal registers the given match rule to receive broadcast // AddMatchSignal registers the given match rule to receive broadcast

View File

@ -42,9 +42,9 @@ func getSessionBusPlatformAddress() (string, error) {
// It tries different techniques employed by different operating systems, // It tries different techniques employed by different operating systems,
// returning the first valid address it finds, or an empty string. // returning the first valid address it finds, or an empty string.
// //
// * /run/user/<uid>/bus if this exists, it *is* the bus socket. present on // - /run/user/<uid>/bus if this exists, it *is* the bus socket. present on
// Ubuntu 18.04 // Ubuntu 18.04
// * /run/user/<uid>/dbus-session: if this exists, it can be parsed for the bus // - /run/user/<uid>/dbus-session: if this exists, it can be parsed for the bus
// address. present on Ubuntu 16.04 // address. present on Ubuntu 16.04
// //
// See https://dbus.freedesktop.org/doc/dbus-launch.1.html // See https://dbus.freedesktop.org/doc/dbus-launch.1.html

View File

@ -11,6 +11,11 @@ type decoder struct {
order binary.ByteOrder order binary.ByteOrder
pos int pos int
fds []int fds []int
// The following fields are used to reduce memory allocs.
buf []byte
d float64
y [1]byte
} }
// newDecoder returns a new decoder that reads values from in. The input is // newDecoder returns a new decoder that reads values from in. The input is
@ -23,14 +28,19 @@ func newDecoder(in io.Reader, order binary.ByteOrder, fds []int) *decoder {
return dec return dec
} }
// Reset resets the decoder to be reading from in.
func (dec *decoder) Reset(in io.Reader, order binary.ByteOrder, fds []int) {
dec.in = in
dec.order = order
dec.pos = 0
dec.fds = fds
}
// align aligns the input to the given boundary and panics on error. // align aligns the input to the given boundary and panics on error.
func (dec *decoder) align(n int) { func (dec *decoder) align(n int) {
if dec.pos%n != 0 { if dec.pos%n != 0 {
newpos := (dec.pos + n - 1) & ^(n - 1) newpos := (dec.pos + n - 1) & ^(n - 1)
empty := make([]byte, newpos-dec.pos) dec.read2buf(newpos - dec.pos)
if _, err := io.ReadFull(dec.in, empty); err != nil {
panic(err)
}
dec.pos = newpos dec.pos = newpos
} }
} }
@ -66,79 +76,89 @@ func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
return vs, nil return vs, nil
} }
// read2buf reads exactly n bytes from the reader dec.in into the buffer dec.buf
// to reduce memory allocs.
// The buffer grows automatically.
func (dec *decoder) read2buf(n int) {
if cap(dec.buf) < n {
dec.buf = make([]byte, n)
} else {
dec.buf = dec.buf[:n]
}
if _, err := io.ReadFull(dec.in, dec.buf); err != nil {
panic(err)
}
}
// decodeU decodes uint32 obtained from the reader dec.in.
// The goal is to reduce memory allocs.
func (dec *decoder) decodeU() uint32 {
dec.align(4)
dec.read2buf(4)
dec.pos += 4
return dec.order.Uint32(dec.buf)
}
func (dec *decoder) decode(s string, depth int) interface{} { func (dec *decoder) decode(s string, depth int) interface{} {
dec.align(alignment(typeFor(s))) dec.align(alignment(typeFor(s)))
switch s[0] { switch s[0] {
case 'y': case 'y':
var b [1]byte if _, err := dec.in.Read(dec.y[:]); err != nil {
if _, err := dec.in.Read(b[:]); err != nil {
panic(err) panic(err)
} }
dec.pos++ dec.pos++
return b[0] return dec.y[0]
case 'b': case 'b':
i := dec.decode("u", depth).(uint32) switch dec.decodeU() {
switch { case 0:
case i == 0:
return false return false
case i == 1: case 1:
return true return true
default: default:
panic(FormatError("invalid value for boolean")) panic(FormatError("invalid value for boolean"))
} }
case 'n': case 'n':
var i int16 dec.read2buf(2)
dec.binread(&i)
dec.pos += 2 dec.pos += 2
return i return int16(dec.order.Uint16(dec.buf))
case 'i': case 'i':
var i int32 dec.read2buf(4)
dec.binread(&i)
dec.pos += 4 dec.pos += 4
return i return int32(dec.order.Uint32(dec.buf))
case 'x': case 'x':
var i int64 dec.read2buf(8)
dec.binread(&i)
dec.pos += 8 dec.pos += 8
return i return int64(dec.order.Uint64(dec.buf))
case 'q': case 'q':
var i uint16 dec.read2buf(2)
dec.binread(&i)
dec.pos += 2 dec.pos += 2
return i return dec.order.Uint16(dec.buf)
case 'u': case 'u':
var i uint32 return dec.decodeU()
dec.binread(&i)
dec.pos += 4
return i
case 't': case 't':
var i uint64 dec.read2buf(8)
dec.binread(&i)
dec.pos += 8 dec.pos += 8
return i return dec.order.Uint64(dec.buf)
case 'd': case 'd':
var f float64 dec.binread(&dec.d)
dec.binread(&f)
dec.pos += 8 dec.pos += 8
return f return dec.d
case 's': case 's':
length := dec.decode("u", depth).(uint32) length := dec.decodeU()
b := make([]byte, int(length)+1) p := int(length) + 1
if _, err := io.ReadFull(dec.in, b); err != nil { dec.read2buf(p)
panic(err) dec.pos += p
} return string(dec.buf[:len(dec.buf)-1])
dec.pos += int(length) + 1
return string(b[:len(b)-1])
case 'o': case 'o':
return ObjectPath(dec.decode("s", depth).(string)) return ObjectPath(dec.decode("s", depth).(string))
case 'g': case 'g':
length := dec.decode("y", depth).(byte) length := dec.decode("y", depth).(byte)
b := make([]byte, int(length)+1) p := int(length) + 1
if _, err := io.ReadFull(dec.in, b); err != nil { dec.read2buf(p)
panic(err) dec.pos += p
} sig, err := ParseSignature(
dec.pos += int(length) + 1 string(dec.buf[:len(dec.buf)-1]),
sig, err := ParseSignature(string(b[:len(b)-1])) )
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -163,7 +183,7 @@ func (dec *decoder) decode(s string, depth int) interface{} {
variant.value = dec.decode(sig.str, depth+1) variant.value = dec.decode(sig.str, depth+1)
return variant return variant
case 'h': case 'h':
idx := dec.decode("u", depth).(uint32) idx := dec.decodeU()
if int(idx) < len(dec.fds) { if int(idx) < len(dec.fds) {
return UnixFD(dec.fds[idx]) return UnixFD(dec.fds[idx])
} }
@ -176,7 +196,7 @@ func (dec *decoder) decode(s string, depth int) interface{} {
if depth >= 63 { if depth >= 63 {
panic(FormatError("input exceeds container depth limit")) panic(FormatError("input exceeds container depth limit"))
} }
length := dec.decode("u", depth).(uint32) length := dec.decodeU()
// Even for empty maps, the correct padding must be included // Even for empty maps, the correct padding must be included
dec.align(8) dec.align(8)
spos := dec.pos spos := dec.pos
@ -195,7 +215,7 @@ func (dec *decoder) decode(s string, depth int) interface{} {
panic(FormatError("input exceeds container depth limit")) panic(FormatError("input exceeds container depth limit"))
} }
sig := s[1:] sig := s[1:]
length := dec.decode("u", depth).(uint32) length := dec.decodeU()
// capacity can be determined only for fixed-size element types // capacity can be determined only for fixed-size element types
var capacity int var capacity int
if s := sigByteSize(sig); s != 0 { if s := sigByteSize(sig); s != 0 {

View File

@ -18,9 +18,9 @@ func newIntrospectIntf(h *defaultHandler) *exportedIntf {
return newExportedIntf(methods, true) return newExportedIntf(methods, true)
} }
//NewDefaultHandler returns an instance of the default // NewDefaultHandler returns an instance of the default
//call handler. This is useful if you want to implement only // call handler. This is useful if you want to implement only
//one of the two handlers but not both. // one of the two handlers but not both.
// //
// Deprecated: this is the default value, don't use it, it will be unexported. // Deprecated: this is the default value, don't use it, it will be unexported.
func NewDefaultHandler() *defaultHandler { func NewDefaultHandler() *defaultHandler {
@ -238,9 +238,9 @@ func (obj *exportedIntf) isFallbackInterface() bool {
return obj.includeSubtree return obj.includeSubtree
} }
//NewDefaultSignalHandler returns an instance of the default // NewDefaultSignalHandler returns an instance of the default
//signal handler. This is useful if you want to implement only // signal handler. This is useful if you want to implement only
//one of the two handlers but not both. // one of the two handlers but not both.
// //
// Deprecated: this is the default value, don't use it, it will be unexported. // Deprecated: this is the default value, don't use it, it will be unexported.
func NewDefaultSignalHandler() *defaultSignalHandler { func NewDefaultSignalHandler() *defaultSignalHandler {

View File

@ -7,7 +7,7 @@ on remote objects and emit or receive signals. Using the Export method, you can
arrange D-Bus methods calls to be directly translated to method calls on a Go arrange D-Bus methods calls to be directly translated to method calls on a Go
value. value.
Conversion Rules # Conversion Rules
For outgoing messages, Go types are automatically converted to the For outgoing messages, Go types are automatically converted to the
corresponding D-Bus types. See the official specification at corresponding D-Bus types. See the official specification at
@ -57,7 +57,7 @@ of STRUCTs. Incoming STRUCTS are represented as a slice of empty interfaces
containing the struct fields in the correct order. The Store function can be containing the struct fields in the correct order. The Store function can be
used to convert such values to Go structs. used to convert such values to Go structs.
Unix FD passing # Unix FD passing
Handling Unix file descriptors deserves special mention. To use them, you should Handling Unix file descriptors deserves special mention. To use them, you should
first check that they are supported on a connection by calling SupportsUnixFDs. first check that they are supported on a connection by calling SupportsUnixFDs.
@ -66,6 +66,5 @@ UnixFD's to messages that are accompanied by the given file descriptors with the
UnixFD values being substituted by the correct indices. Similarly, the indices UnixFD values being substituted by the correct indices. Similarly, the indices
of incoming messages are automatically resolved. It shouldn't be necessary to use of incoming messages are automatically resolved. It shouldn't be necessary to use
UnixFDIndex. UnixFDIndex.
*/ */
package dbus package dbus

View File

@ -208,10 +208,10 @@ func (conn *Conn) handleCall(msg *Message) {
copy(reply.Body, ret) copy(reply.Body, ret)
reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...)) reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...))
if err := reply.IsValid(); err != nil { if err := conn.sendMessageAndIfClosed(reply, nil); err != nil {
fmt.Fprintf(os.Stderr, "dbus: dropping invalid reply to %s.%s on obj %s: %s\n", ifaceName, name, path, err) if _, ok := err.(FormatError); ok {
} else { fmt.Fprintf(os.Stderr, "dbus: replacing invalid reply to %s.%s on obj %s: %s\n", ifaceName, name, path, err)
conn.sendMessageAndIfClosed(reply, nil) }
} }
} }
} }
@ -235,18 +235,15 @@ func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) erro
if len(values) > 0 { if len(values) > 0 {
msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...)) msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
} }
if err := msg.IsValid(); err != nil {
return err
}
var closed bool var closed bool
conn.sendMessageAndIfClosed(msg, func() { err := conn.sendMessageAndIfClosed(msg, func() {
closed = true closed = true
}) })
if closed { if closed {
return ErrClosed return ErrClosed
} }
return nil return err
} }
// Export registers the given value to be exported as an object on the // Export registers the given value to be exported as an object on the

View File

@ -188,7 +188,7 @@ func DecodeMessageWithFDs(rd io.Reader, fds []int) (msg *Message, err error) {
} }
} }
if err = msg.IsValid(); err != nil { if err = msg.validateHeader(); err != nil {
return nil, err return nil, err
} }
sig, _ := msg.Headers[FieldSignature].value.(Signature) sig, _ := msg.Headers[FieldSignature].value.(Signature)
@ -290,8 +290,7 @@ func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) (err error)
// IsValid checks whether msg is a valid message and returns an // IsValid checks whether msg is a valid message and returns an
// InvalidMessageError or FormatError if it is not. // InvalidMessageError or FormatError if it is not.
func (msg *Message) IsValid() error { func (msg *Message) IsValid() error {
var b bytes.Buffer return msg.EncodeTo(io.Discard, nativeEndian)
return msg.EncodeTo(&b, nativeEndian)
} }
func (msg *Message) validateHeader() error { func (msg *Message) validateHeader() error {

View File

@ -151,7 +151,14 @@ func (o *Object) StoreProperty(p string, value interface{}) error {
// SetProperty calls org.freedesktop.DBus.Properties.Set on the given // SetProperty calls org.freedesktop.DBus.Properties.Set on the given
// object. The property name must be given in interface.member notation. // object. The property name must be given in interface.member notation.
// Panics if v is not a valid Variant type.
func (o *Object) SetProperty(p string, v interface{}) error { func (o *Object) SetProperty(p string, v interface{}) error {
// v might already be a variant...
variant, ok := v.(Variant)
if !ok {
// Otherwise, make it into one.
variant = MakeVariant(v)
}
idx := strings.LastIndex(p, ".") idx := strings.LastIndex(p, ".")
if idx == -1 || idx+1 == len(p) { if idx == -1 || idx+1 == len(p) {
return errors.New("dbus: invalid property " + p) return errors.New("dbus: invalid property " + p)
@ -160,7 +167,7 @@ func (o *Object) SetProperty(p string, v interface{}) error {
iface := p[:idx] iface := p[:idx]
prop := p[idx+1:] prop := p[idx+1:]
return o.Call("org.freedesktop.DBus.Properties.Set", 0, iface, prop, v).Err return o.Call("org.freedesktop.DBus.Properties.Set", 0, iface, prop, variant).Err
} }
// Destination returns the destination that calls on (o *Object) are sent to. // Destination returns the destination that calls on (o *Object) are sent to.

View File

@ -183,19 +183,19 @@ func (cnt *depthCounter) Valid() bool {
return cnt.arrayDepth <= 32 && cnt.structDepth <= 32 && cnt.dictEntryDepth <= 32 return cnt.arrayDepth <= 32 && cnt.structDepth <= 32 && cnt.dictEntryDepth <= 32
} }
func (cnt depthCounter) EnterArray() *depthCounter { func (cnt *depthCounter) EnterArray() *depthCounter {
cnt.arrayDepth++ cnt.arrayDepth++
return &cnt return cnt
} }
func (cnt depthCounter) EnterStruct() *depthCounter { func (cnt *depthCounter) EnterStruct() *depthCounter {
cnt.structDepth++ cnt.structDepth++
return &cnt return cnt
} }
func (cnt depthCounter) EnterDictEntry() *depthCounter { func (cnt *depthCounter) EnterDictEntry() *depthCounter {
cnt.dictEntryDepth++ cnt.dictEntryDepth++
return &cnt return cnt
} }
// Try to read a single type from this string. If it was successful, err is nil // Try to read a single type from this string. If it was successful, err is nil

View File

@ -12,10 +12,29 @@ import (
"syscall" "syscall"
) )
// msghead represents the part of the message header
// that has a constant size (byte order + 15 bytes).
type msghead struct {
Type Type
Flags Flags
Proto byte
BodyLen uint32
Serial uint32
HeaderLen uint32
}
type oobReader struct { type oobReader struct {
conn *net.UnixConn conn *net.UnixConn
oob []byte oob []byte
buf [4096]byte buf [4096]byte
// The following fields are used to reduce memory allocs.
headers []header
csheader []byte
b *bytes.Buffer
r *bytes.Reader
dec *decoder
msghead
} }
func (o *oobReader) Read(b []byte) (n int, err error) { func (o *oobReader) Read(b []byte) (n int, err error) {
@ -71,28 +90,36 @@ func (t *unixTransport) EnableUnixFDs() {
} }
func (t *unixTransport) ReadMessage() (*Message, error) { func (t *unixTransport) ReadMessage() (*Message, error) {
var (
blen, hlen uint32
csheader [16]byte
headers []header
order binary.ByteOrder
unixfds uint32
)
// To be sure that all bytes of out-of-band data are read, we use a special // To be sure that all bytes of out-of-band data are read, we use a special
// reader that uses ReadUnix on the underlying connection instead of Read // reader that uses ReadUnix on the underlying connection instead of Read
// and gathers the out-of-band data in a buffer. // and gathers the out-of-band data in a buffer.
if t.rdr == nil { if t.rdr == nil {
t.rdr = &oobReader{conn: t.UnixConn} t.rdr = &oobReader{
} else { conn: t.UnixConn,
t.rdr.oob = nil // This buffer is used to decode the part of the header that has a constant size.
csheader: make([]byte, 16),
b: &bytes.Buffer{},
// The reader helps to read from the buffer several times.
r: &bytes.Reader{},
dec: &decoder{},
} }
} else {
t.rdr.oob = t.rdr.oob[:0]
t.rdr.headers = t.rdr.headers[:0]
}
var (
r = t.rdr.r
b = t.rdr.b
dec = t.rdr.dec
)
// read the first 16 bytes (the part of the header that has a constant size), _, err := io.ReadFull(t.rdr, t.rdr.csheader)
// from which we can figure out the length of the rest of the message if err != nil {
if _, err := io.ReadFull(t.rdr, csheader[:]); err != nil {
return nil, err return nil, err
} }
switch csheader[0] {
var order binary.ByteOrder
switch t.rdr.csheader[0] {
case 'l': case 'l':
order = binary.LittleEndian order = binary.LittleEndian
case 'B': case 'B':
@ -100,45 +127,62 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
default: default:
return nil, InvalidMessageError("invalid byte order") return nil, InvalidMessageError("invalid byte order")
} }
// csheader[4:8] -> length of message body, csheader[12:16] -> length of
// header fields (without alignment) r.Reset(t.rdr.csheader[1:])
if err := binary.Read(bytes.NewBuffer(csheader[4:8]), order, &blen); err != nil { if err := binary.Read(r, order, &t.rdr.msghead); err != nil {
return nil, err return nil, err
} }
if err := binary.Read(bytes.NewBuffer(csheader[12:]), order, &hlen); err != nil {
return nil, err msg := &Message{
Type: t.rdr.msghead.Type,
Flags: t.rdr.msghead.Flags,
serial: t.rdr.msghead.Serial,
} }
// Length of header fields (without alignment).
hlen := t.rdr.msghead.HeaderLen
if hlen%8 != 0 { if hlen%8 != 0 {
hlen += 8 - (hlen % 8) hlen += 8 - (hlen % 8)
} }
if hlen+t.rdr.msghead.BodyLen+16 > 1<<27 {
return nil, InvalidMessageError("message is too long")
}
// decode headers and look for unix fds // Decode headers and look for unix fds.
headerdata := make([]byte, hlen+4) b.Reset()
copy(headerdata, csheader[12:]) if _, err = b.Write(t.rdr.csheader[12:]); err != nil {
if _, err := io.ReadFull(t.rdr, headerdata[4:]); err != nil {
return nil, err return nil, err
} }
dec := newDecoder(bytes.NewBuffer(headerdata), order, make([]int, 0)) if _, err = io.CopyN(b, t.rdr, int64(hlen)); err != nil {
return nil, err
}
dec.Reset(b, order, nil)
dec.pos = 12 dec.pos = 12
vs, err := dec.Decode(Signature{"a(yv)"}) vs, err := dec.Decode(Signature{"a(yv)"})
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = Store(vs, &headers) if err = Store(vs, &t.rdr.headers); err != nil {
if err != nil {
return nil, err return nil, err
} }
for _, v := range headers { var unixfds uint32
for _, v := range t.rdr.headers {
if v.Field == byte(FieldUnixFDs) { if v.Field == byte(FieldUnixFDs) {
unixfds, _ = v.Variant.value.(uint32) unixfds, _ = v.Variant.value.(uint32)
} }
} }
all := make([]byte, 16+hlen+blen)
copy(all, csheader[:]) msg.Headers = make(map[HeaderField]Variant)
copy(all[16:], headerdata[4:]) for _, v := range t.rdr.headers {
if _, err := io.ReadFull(t.rdr, all[16+hlen:]); err != nil { msg.Headers[HeaderField(v.Field)] = v.Variant
}
dec.align(8)
body := make([]byte, t.rdr.BodyLen)
if _, err = io.ReadFull(t.rdr, body); err != nil {
return nil, err return nil, err
} }
r.Reset(body)
if unixfds != 0 { if unixfds != 0 {
if !t.hasUnixFDs { if !t.hasUnixFDs {
return nil, errors.New("dbus: got unix fds on unsupported transport") return nil, errors.New("dbus: got unix fds on unsupported transport")
@ -155,8 +199,8 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
msg, err := DecodeMessageWithFDs(bytes.NewBuffer(all), fds) dec.Reset(r, order, fds)
if err != nil { if err = decodeMessageBody(msg, dec); err != nil {
return nil, err return nil, err
} }
// substitute the values in the message body (which are indices for the // substitute the values in the message body (which are indices for the
@ -181,7 +225,27 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
} }
return msg, nil return msg, nil
} }
return DecodeMessage(bytes.NewBuffer(all))
dec.Reset(r, order, nil)
if err = decodeMessageBody(msg, dec); err != nil {
return nil, err
}
return msg, nil
}
func decodeMessageBody(msg *Message, dec *decoder) error {
if err := msg.validateHeader(); err != nil {
return err
}
sig, _ := msg.Headers[FieldSignature].value.(Signature)
if sig.str == "" {
return nil
}
var err error
msg.Body, err = dec.Decode(sig)
return err
} }
func (t *unixTransport) SendMessage(msg *Message) error { func (t *unixTransport) SendMessage(msg *Message) error {

2
vendor/modules.txt vendored
View File

@ -513,7 +513,7 @@ github.com/go-playground/validator/v10
# github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 # github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572
## explicit; go 1.13 ## explicit; go 1.13
github.com/go-task/slim-sprig github.com/go-task/slim-sprig
# github.com/godbus/dbus/v5 v5.1.1-0.20221029134443-4b691ce883d5 # github.com/godbus/dbus/v5 v5.1.1-0.20230502183206-6cc540df4ec5
## explicit; go 1.12 ## explicit; go 1.12
github.com/godbus/dbus/v5 github.com/godbus/dbus/v5
# github.com/gogo/protobuf v1.3.2 # github.com/gogo/protobuf v1.3.2