Signed-off-by: Winter winter@winter.cafe
+17
-3
knotserver/routes.go
+17
-3
knotserver/routes.go
···
361
362
ref := strings.TrimSuffix(file, ".tar.gz")
363
364
// This allows the browser to use a proper name for the file when
365
// downloading
366
-
filename := fmt.Sprintf("%s-%s.tar.gz", name, ref)
367
setContentDisposition(w, filename)
368
setGZipMIME(w)
369
370
path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r))
371
-
gr, err := git.Open(path, ref)
372
if err != nil {
373
notFound(w)
374
return
···
377
gw := gzip.NewWriter(w)
378
defer gw.Close()
379
380
-
prefix := fmt.Sprintf("%s-%s", name, ref)
381
err = gr.WriteTar(gw, prefix)
382
if err != nil {
383
// once we start writing to the body we can't report error anymore
···
361
362
ref := strings.TrimSuffix(file, ".tar.gz")
363
364
+
unescapedRef, err := url.PathUnescape(ref)
365
+
if err != nil {
366
+
notFound(w)
367
+
return
368
+
}
369
+
370
+
// For now, only accept `/` in a ref name if it's refs/tags/*
371
+
if strings.Contains(unescapedRef, "/") && !strings.HasPrefix(unescapedRef, "refs/tags/") {
372
+
notFound(w)
373
+
return
374
+
}
375
+
376
+
safeRefFilename := strings.TrimPrefix(unescapedRef, "refs/tags/")
377
+
378
// This allows the browser to use a proper name for the file when
379
// downloading
380
+
filename := fmt.Sprintf("%s-%s.tar.gz", name, safeRefFilename)
381
setContentDisposition(w, filename)
382
setGZipMIME(w)
383
384
path, _ := securejoin.SecureJoin(h.c.Repo.ScanPath, didPath(r))
385
+
gr, err := git.Open(path, unescapedRef)
386
if err != nil {
387
notFound(w)
388
return
···
391
gw := gzip.NewWriter(w)
392
defer gw.Close()
393
394
+
prefix := fmt.Sprintf("%s-%s", name, safeRefFilename)
395
err = gr.WriteTar(gw, prefix)
396
if err != nil {
397
// once we start writing to the body we can't report error anymore