Skip to content

Commit 59fd8e5

Browse files
committed
BUG/MEDIUM: avoid double quotes
in rules generated from annotations
1 parent 4e3595f commit 59fd8e5

File tree

5 files changed

+92
-4
lines changed

5 files changed

+92
-4
lines changed

deploy/tests/e2e/cors/cors_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"net/http"
2121

2222
"github.com/haproxytech/kubernetes-ingress/deploy/tests/e2e"
23+
"github.com/haproxytech/kubernetes-ingress/pkg/annotations/common"
2324
)
2425

2526
const (
@@ -105,7 +106,7 @@ func (suite *CorsSuite) eventuallyReturnsWithNoContentOption(expectedHeaders, un
105106
}
106107

107108
func q(value string) string {
108-
return "\"" + value + "\""
109+
return common.EnsureQuoted(value)
109110
}
110111

111112
func (suite *CorsSuite) Default(ingressCors bool) func() {

pkg/annotations/common/main.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,21 @@ func GetValuesAndIndices(annotationName string, annotations ...map[string]string
7575
}
7676
return result
7777
}
78+
79+
// EnsureQuoted ensures that a string starts and ends with a double quote.
80+
// It adds a quote to the beginning if one is not already present,
81+
// and adds a quote to the end if one is not already present.
82+
func EnsureQuoted(s string) string {
83+
newS := s
84+
if s == "\"" || s == "" {
85+
newS = "\"\""
86+
return newS
87+
}
88+
if !strings.HasPrefix(newS, "\"") {
89+
newS = "\"" + newS
90+
}
91+
if !strings.HasSuffix(newS, "\"") {
92+
newS += "\""
93+
}
94+
return newS
95+
}

pkg/annotations/ingress/reqSetHdr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func (a *SetHdr) Process(k store.K8s, annotations ...map[string]string) (err err
4242
}
4343
a.rules.Add(&rules.SetHdr{
4444
HdrName: param[:indexSpace],
45-
HdrFormat: "\"" + param[indexSpace+1:] + "\"",
45+
HdrFormat: common.EnsureQuoted(param[indexSpace+1:]),
4646
Response: a.response,
4747
})
4848
}

pkg/annotations/ingress/resSetCORS.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (a ResSetCORSAnn) Process(k store.K8s, annotations ...map[string]string) (e
9393
return fmt.Errorf("unsupported HTTP method '%s' in cors-allow-methods configuration", methods[i])
9494
}
9595
}
96-
input = "\"" + strings.Join(methods, ", ") + "\""
96+
input = common.EnsureQuoted(strings.Join(methods, ", "))
9797
}
9898
a.parent.rules.Add(&rules.SetHdr{
9999
HdrName: "Access-Control-Allow-Methods",
@@ -109,7 +109,7 @@ func (a ResSetCORSAnn) Process(k store.K8s, annotations ...map[string]string) (e
109109
input = strings.Join(strings.Fields(input), "") // strip spaces
110110
a.parent.rules.Add(rules.SetHdr{
111111
HdrName: "Access-Control-Allow-Headers",
112-
HdrFormat: "\"" + input + "\"",
112+
HdrFormat: common.EnsureQuoted(input),
113113
AfterResponse: true,
114114
CondTest: a.parent.acl,
115115
Cond: "if",

test/annotations/common_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package annotations_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/haproxytech/kubernetes-ingress/pkg/annotations/common"
7+
)
8+
9+
func TestEnsureQuoted(t *testing.T) {
10+
tests := []struct {
11+
name string
12+
input string
13+
want string
14+
}{
15+
{
16+
name: "simple string",
17+
input: "test",
18+
want: "\"test\"",
19+
},
20+
{
21+
name: "already quoted",
22+
input: "\"test\"",
23+
want: "\"test\"",
24+
},
25+
{
26+
name: "empty string",
27+
input: "",
28+
want: "\"\"",
29+
},
30+
{
31+
name: "starts with quote",
32+
input: "\"test",
33+
want: "\"test\"",
34+
},
35+
{
36+
name: "ends with quote",
37+
input: "test\"",
38+
want: "\"test\"",
39+
},
40+
{
41+
name: "single quote",
42+
input: "\"",
43+
want: "\"\"",
44+
},
45+
{
46+
name: "empty quoted string",
47+
input: "\"\"",
48+
want: "\"\"",
49+
},
50+
{
51+
name: "string with internal quotes",
52+
input: "te\"st",
53+
want: "\"te\"st\"",
54+
},
55+
{
56+
name: "string with leading/trailing spaces",
57+
input: " test ",
58+
want: "\" test \"",
59+
},
60+
}
61+
62+
for _, tt := range tests {
63+
t.Run(tt.name, func(t *testing.T) {
64+
if got := common.EnsureQuoted(tt.input); got != tt.want {
65+
t.Errorf("EnsureQuoted() = %v, want %v", got, tt.want)
66+
}
67+
})
68+
}
69+
}

0 commit comments

Comments
 (0)