...

Source file src/github.com/godbus/dbus/v5/escape.go

Documentation: github.com/godbus/dbus/v5

     1  package dbus
     2  
     3  import "net/url"
     4  
     5  // EscapeBusAddressValue implements a requirement to escape the values
     6  // in D-Bus server addresses, as defined by the D-Bus specification at
     7  // https://dbus.freedesktop.org/doc/dbus-specification.html#addresses.
     8  func EscapeBusAddressValue(val string) string {
     9  	toEsc := strNeedsEscape(val)
    10  	if toEsc == 0 {
    11  		// Avoid unneeded allocation/copying.
    12  		return val
    13  	}
    14  
    15  	// Avoid allocation for short paths.
    16  	var buf [64]byte
    17  	var out []byte
    18  	// Every to-be-escaped byte needs 2 extra bytes.
    19  	required := len(val) + 2*toEsc
    20  	if required <= len(buf) {
    21  		out = buf[:required]
    22  	} else {
    23  		out = make([]byte, required)
    24  	}
    25  
    26  	j := 0
    27  	for i := 0; i < len(val); i++ {
    28  		if ch := val[i]; needsEscape(ch) {
    29  			// Convert ch to %xx, where xx is hex value.
    30  			out[j] = '%'
    31  			out[j+1] = hexchar(ch >> 4)
    32  			out[j+2] = hexchar(ch & 0x0F)
    33  			j += 3
    34  		} else {
    35  			out[j] = ch
    36  			j++
    37  		}
    38  	}
    39  
    40  	return string(out)
    41  }
    42  
    43  // UnescapeBusAddressValue unescapes values in D-Bus server addresses,
    44  // as defined by the D-Bus specification at
    45  // https://dbus.freedesktop.org/doc/dbus-specification.html#addresses.
    46  func UnescapeBusAddressValue(val string) (string, error) {
    47  	// Looks like url.PathUnescape does exactly what is required.
    48  	return url.PathUnescape(val)
    49  }
    50  
    51  // hexchar returns an octal representation of a n, where n < 16.
    52  // For invalid values of n, the function panics.
    53  func hexchar(n byte) byte {
    54  	const hex = "0123456789abcdef"
    55  
    56  	// For n >= len(hex), runtime will panic.
    57  	return hex[n]
    58  }
    59  
    60  // needsEscape tells if a byte is NOT one of optionally-escaped bytes.
    61  func needsEscape(c byte) bool {
    62  	if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
    63  		return false
    64  	}
    65  	switch c {
    66  	case '-', '_', '/', '\\', '.', '*':
    67  		return false
    68  	}
    69  
    70  	return true
    71  }
    72  
    73  // strNeedsEscape tells how many bytes in the string need escaping.
    74  func strNeedsEscape(val string) int {
    75  	count := 0
    76  
    77  	for i := 0; i < len(val); i++ {
    78  		if needsEscape(val[i]) {
    79  			count++
    80  		}
    81  	}
    82  
    83  	return count
    84  }
    85  

View as plain text