mirror of
https://github.com/golang/go
synced 2024-11-16 21:04:45 -07:00
cmd/internal/objabi: add inverse of PathToPrefix
Add PrefixToPath, which can be used to convert a package path in a symbol name back to the original package path. For #61577. Change-Id: Ifbe8c852a7f41ff9b81ad48b92a26a0e1b046777 Reviewed-on: https://go-review.googlesource.com/c/go/+/529557 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
d1ef967306
commit
696fb5ead0
@ -4,7 +4,11 @@
|
|||||||
|
|
||||||
package objabi
|
package objabi
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// PathToPrefix converts raw string to the prefix that will be used in the
|
// PathToPrefix converts raw string to the prefix that will be used in the
|
||||||
// symbol table. All control characters, space, '%' and '"', as well as
|
// symbol table. All control characters, space, '%' and '"', as well as
|
||||||
@ -39,3 +43,36 @@ func PathToPrefix(s string) string {
|
|||||||
|
|
||||||
return string(p)
|
return string(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrefixToPath is the inverse of PathToPrefix, replacing escape sequences with
|
||||||
|
// the original character.
|
||||||
|
func PrefixToPath(s string) (string, error) {
|
||||||
|
percent := strings.IndexByte(s, '%')
|
||||||
|
if percent == -1 {
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
p := make([]byte, 0, len(s))
|
||||||
|
for i := 0; i < len(s); {
|
||||||
|
if s[i] != '%' {
|
||||||
|
p = append(p, s[i])
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i+2 >= len(s) {
|
||||||
|
// Not enough characters remaining to be a valid escape
|
||||||
|
// sequence.
|
||||||
|
return "", fmt.Errorf("malformed prefix %q: escape sequence must contain two hex digits", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := strconv.ParseUint(s[i+1:i+3], 16, 8)
|
||||||
|
if err != nil {
|
||||||
|
// Not a valid escape sequence.
|
||||||
|
return "", fmt.Errorf("malformed prefix %q: escape sequence %q must contain two hex digits", s, s[i:i+3])
|
||||||
|
}
|
||||||
|
|
||||||
|
p = append(p, byte(b))
|
||||||
|
i += 3
|
||||||
|
}
|
||||||
|
return string(p), nil
|
||||||
|
}
|
||||||
|
@ -11,11 +11,11 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPathToPrefix(t *testing.T) {
|
var escapeTests = []struct {
|
||||||
tests := []struct {
|
Path string
|
||||||
Path string
|
Escaped string
|
||||||
Expected string
|
}{
|
||||||
}{{"foo/bar/v1", "foo/bar/v1"},
|
{"foo/bar/v1", "foo/bar/v1"},
|
||||||
{"foo/bar/v.1", "foo/bar/v%2e1"},
|
{"foo/bar/v.1", "foo/bar/v%2e1"},
|
||||||
{"f.o.o/b.a.r/v1", "f.o.o/b.a.r/v1"},
|
{"f.o.o/b.a.r/v1", "f.o.o/b.a.r/v1"},
|
||||||
{"f.o.o/b.a.r/v.1", "f.o.o/b.a.r/v%2e1"},
|
{"f.o.o/b.a.r/v.1", "f.o.o/b.a.r/v%2e1"},
|
||||||
@ -30,9 +30,38 @@ func TestPathToPrefix(t *testing.T) {
|
|||||||
{"%foo%bar", "%25foo%25bar"},
|
{"%foo%bar", "%25foo%25bar"},
|
||||||
{"\x01\x00\x7F☺", "%01%00%7f%e2%98%ba"},
|
{"\x01\x00\x7F☺", "%01%00%7f%e2%98%ba"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPathToPrefix(t *testing.T) {
|
||||||
|
for _, tc := range escapeTests {
|
||||||
|
if got := PathToPrefix(tc.Path); got != tc.Escaped {
|
||||||
|
t.Errorf("expected PathToPrefix(%s) = %s, got %s", tc.Path, tc.Escaped, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefixToPath(t *testing.T) {
|
||||||
|
for _, tc := range escapeTests {
|
||||||
|
got, err := PrefixToPath(tc.Escaped)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected PrefixToPath(%s) err = nil, got %v", tc.Escaped, err)
|
||||||
|
}
|
||||||
|
if got != tc.Path {
|
||||||
|
t.Errorf("expected PrefixToPath(%s) = %s, got %s", tc.Escaped, tc.Path, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrefixToPathError(t *testing.T) {
|
||||||
|
tests := []string{
|
||||||
|
"foo%",
|
||||||
|
"foo%1",
|
||||||
|
"foo%%12",
|
||||||
|
"foo%1g",
|
||||||
|
}
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
if got := PathToPrefix(tc.Path); got != tc.Expected {
|
_, err := PrefixToPath(tc)
|
||||||
t.Errorf("expected PathToPrefix(%s) = %s, got %s", tc.Path, tc.Expected, got)
|
if err == nil {
|
||||||
|
t.Errorf("expected PrefixToPath(%s) err != nil, got nil", tc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user