diff options
Diffstat (limited to 'vendor/github.com/godbus/dbus/v5/escape.go')
-rw-r--r-- | vendor/github.com/godbus/dbus/v5/escape.go | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/vendor/github.com/godbus/dbus/v5/escape.go b/vendor/github.com/godbus/dbus/v5/escape.go new file mode 100644 index 000000000..d1509d945 --- /dev/null +++ b/vendor/github.com/godbus/dbus/v5/escape.go @@ -0,0 +1,84 @@ +package dbus + +import "net/url" + +// EscapeBusAddressValue implements a requirement to escape the values +// in D-Bus server addresses, as defined by the D-Bus specification at +// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses. +func EscapeBusAddressValue(val string) string { + toEsc := strNeedsEscape(val) + if toEsc == 0 { + // Avoid unneeded allocation/copying. + return val + } + + // Avoid allocation for short paths. + var buf [64]byte + var out []byte + // Every to-be-escaped byte needs 2 extra bytes. + required := len(val) + 2*toEsc + if required <= len(buf) { + out = buf[:required] + } else { + out = make([]byte, required) + } + + j := 0 + for i := 0; i < len(val); i++ { + if ch := val[i]; needsEscape(ch) { + // Convert ch to %xx, where xx is hex value. + out[j] = '%' + out[j+1] = hexchar(ch >> 4) + out[j+2] = hexchar(ch & 0x0F) + j += 3 + } else { + out[j] = ch + j++ + } + } + + return string(out) +} + +// UnescapeBusAddressValue unescapes values in D-Bus server addresses, +// as defined by the D-Bus specification at +// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses. +func UnescapeBusAddressValue(val string) (string, error) { + // Looks like url.PathUnescape does exactly what is required. + return url.PathUnescape(val) +} + +// hexchar returns an octal representation of a n, where n < 16. +// For invalid values of n, the function panics. +func hexchar(n byte) byte { + const hex = "0123456789abcdef" + + // For n >= len(hex), runtime will panic. + return hex[n] +} + +// needsEscape tells if a byte is NOT one of optionally-escaped bytes. +func needsEscape(c byte) bool { + if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' { + return false + } + switch c { + case '-', '_', '/', '\\', '.', '*': + return false + } + + return true +} + +// strNeedsEscape tells how many bytes in the string need escaping. +func strNeedsEscape(val string) int { + count := 0 + + for i := 0; i < len(val); i++ { + if needsEscape(val[i]) { + count++ + } + } + + return count +} |