Subject: [PATCH links] Limit the tag search input to 50 chars. Also escape extra characters to avoid query errors.

From: Peter Sanchez <[email-masked]>
Date: Thu, 10 Jul 2025 17:39:51 -0600

Changelog-fixed: Issue where tag characters can cause PostgreSQL to
  return errors. Also limit tag queries to tag name limit (50).
---
 core/routes.go |  2 +-
 helpers.go     | 15 ++++++++++++---
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/core/routes.go b/core/routes.go
index aa0c9f5..74ed039 100644
--- a/core/routes.go
+++ b/core/routes.go
@@ -3370,7 +3370,7 @@ func (s *Service) TagAutocomplete(c echo.Context) error {
 	gctx := c.(*server.Context)
 	user := gctx.User.(*models.User)
 	orgID := c.QueryParam("org")
-	q := links.ParseSearch(c.QueryParam("q"))
+	q := links.ParseSearchTag(c.QueryParam("q"))
 	var (
 		tags []*models.Tag
 		err  error
diff --git a/helpers.go b/helpers.go
index 53dd36f..c10907a 100644
--- a/helpers.go
+++ b/helpers.go
@@ -404,7 +404,7 @@ func ParseBaseURL(ctx context.Context, baseURL *models.BaseURL) error {
 		return err
 	}
 
-	baseURL.ParseAttempts += 1
+	baseURL.ParseAttempts++
 	baseURL.LastParseAttempt = sql.NullTime{Valid: true, Time: time.Now().UTC()}
 
 	userAgent := BuildUserAgent(ctx)
@@ -583,8 +583,8 @@ func RenderRestrictedTemplate(c echo.Context) error {
 	gmap := gobwebs.Map{
 		"pd": pd,
 	}
-	if pass_msg, ok := c.Get("pass_msg").(string); ok {
-		gmap["pass_msg"] = pass_msg
+	if passMsg, ok := c.Get("pass_msg").(string); ok {
+		gmap["pass_msg"] = passMsg
 	}
 	curSlug := PullOrgSlug(c)
 	if curSlug != "" {
@@ -877,6 +877,7 @@ func ParseSearch(s string) string {
 			word = strings.TrimSpace(word)
 			word = strings.Replace(word, ":", "\\:", -1)
 			word = strings.Replace(word, "|", "\\|", -1)
+			word = strings.Replace(word, "!", "\\!", -1)
 			if !strings.HasPrefix(word, "-") {
 				word = word + ":*"
 			}
@@ -887,6 +888,14 @@ func ParseSearch(s string) string {
 	return s
 }
 
+// ParseSearchTag is just a helper to limit the size of the input query
+func ParseSearchTag(s string) string {
+	if len(s) > 50 {
+		s = s[:50]
+	}
+	return ParseSearch(s)
+}
+
 func AddQueryElement(q template.URL, param, val string, replace bool) template.URL {
 	query, err := url.ParseQuery(string(q))
 	if err != nil {
-- 
2.49.0