From d3a256bffb172eef2541ce32f2de91681b816632 Mon Sep 17 00:00:00 2001 From: Aki Kareha Date: Fri, 5 Dec 2025 22:23:47 +0900 Subject: [PATCH] Normalize Unicode strings --- go.mod | 2 +- internal/action/edit.go | 5 ++++- internal/action/handler.go | 5 ++++- internal/action/image.go | 5 ++++- internal/action/search.go | 5 ++++- internal/action/static.go | 5 ++++- internal/filter/filter.go | 22 +++++++++++++++++----- 7 files changed, 38 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index bd9533f..9daef49 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/openai/openai-go/v3 v3.8.1 github.com/pmezard/go-difflib v1.0.0 golang.org/x/image v0.33.0 + golang.org/x/text v0.31.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -24,5 +25,4 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect golang.org/x/crypto v0.37.0 // indirect golang.org/x/sync v0.18.0 // indirect - golang.org/x/text v0.31.0 // indirect ) diff --git a/internal/action/edit.go b/internal/action/edit.go index 4283c4e..9e5ecf5 100644 --- a/internal/action/edit.go +++ b/internal/action/edit.go @@ -7,6 +7,8 @@ import ( "strconv" "strings" + "golang.org/x/text/unicode/norm" + "github.com/akikareha/himewiki/internal/config" "github.com/akikareha/himewiki/internal/data" "github.com/akikareha/himewiki/internal/filter" @@ -80,7 +82,8 @@ func Edit(cfg *config.Config, w http.ResponseWriter, r *http.Request, params *Pa http.Error(w, "Invalid revision ID", http.StatusInternalServerError) return } - content = r.FormValue("content") + rawContent := r.FormValue("content") + content = norm.NFC.String(rawContent) preview = r.FormValue("preview") save = r.FormValue("save") } diff --git a/internal/action/handler.go b/internal/action/handler.go index 6debca8..545973b 100644 --- a/internal/action/handler.go +++ b/internal/action/handler.go @@ -6,6 +6,8 @@ import ( "strconv" "strings" + "golang.org/x/text/unicode/norm" + "github.com/akikareha/himewiki/internal/config" ) @@ -18,7 +20,8 @@ type Params struct { } func parse(cfg *config.Config, r *http.Request) Params { - name := strings.TrimPrefix(r.URL.Path, "/") + rawName := strings.TrimPrefix(r.URL.Path, "/") + name := norm.NFC.String(rawName) if name == "" { name = cfg.Wiki.Front } diff --git a/internal/action/image.go b/internal/action/image.go index 5c2bff0..089b364 100644 --- a/internal/action/image.go +++ b/internal/action/image.go @@ -9,6 +9,8 @@ import ( "net/url" "strconv" + "golang.org/x/text/unicode/norm" + "github.com/akikareha/himewiki/internal/config" "github.com/akikareha/himewiki/internal/data" "github.com/akikareha/himewiki/internal/filter" @@ -54,7 +56,8 @@ func Upload(cfg *config.Config, w http.ResponseWriter, r *http.Request, params * return } - name = r.FormValue("name") + rawName := r.FormValue("name") + name = norm.NFC.String(rawName) if name == "" { http.Error(w, "name required", http.StatusBadRequest) return diff --git a/internal/action/search.go b/internal/action/search.go index 1098bf5..b8189df 100644 --- a/internal/action/search.go +++ b/internal/action/search.go @@ -5,6 +5,8 @@ import ( "strconv" "strings" + "golang.org/x/text/unicode/norm" + "github.com/akikareha/himewiki/internal/config" "github.com/akikareha/himewiki/internal/data" "github.com/akikareha/himewiki/internal/templates" @@ -17,7 +19,8 @@ func Search(cfg *config.Config, w http.ResponseWriter, r *http.Request, params * page = 1 } - word := r.URL.Query().Get("w") + rawWord := r.URL.Query().Get("w") + word := norm.NFC.String(rawWord) searchType := r.URL.Query().Get("t") var results []string if word != "" { diff --git a/internal/action/static.go b/internal/action/static.go index f5a4cb6..94d0c39 100644 --- a/internal/action/static.go +++ b/internal/action/static.go @@ -9,6 +9,8 @@ import ( "path/filepath" "strings" + "golang.org/x/text/unicode/norm" + "github.com/akikareha/himewiki/internal/config" ) @@ -18,7 +20,8 @@ func handleStatic(cfg *config.Config, w http.ResponseWriter, r *http.Request) bo log.Fatalf("Invalid static dir: %v", err) } - cleanPath := filepath.Clean(r.URL.Path) + path := norm.NFC.String(r.URL.Path) + cleanPath := filepath.Clean(path) staticPath := filepath.Join(baseDir, cleanPath) if !strings.HasPrefix(staticPath, baseDir + string(os.PathSeparator)) { return false diff --git a/internal/filter/filter.go b/internal/filter/filter.go index 89c470f..6b11499 100644 --- a/internal/filter/filter.go +++ b/internal/filter/filter.go @@ -3,22 +3,30 @@ package filter import ( "fmt" + "golang.org/x/text/unicode/norm" + "github.com/akikareha/himewiki/internal/config" ) func Apply(cfg *config.Config, title string, content string) (string, error) { + normTitle := norm.NFC.String(title) + normContent := norm.NFC.String(content) + if cfg.Filter.Agent == "openai" { - return withOpenAI(cfg, title, content) + filtered, err := withOpenAI(cfg, normTitle, normContent) + return norm.NFC.String(filtered), err } else if cfg.Filter.Agent == "nil" { - return content, nil + return normContent, nil } else { return "", fmt.Errorf("Invalid filter agent. If you want to disable filter, set it to \"nil\".") } } func ImageApply(cfg *config.Config, title string, data []byte) ([]byte, error) { + normTitle := norm.NFC.String(title) + if cfg.ImageFilter.Agent == "openai" { - return imageWithOpenAI(cfg, title, data) + return imageWithOpenAI(cfg, normTitle, data) } else if cfg.ImageFilter.Agent == "nil" { return data, nil } else { @@ -27,10 +35,14 @@ func ImageApply(cfg *config.Config, title string, data []byte) ([]byte, error) { } func GnomeApply(cfg *config.Config, title string, content string) (string, error) { + normTitle := norm.NFC.String(title) + normContent := norm.NFC.String(content) + if cfg.Gnome.Agent == "openai" { - return gnomeWithOpenAI(cfg, title, content) + filtered, err := gnomeWithOpenAI(cfg, normTitle, normContent) + return norm.NFC.String(filtered), err } else if cfg.Gnome.Agent == "nil" { - return content, nil + return normContent, nil } else { return "", fmt.Errorf("Invalid gnome filter agent. If you want to disable filter, set it to \"nil\".") }