mirror of
https://github.com/navidrome/navidrome.git
synced 2026-02-08 14:01:10 -05:00
Compare commits
1 Commits
transcodin
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a4722802a |
@@ -6,6 +6,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/chi/v5/middleware"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
@@ -26,6 +27,8 @@ import (
|
|||||||
|
|
||||||
const Version = "1.16.1"
|
const Version = "1.16.1"
|
||||||
|
|
||||||
|
var validJSIdentifier = regexp.MustCompile(`^[a-zA-Z_$][a-zA-Z0-9_$.]*$`)
|
||||||
|
|
||||||
type handler = func(*http.Request) (*responses.Subsonic, error)
|
type handler = func(*http.Request) (*responses.Subsonic, error)
|
||||||
type handlerRaw = func(http.ResponseWriter, *http.Request) (*responses.Subsonic, error)
|
type handlerRaw = func(http.ResponseWriter, *http.Request) (*responses.Subsonic, error)
|
||||||
|
|
||||||
@@ -315,8 +318,17 @@ func sendResponse(w http.ResponseWriter, r *http.Request, payload *responses.Sub
|
|||||||
wrapper := &responses.JsonWrapper{Subsonic: *payload}
|
wrapper := &responses.JsonWrapper{Subsonic: *payload}
|
||||||
response, err = json.Marshal(wrapper)
|
response, err = json.Marshal(wrapper)
|
||||||
case "jsonp":
|
case "jsonp":
|
||||||
w.Header().Set("Content-Type", "application/javascript")
|
|
||||||
callback, _ := p.String("callback")
|
callback, _ := p.String("callback")
|
||||||
|
if !validJSIdentifier.MatchString(callback) {
|
||||||
|
log.Warn(r.Context(), "Invalid JSONP callback parameter", "callback", callback)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
errResp := newResponse()
|
||||||
|
errResp.Status = responses.StatusFailed
|
||||||
|
errResp.Error = &responses.Error{Code: responses.ErrorGeneric, Message: "invalid callback parameter"}
|
||||||
|
response, _ = json.Marshal(responses.JsonWrapper{Subsonic: *errResp})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/javascript")
|
||||||
wrapper := &responses.JsonWrapper{Subsonic: *payload}
|
wrapper := &responses.JsonWrapper{Subsonic: *payload}
|
||||||
response, err = json.Marshal(wrapper)
|
response, err = json.Marshal(wrapper)
|
||||||
response = fmt.Appendf(nil, "%s(%s)", callback, response)
|
response = fmt.Appendf(nil, "%s(%s)", callback, response)
|
||||||
|
|||||||
@@ -73,6 +73,49 @@ var _ = Describe("sendResponse", func() {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(wrapper.Subsonic.Status).To(Equal(payload.Status))
|
Expect(wrapper.Subsonic.Status).To(Equal(payload.Status))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("should accept valid callback names with dots", func() {
|
||||||
|
q := r.URL.Query()
|
||||||
|
q.Add("f", "jsonp")
|
||||||
|
q.Add("callback", "jQuery.callback_123")
|
||||||
|
r.URL.RawQuery = q.Encode()
|
||||||
|
|
||||||
|
sendResponse(w, r, payload)
|
||||||
|
|
||||||
|
body := w.Body.String()
|
||||||
|
Expect(body).To(HavePrefix("jQuery.callback_123("))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should reject callback with invalid characters", func() {
|
||||||
|
q := r.URL.Query()
|
||||||
|
q.Add("f", "jsonp")
|
||||||
|
q.Add("callback", "alert(1)//")
|
||||||
|
r.URL.RawQuery = q.Encode()
|
||||||
|
|
||||||
|
sendResponse(w, r, payload)
|
||||||
|
|
||||||
|
Expect(w.Header().Get("Content-Type")).To(Equal("application/json"))
|
||||||
|
var wrapper responses.JsonWrapper
|
||||||
|
err := json.Unmarshal(w.Body.Bytes(), &wrapper)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(wrapper.Subsonic.Status).To(Equal(responses.StatusFailed))
|
||||||
|
Expect(wrapper.Subsonic.Error.Message).To(ContainSubstring("invalid callback parameter"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should reject empty callback parameter", func() {
|
||||||
|
q := r.URL.Query()
|
||||||
|
q.Add("f", "jsonp")
|
||||||
|
q.Add("callback", "")
|
||||||
|
r.URL.RawQuery = q.Encode()
|
||||||
|
|
||||||
|
sendResponse(w, r, payload)
|
||||||
|
|
||||||
|
Expect(w.Header().Get("Content-Type")).To(Equal("application/json"))
|
||||||
|
var wrapper responses.JsonWrapper
|
||||||
|
err := json.Unmarshal(w.Body.Bytes(), &wrapper)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(wrapper.Subsonic.Status).To(Equal(responses.StatusFailed))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
When("format is XML or unspecified", func() {
|
When("format is XML or unspecified", func() {
|
||||||
|
|||||||
Reference in New Issue
Block a user