Test the generator refusals and a "'" in the source query
Through the router: a source query holding "'" must reach the upstream as %27. The generator page must answer 400, show the URL pixa would fetch and make no encrypted URL for a source path holding %2F next to a space, a "|" or a letter outside ASCII, and for a source URL holding a user name and password. It must also refuse a source path holding a ".." segment, as /v1/image/ does. These fail on the branch; the fix follows. Model: opus-5-5
This commit is contained in:
@@ -157,10 +157,11 @@ func postGenerate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TestImageURLFetchesItsSourcePathAndQuery requests image URLs whose source
|
// TestImageURLFetchesItsSourcePathAndQuery requests image URLs whose source
|
||||||
// query holds a space and whose source path holds a "%", each written
|
// query holds a space, written percent-encoded, or a "'", and whose source
|
||||||
// percent-encoded, and checks the one request the upstream receives: the
|
// path holds a "%", written percent-encoded, and checks the one request the
|
||||||
// source path percent-encoded again, and the source query with the space
|
// upstream receives: the source path percent-encoded again, and the source
|
||||||
// written %20.
|
// query with the space written %20 and the "'" written %27, as a browser
|
||||||
|
// writes them in a query.
|
||||||
func TestImageURLFetchesItsSourcePathAndQuery(t *testing.T) {
|
func TestImageURLFetchesItsSourcePathAndQuery(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -174,6 +175,8 @@ func TestImageURLFetchesItsSourcePathAndQuery(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"space in the query", "/photo.png%3Fname=my%20cat",
|
{"space in the query", "/photo.png%3Fname=my%20cat",
|
||||||
"/photo.png?name=my%20cat"},
|
"/photo.png?name=my%20cat"},
|
||||||
|
{"apostrophe in the query", "/photo.png%3Fname=it's",
|
||||||
|
"/photo.png?name=it%27s"},
|
||||||
{"percent sign in the path", percentSignPath, percentSignPath},
|
{"percent sign in the path", percentSignPath, percentSignPath},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,30 +308,64 @@ func TestGeneratedURLFetchesTheSourceURLAsEntered(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestGeneratorRefusesSourceURLItWouldFetchAnotherWay submits a source URL
|
// TestGeneratorRefusesSourceURLItCannotFetchAsWritten submits source URLs the
|
||||||
// whose path holds %2F. pixa keeps the path decoded and would fetch it with a
|
// generator page must make no encrypted URL for, and checks that it answers
|
||||||
// "/" there, which is another URL, so the generator page answers 400, shows
|
// 400 and shows why. pixa keeps the source path decoded and fetches it
|
||||||
// the URL pixa would fetch, and makes no encrypted URL.
|
// percent-encoded again, so a path holding %2F would be fetched with a "/"
|
||||||
func TestGeneratorRefusesSourceURLItWouldFetchAnotherWay(t *testing.T) {
|
// there, whatever else the path holds. pixa sends no user name or password,
|
||||||
|
// and no "?" with no query after it. For these the page shows the URL pixa
|
||||||
|
// would fetch. A source path holding a ".." segment is refused, as
|
||||||
|
// /v1/image/ refuses it.
|
||||||
|
func TestGeneratorRefusesSourceURLItCannotFetchAsWritten(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
s, _, _ := startImageProxy(t, startRecordingUpstream(t).Server)
|
|
||||||
|
|
||||||
rec := postGenerate(t, s, "https://"+upstreamHost+"/a%2Fb.png")
|
|
||||||
body := rec.Body.String()
|
|
||||||
|
|
||||||
if rec.Code != http.StatusBadRequest {
|
|
||||||
t.Errorf("status = %d, want %d", rec.Code, http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.Contains(body, "/v1/e/") {
|
|
||||||
t.Error("the page shows an encrypted URL")
|
|
||||||
}
|
|
||||||
|
|
||||||
// The test config sets allow_http, so pixa would fetch over plain HTTP
|
// The test config sets allow_http, so pixa would fetch over plain HTTP
|
||||||
fetchURL := "http://" + upstreamHost + "/a/b.png"
|
const fetchedFrom = "http://" + upstreamHost
|
||||||
if !strings.Contains(body, fetchURL) {
|
|
||||||
t.Errorf("the page does not show the URL pixa would fetch, %s; body %s",
|
tests := []struct {
|
||||||
fetchURL, body)
|
name string
|
||||||
|
// sourceURL is the source URL after "https://"
|
||||||
|
sourceURL string
|
||||||
|
// wantShown is what the page must show: the URL pixa would fetch, or
|
||||||
|
// why it makes no encrypted URL
|
||||||
|
wantShown string
|
||||||
|
}{
|
||||||
|
{"encoded slash", upstreamHost + "/a%2Fb.png",
|
||||||
|
fetchedFrom + "/a/b.png"},
|
||||||
|
{"encoded slash and a space", upstreamHost + "/a%2Fb c.png",
|
||||||
|
fetchedFrom + "/a/b%20c.png"},
|
||||||
|
{"encoded slash and a bar", upstreamHost + "/a%2Fb|c.png",
|
||||||
|
fetchedFrom + "/a/b%7Cc.png"},
|
||||||
|
{"encoded slash and a letter outside ASCII", upstreamHost + "/café%2Fx.png",
|
||||||
|
fetchedFrom + "/caf%C3%A9/x.png"},
|
||||||
|
{"user name and password", "user:pass@" + upstreamHost + "/a.png",
|
||||||
|
fetchedFrom + "/a.png"},
|
||||||
|
{"question mark with no query", upstreamHost + "/a.png?",
|
||||||
|
fetchedFrom + "/a.png"},
|
||||||
|
{"two-dot segment", upstreamHost + "/a/../b.png",
|
||||||
|
"cannot hold a .. segment"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
s, _, _ := startImageProxy(t, startRecordingUpstream(t).Server)
|
||||||
|
|
||||||
|
rec := postGenerate(t, s, "https://"+tt.sourceURL)
|
||||||
|
body := rec.Body.String()
|
||||||
|
|
||||||
|
if rec.Code != http.StatusBadRequest {
|
||||||
|
t.Errorf("status = %d, want %d", rec.Code, http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(body, "/v1/e/") {
|
||||||
|
t.Error("the page shows an encrypted URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(body, tt.wantShown) {
|
||||||
|
t.Errorf("the page does not show %s; body %s", tt.wantShown, body)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user