Skip to content

Commit 7c88976

Browse files
committed
fix: Handle special characters in feed name
1 parent e3530ef commit 7c88976

File tree

8 files changed

+43
-23
lines changed

8 files changed

+43
-23
lines changed

internal/feed/feed.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io"
66
"io/fs"
77
"net/http"
8+
"net/url"
89
"os"
910
"path"
1011
"path/filepath"
@@ -62,7 +63,7 @@ func NewFeed(basePath string, feedName string) (*Feed, error) {
6263
secret := uuid.NewString()
6364
err = os.WriteFile(path.Join(basePath, feedName, "secret"), []byte(secret), 0600)
6465
if err != nil {
65-
log.Errorf("Unable towrite file %s", err.Error())
66+
log.Errorf("Unable to write file %s", err.Error())
6667
return nil, err
6768
}
6869
return &Feed{
@@ -340,3 +341,15 @@ func (feed *Feed) SetPIN(pin string) error {
340341
}
341342
return nil
342343
}
344+
345+
func FeedNameFromPath(path string) (*string, error) {
346+
s := strings.Split(path, "/")
347+
if len(s) < 4 {
348+
return nil, fmt.Errorf("No feed in URL (not enough components)")
349+
}
350+
result, err := url.QueryUnescape(s[3])
351+
if err != nil {
352+
return nil, err
353+
}
354+
return &result, nil
355+
}

internal/handlers/handlers.go

+21-14
Original file line numberDiff line numberDiff line change
@@ -102,19 +102,26 @@ func (api *ApiHandler) feedHandlerFunc(w http.ResponseWriter, r *http.Request) {
102102

103103
secret, fromURL := utils.GetSecret(r)
104104

105-
feedName := strings.Split(r.URL.Path, "/")[3]
105+
feedName, err := feed.FeedNameFromPath(r.URL.Path)
106106

107-
f, err := feed.GetFeed(api.BasePath, feedName, secret)
107+
if err != nil {
108+
utils.CloseWithCodeAndMessage(w, 500, "Unable to unescape feed name")
109+
}
110+
111+
f, err := feed.GetFeed(api.BasePath, *feedName, secret)
108112

109113
if err != nil {
110114
yberr := err.(*feed.FeedError)
111115
if yberr.Code == 404 {
112-
f, err = feed.NewFeed(api.BasePath, feedName)
113-
116+
f, err = feed.NewFeed(api.BasePath, *feedName)
117+
if err != nil {
118+
yberr := err.(*feed.FeedError)
119+
utils.CloseWithCodeAndMessage(w, yberr.Code, yberr.Error())
120+
}
114121
http.SetCookie(w, &http.Cookie{
115122
Name: "Secret",
116123
Value: f.Secret,
117-
Path: fmt.Sprintf("/api/feed/%s", feedName),
124+
Path: fmt.Sprintf("/api/feed/%s", *feedName),
118125
Expires: time.Now().Add(time.Hour * 24 * 365 * 10),
119126
})
120127
} else {
@@ -127,7 +134,7 @@ func (api *ApiHandler) feedHandlerFunc(w http.ResponseWriter, r *http.Request) {
127134
http.SetCookie(w, &http.Cookie{
128135
Name: "Secret",
129136
Value: f.Secret,
130-
Path: fmt.Sprintf("/api/feed/%s", feedName),
137+
Path: fmt.Sprintf("/api/feed/%s", *feedName),
131138
Expires: time.Now().Add(time.Hour * 24 * 365 * 10),
132139
})
133140
}
@@ -144,9 +151,9 @@ func (api *ApiHandler) feedPatchHandlerFunc(w http.ResponseWriter, r *http.Reque
144151
slog.Default().WithGroup("http").Debug("Feed API Set PIN request", slog.Any("request", r))
145152
secret, _ := utils.GetSecret(r)
146153

147-
feedName := strings.Split(r.URL.Path, "/")[3]
154+
feedName, err := feed.FeedNameFromPath(r.URL.Path)
148155

149-
f, err := feed.GetFeed(api.BasePath, feedName, secret)
156+
f, err := feed.GetFeed(api.BasePath, *feedName, secret)
150157

151158
if err != nil {
152159
yberr := err.(*feed.FeedError)
@@ -172,9 +179,9 @@ func (api *ApiHandler) feedItemHandlerFunc(w http.ResponseWriter, r *http.Reques
172179

173180
secret, _ := utils.GetSecret(r)
174181

175-
feedName := strings.Split(r.URL.Path, "/")[3]
182+
feedName, err := feed.FeedNameFromPath(r.URL.Path)
176183

177-
f, err := feed.GetFeed(api.BasePath, feedName, secret)
184+
f, err := feed.GetFeed(api.BasePath, *feedName, secret)
178185

179186
if err != nil {
180187
yberr := err.(*feed.FeedError)
@@ -205,9 +212,9 @@ func (api *ApiHandler) feedPostHandlerFunc(w http.ResponseWriter, r *http.Reques
205212

206213
secret, _ := utils.GetSecret(r)
207214

208-
feedName := strings.Split(r.URL.Path, "/")[3]
215+
feedName, err := feed.FeedNameFromPath(r.URL.Path)
209216

210-
f, err := feed.GetFeed(api.BasePath, feedName, secret)
217+
f, err := feed.GetFeed(api.BasePath, *feedName, secret)
211218

212219
if err != nil {
213220
yberr := err.(*feed.FeedError)
@@ -234,9 +241,9 @@ func (api *ApiHandler) feedItemDeleteHandlerFunc(w http.ResponseWriter, r *http.
234241

235242
secret, _ := utils.GetSecret(r)
236243

237-
feedName := strings.Split(r.URL.Path, "/")[3]
244+
feedName, err := feed.FeedNameFromPath(r.URL.Path)
238245

239-
f, err := feed.GetFeed(api.BasePath, feedName, secret)
246+
f, err := feed.GetFeed(api.BasePath, *feedName, secret)
240247

241248
if err != nil {
242249
yberr := err.(*feed.FeedError)

web/ui/src/YBFeed/YBBreadCrumb.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function YBBreadCrumb() {
1515

1616
if (p.length > 1 && p[1] !== "") {
1717
items.push({
18-
title: window.location.pathname.split("/")[1],
18+
title: decodeURIComponent(window.location.pathname.split("/")[1]),
1919
})
2020
}
2121
return (

web/ui/src/YBFeed/YBFeedItemImage.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function FeedItemImage(props:FeedItemProps) {
2626
img.onload = imageLoaded
2727

2828
})
29-
img.src = "/api/feed/"+feed+"/"+name
29+
img.src = "/api/feed/"+encodeURIComponent(feed)+"/"+name
3030

3131
let mime = 'image/png'
3232
navigator.clipboard.write([new ClipboardItem({[mime]:imageDataPromise})])
@@ -43,7 +43,7 @@ export function FeedItemImage(props:FeedItemProps) {
4343
<div className="itemContainer">
4444
<div className="itemImg">
4545
<Image
46-
src={"/api/feed/"+feed+"/"+name}
46+
src={"/api/feed/"+encodeURIComponent(feed)+"/"+name}
4747
preview={false}
4848
/>
4949
{showCopyButton?

web/ui/src/YBFeed/YBFeedItemText.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function FeedItemText(props:FeedItemProps) {
1515
}
1616

1717
useEffect(() => {
18-
fetch("/api/feed/"+feed+"/"+name,{
18+
fetch("/api/feed/"+encodeURIComponent(feed)+"/"+name,{
1919
credentials: "include"
2020
})
2121
.then(r => {

web/ui/src/YBFeed/YBPasteCard.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export function YBPasteCard(props:PasteCardProps) {
3939

4040
const requestHeaders: HeadersInit = new Headers();
4141
requestHeaders.set("Content-Type", type)
42-
fetch("/api/feed/" + feed,{
42+
fetch("/api/feed/" + encodeURIComponent(feed!),{
4343
method: "POST",
4444
body: data,
4545
headers: requestHeaders,
@@ -52,7 +52,7 @@ export function YBPasteCard(props:PasteCardProps) {
5252
const handleFinish = () => {
5353
const requestHeaders: HeadersInit = new Headers();
5454
requestHeaders.set("Content-Type", "text/plain")
55-
fetch("/api/feed/" + feed,{
55+
fetch("/api/feed/" + encodeURIComponent(feed!),{
5656
method: "POST",
5757
body: textFieldValue,
5858
headers: requestHeaders,

web/ui/src/routes/feed.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default function FeedComponent() {
4444
// Update feed is run every 2s or o, some events
4545
//
4646
function update() {
47-
fetch("/api/feed/"+feed,{
47+
fetch("/api/feed/"+encodeURIComponent(feed!),{
4848
credentials: "include"
4949
})
5050
.then(r => {

web/ui/src/routes/root.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default function Root() {
99
const [goToPath,setGoToPath] = useState("")
1010

1111
const handleFinish = (values: any) => {
12-
setGoToPath("/" + feed)
12+
setGoToPath("/" + encodeURIComponent(feed))
1313
}
1414

1515
if (window.location.pathname !== "/") {

0 commit comments

Comments
 (0)