Skip to content

Commit

Permalink
cmd/internal/objabi: add inverse of PathToPrefix
Browse files Browse the repository at this point in the history
Add PrefixToPath, which can be used to convert a package path in a
symbol name back to the original package path.

For golang#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>
  • Loading branch information
prattmic authored and yunginnanet committed Oct 20, 2023
1 parent c905708 commit 41871c1
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 8 deletions.
39 changes: 38 additions & 1 deletion src/cmd/internal/objabi/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

package objabi

import "strings"
import (
"fmt"
"strconv"
"strings"
)

// PathToPrefix converts raw string to the prefix that will be used in the
// symbol table. All control characters, space, '%' and '"', as well as
Expand Down Expand Up @@ -39,3 +43,36 @@ func PathToPrefix(s string) string {

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
}
43 changes: 36 additions & 7 deletions src/cmd/internal/objabi/path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import (
"testing"
)

func TestPathToPrefix(t *testing.T) {
tests := []struct {
Path string
Expected string
}{{"foo/bar/v1", "foo/bar/v1"},
var escapeTests = []struct {
Path string
Escaped string
}{
{"foo/bar/v1", "foo/bar/v1"},
{"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/v.1", "f.o.o/b.a.r/v%2e1"},
Expand All @@ -30,9 +30,38 @@ func TestPathToPrefix(t *testing.T) {
{"%foo%bar", "%25foo%25bar"},
{"\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 {
if got := PathToPrefix(tc.Path); got != tc.Expected {
t.Errorf("expected PathToPrefix(%s) = %s, got %s", tc.Path, tc.Expected, got)
_, err := PrefixToPath(tc)
if err == nil {
t.Errorf("expected PrefixToPath(%s) err != nil, got nil", tc)
}
}
}
Expand Down

0 comments on commit 41871c1

Please sign in to comment.