Skip to content

Commit 84c6c7e

Browse files
wty-BryantTianyi Wang
and
Tianyi Wang
authored
Fix: URI path element replace issue due to elements name overlap (#553)
* fix path replace issue of duplicate key prefix * add more comment to clarify element indexing * remove extra changelog * add error test case --------- Co-authored-by: Tianyi Wang <[email protected]>
1 parent 253cd26 commit 84c6c7e

File tree

2 files changed

+43
-16
lines changed

2 files changed

+43
-16
lines changed

encoding/httpbinding/path_replace.go

+15-15
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,33 @@ func bufCap(b []byte, n int) []byte {
2222
// replacePathElement replaces a single element in the path []byte.
2323
// Escape is used to control whether the value will be escaped using Amazon path escape style.
2424
func replacePathElement(path, fieldBuf []byte, key, val string, escape bool) ([]byte, []byte, error) {
25-
fieldBuf = bufCap(fieldBuf, len(key)+3) // { <key> [+] }
25+
// search for "{<key>}". If not found, search for the greedy version "{<key>+}". If none are found, return error
26+
fieldBuf = bufCap(fieldBuf, len(key)+2) // { <key> }
2627
fieldBuf = append(fieldBuf, uriTokenStart)
2728
fieldBuf = append(fieldBuf, key...)
29+
fieldBuf = append(fieldBuf, uriTokenStop)
2830

2931
start := bytes.Index(path, fieldBuf)
30-
end := start + len(fieldBuf)
31-
if start < 0 || len(path[end:]) == 0 {
32-
// TODO what to do about error?
33-
return path, fieldBuf, fmt.Errorf("invalid path index, start=%d,end=%d. %s", start, end, path)
34-
}
35-
3632
encodeSep := true
37-
if path[end] == uriTokenSkip {
38-
// '+' token means do not escape slashes
33+
if start < 0 {
34+
fieldBuf = bufCap(fieldBuf, len(key)+3) // { <key> [+] }
35+
fieldBuf = append(fieldBuf, uriTokenStart)
36+
fieldBuf = append(fieldBuf, key...)
37+
fieldBuf = append(fieldBuf, uriTokenSkip)
38+
fieldBuf = append(fieldBuf, uriTokenStop)
39+
40+
start = bytes.Index(path, fieldBuf)
41+
if start < 0 {
42+
return path, fieldBuf, fmt.Errorf("invalid path index, start=%d. %s", start, path)
43+
}
3944
encodeSep = false
40-
end++
4145
}
46+
end := start + len(fieldBuf)
4247

4348
if escape {
4449
val = EscapePath(val, encodeSep)
4550
}
4651

47-
if path[end] != uriTokenStop {
48-
return path, fieldBuf, fmt.Errorf("invalid path element, does not contain token stop, %s", path)
49-
}
50-
end++
51-
5252
fieldBuf = bufCap(fieldBuf, len(val))
5353
fieldBuf = append(fieldBuf, val...)
5454

encoding/httpbinding/path_replace_test.go

+28-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ func TestPathReplace(t *testing.T) {
99
cases := []struct {
1010
Orig, ExpPath, ExpRawPath []byte
1111
Key, Val string
12+
ExpectErr bool
1213
}{
1314
{
1415
Orig: []byte("/{bucket}/{key+}"),
@@ -40,6 +41,23 @@ func TestPathReplace(t *testing.T) {
4041
ExpRawPath: []byte("/reallylongvaluegoesheregrowingarray/{key+}"),
4142
Key: "bucket", Val: "reallylongvaluegoesheregrowingarray",
4243
},
44+
{
45+
Orig: []byte("/{namespace}/{name}"),
46+
ExpPath: []byte("/{namespace}/value"),
47+
ExpRawPath: []byte("/{namespace}/value"),
48+
Key: "name", Val: "value",
49+
},
50+
{
51+
Orig: []byte("/{name}/{namespace}"),
52+
ExpPath: []byte("/value/{namespace}"),
53+
ExpRawPath: []byte("/value/{namespace}"),
54+
Key: "name", Val: "value",
55+
},
56+
{
57+
Orig: []byte("/{namespace}/{name+}"),
58+
Key: "nam", Val: "value",
59+
ExpectErr: true,
60+
},
4361
}
4462

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

5169
path, _, err := replacePathElement(c.Orig, buffer[:0], c.Key, c.Val, false)
5270
if err != nil {
53-
t.Fatalf("expected no error, got %v", err)
71+
if !c.ExpectErr {
72+
t.Fatalf("expected no error, got %v", err)
73+
}
74+
} else if c.ExpectErr {
75+
t.Fatalf("expect error, got none")
5476
}
77+
78+
if c.ExpectErr {
79+
return
80+
}
81+
5582
rawPath, _, err := replacePathElement(origRaw, buffer[:0], c.Key, c.Val, true)
5683
if err != nil {
5784
t.Fatalf("expected no error, got %v", err)

0 commit comments

Comments
 (0)