Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: URI path element replace issue due to elements name overlap #553

Merged
merged 4 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions encoding/httpbinding/path_replace.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,33 @@ func bufCap(b []byte, n int) []byte {
// replacePathElement replaces a single element in the path []byte.
// Escape is used to control whether the value will be escaped using Amazon path escape style.
func replacePathElement(path, fieldBuf []byte, key, val string, escape bool) ([]byte, []byte, error) {
fieldBuf = bufCap(fieldBuf, len(key)+3) // { <key> [+] }
wty-Bryant marked this conversation as resolved.
Show resolved Hide resolved
// search for "{<key>}". If not found, search for the greedy version "{<key>+}". If none are found, return error
fieldBuf = bufCap(fieldBuf, len(key)+2) // { <key> }
fieldBuf = append(fieldBuf, uriTokenStart)
fieldBuf = append(fieldBuf, key...)
fieldBuf = append(fieldBuf, uriTokenStop)

start := bytes.Index(path, fieldBuf)
end := start + len(fieldBuf)
if start < 0 || len(path[end:]) == 0 {
// TODO what to do about error?
return path, fieldBuf, fmt.Errorf("invalid path index, start=%d,end=%d. %s", start, end, path)
}

encodeSep := true
if path[end] == uriTokenSkip {
// '+' token means do not escape slashes
if start < 0 {
fieldBuf = bufCap(fieldBuf, len(key)+3) // { <key> [+] }
fieldBuf = append(fieldBuf, uriTokenStart)
fieldBuf = append(fieldBuf, key...)
fieldBuf = append(fieldBuf, uriTokenSkip)
fieldBuf = append(fieldBuf, uriTokenStop)

start = bytes.Index(path, fieldBuf)
if start < 0 {
return path, fieldBuf, fmt.Errorf("invalid path index, start=%d. %s", start, path)
}
encodeSep = false
end++
}
end := start + len(fieldBuf)

if escape {
val = EscapePath(val, encodeSep)
}

if path[end] != uriTokenStop {
return path, fieldBuf, fmt.Errorf("invalid path element, does not contain token stop, %s", path)
}
end++

fieldBuf = bufCap(fieldBuf, len(val))
fieldBuf = append(fieldBuf, val...)

Expand Down
29 changes: 28 additions & 1 deletion encoding/httpbinding/path_replace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ func TestPathReplace(t *testing.T) {
cases := []struct {
Orig, ExpPath, ExpRawPath []byte
Key, Val string
ExpectErr bool
}{
{
Orig: []byte("/{bucket}/{key+}"),
Expand Down Expand Up @@ -40,6 +41,23 @@ func TestPathReplace(t *testing.T) {
ExpRawPath: []byte("/reallylongvaluegoesheregrowingarray/{key+}"),
Key: "bucket", Val: "reallylongvaluegoesheregrowingarray",
},
{
Orig: []byte("/{namespace}/{name}"),
ExpPath: []byte("/{namespace}/value"),
ExpRawPath: []byte("/{namespace}/value"),
Key: "name", Val: "value",
},
{
Orig: []byte("/{name}/{namespace}"),
ExpPath: []byte("/value/{namespace}"),
ExpRawPath: []byte("/value/{namespace}"),
Key: "name", Val: "value",
},
{
Orig: []byte("/{namespace}/{name+}"),
Key: "nam", Val: "value",
ExpectErr: true,
},
}

var buffer [64]byte
Expand All @@ -50,8 +68,17 @@ func TestPathReplace(t *testing.T) {

path, _, err := replacePathElement(c.Orig, buffer[:0], c.Key, c.Val, false)
if err != nil {
t.Fatalf("expected no error, got %v", err)
if !c.ExpectErr {
t.Fatalf("expected no error, got %v", err)
}
} else if c.ExpectErr {
t.Fatalf("expect error, got none")
}

if c.ExpectErr {
return
}

rawPath, _, err := replacePathElement(origRaw, buffer[:0], c.Key, c.Val, true)
if err != nil {
t.Fatalf("expected no error, got %v", err)
Expand Down
Loading