~bouncepaw/mycorrhiza

4e6adec81ab841c8f2ff042702b418ffbb4a569f — Umar Getagazov 1 year, 27 days ago 9b4b225
Validate the revision hash on /rev{,-text}/ pages
3 files changed, 34 insertions(+), 25 deletions(-)

M history/histweb/histview.go
M util/util.go
M web/readers.go
M history/histweb/histview.go => history/histweb/histview.go +1 -10
@@ 3,7 3,6 @@ package histweb

import (
	"embed"
	"encoding/hex"
	"fmt"
	"github.com/bouncepaw/mycorrhiza/cfg"
	"github.com/bouncepaw/mycorrhiza/files"


@@ 39,15 38,7 @@ func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) {
	util.PrepareRq(rq)
	shorterURL := strings.TrimPrefix(rq.URL.Path, "/primitive-diff/")
	revHash, slug, found := strings.Cut(shorterURL, "/")
	if !found || len(revHash) < 7 || len(slug) < 1 {
		http.Error(w, "403 bad request", http.StatusBadRequest)
		return
	}
	paddedRevHash := revHash
	if len(paddedRevHash)%2 != 0 {
		paddedRevHash = paddedRevHash[:len(paddedRevHash)-1]
	}
	if _, err := hex.DecodeString(paddedRevHash); err != nil {
	if !found || !util.IsRevHash(revHash) || len(slug) < 1 {
		http.Error(w, "403 bad request", http.StatusBadRequest)
		return
	}

M util/util.go => util/util.go +15 -0
@@ 135,3 135,18 @@ func (f FormData) Get(key string) string {
func (f FormData) Put(key, value string) {
	f.fields[key] = value
}

// IsRevHash checks if the revision hash is valid.
func IsRevHash(revHash string) bool {
	if len(revHash) < 7 {
		return false
	}
	paddedRevHash := revHash
	if len(paddedRevHash)%2 != 0 {
		paddedRevHash = paddedRevHash[:len(paddedRevHash)-1]
	}
	if _, err := hex.DecodeString(paddedRevHash); err != nil {
		return false
	}
	return true
}

M web/readers.go => web/readers.go +18 -15
@@ 59,12 59,15 @@ func handlerMedia(w http.ResponseWriter, rq *http.Request) {
// /rev-text/<revHash>/<hyphaName>
func handlerRevisionText(w http.ResponseWriter, rq *http.Request) {
	util.PrepareRq(rq)
	shorterURL := strings.TrimPrefix(rq.URL.Path, "/rev-text/")
	revHash, slug, found := strings.Cut(shorterURL, "/")
	if !found || !util.IsRevHash(revHash) || len(slug) < 1 {
		http.Error(w, "403 bad request", http.StatusBadRequest)
		return
	}
	var (
		shorterURL      = strings.TrimPrefix(rq.URL.Path, "/rev-text/")
		firstSlashIndex = strings.IndexRune(shorterURL, '/')
		revHash         = shorterURL[:firstSlashIndex]
		hyphaName       = util.CanonicalName(shorterURL[firstSlashIndex+1:])
		h               = hyphae.ByName(hyphaName)
		hyphaName = util.CanonicalName(slug)
		h         = hyphae.ByName(hyphaName)
	)
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	switch h := h.(type) {


@@ 103,17 106,17 @@ func handlerRevisionText(w http.ResponseWriter, rq *http.Request) {
// handlerRevision displays a specific revision of the text part the hypha
func handlerRevision(w http.ResponseWriter, rq *http.Request) {
	util.PrepareRq(rq)
	lc := l18n.FromRequest(rq)
	shorterURL := strings.TrimPrefix(rq.URL.Path, "/rev/")
	revHash, slug, found := strings.Cut(shorterURL, "/")
	if !found || !util.IsRevHash(revHash) || len(slug) < 1 {
		http.Error(w, "403 bad request", http.StatusBadRequest)
		return
	}
	var (
		lc              = l18n.FromRequest(rq)
		shorterURL      = strings.TrimPrefix(rq.URL.Path, "/rev/")
		firstSlashIndex = strings.IndexRune(shorterURL, '/')
		revHash         = shorterURL[:firstSlashIndex]
		hyphaName       = util.CanonicalName(shorterURL[firstSlashIndex+1:])
		h               = hyphae.ByName(hyphaName)
		contents        = fmt.Sprintf(`<p>%s</p>`, lc.Get("ui.revision_no_text"))
	)

	var (
		hyphaName    = util.CanonicalName(slug)
		h            = hyphae.ByName(hyphaName)
		contents     = fmt.Sprintf(`<p>%s</p>`, lc.Get("ui.revision_no_text"))
		textContents string
		err          error
		mycoFilePath string