Subject: [PATCH links] Strip html tags instead of escaping all input. Fix escaping when displaying sanitized data on feed / list pages.

From: Peter Sanchez <[email-masked]>
Date: Sat, 15 Feb 2025 08:41:47 -0600

Implements: https://todo.code.netlandish.com/~netlandish/links/93
---
You can use the following program to correct any existing entries in
case anyone actually has this running anywhere.

https://paste.sr.ht/~petersanchez/95f653a54e7ad896472e26950bd88446cda974e1

 core/routes.go           |  2 --
 helpers.go               | 12 ++++++------
 templates/feed.html      |  4 ++--
 templates/link_list.html |  6 +++---
 4 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/core/routes.go b/core/routes.go
index 041bc41..8338503 100644
--- a/core/routes.go
+++ b/core/routes.go
@@ -1584,7 +1584,6 @@ func (s *Service) PopularLinkList(c echo.Context) error {
 						meta {
 							image
 							description
-							image
 							siteName
 						}
 					}
@@ -1919,7 +1918,6 @@ func (s *Service) OrgLinksList(c echo.Context) error {
 							meta {
 								image
 								description
-								image
 								siteName
 							}
 						}
diff --git a/helpers.go b/helpers.go
index 6849b95..36a6eb7 100644
--- a/helpers.go
+++ b/helpers.go
@@ -322,33 +322,33 @@ func extract(resp io.Reader) *models.HTMLMeta {
 			if t.Data == "meta" {
 				desc, ok := extractMetaProperty(t, "description")
 				if ok {
-					hm.Description = html.EscapeString(desc)
+					hm.Description = core.StripHtmlTags(desc)
 				}
 
 				ogTitle, ok := extractMetaProperty(t, "og:title")
 				if ok {
-					hm.Title = html.EscapeString(ogTitle)
+					hm.Title = core.StripHtmlTags(ogTitle)
 				}
 
 				ogDesc, ok := extractMetaProperty(t, "og:description")
 				if ok {
-					hm.Description = html.EscapeString(ogDesc)
+					hm.Description = core.StripHtmlTags(ogDesc)
 				}
 
 				ogImage, ok := extractMetaProperty(t, "og:image")
 				if ok {
-					hm.Image = html.EscapeString(ogImage)
+					hm.Image = core.StripHtmlTags(ogImage)
 				}
 
 				ogSiteName, ok := extractMetaProperty(t, "og:site_name")
 				if ok {
-					hm.SiteName = html.EscapeString(ogSiteName)
+					hm.SiteName = core.StripHtmlTags(ogSiteName)
 				}
 			}
 		case html.TextToken:
 			if titleFound {
 				t := z.Token()
-				hm.Title = html.EscapeString(t.Data)
+				hm.Title = core.StripHtmlTags(t.Data)
 				titleFound = false
 			}
 		}
diff --git a/templates/feed.html b/templates/feed.html
index 64657d9..43cfbe2 100644
--- a/templates/feed.html
+++ b/templates/feed.html
@@ -54,9 +54,9 @@
           </h3>
         </div>
         {{if .Description}}
-            <p class="is-marginless">{{truncate .Description 200}}</p>
+            <p class="is-marginless">{{htmlSafe (truncate .Description 200)}}</p>
         {{else if .BaseURLData.Meta.Description}}
-            <p class="is-marginless">{{truncate .BaseURLData.Meta.Description 200}}</p>
+            <p class="is-marginless">{{htmlSafe (truncate .BaseURLData.Meta.Description 200)}}</p>
         {{end}}
         <div class="link-tag mt-1">
             {{range .Tags}}
diff --git a/templates/link_list.html b/templates/link_list.html
index 8f731b5..6048241 100644
--- a/templates/link_list.html
+++ b/templates/link_list.html
@@ -160,12 +160,12 @@
           {{end}}
         </div>
         {{if $.isPopular}}
-            <p class="is-marginless">{{truncate .Data.Meta.Description 200}}</p>
+            <p class="is-marginless">{{htmlSafe (truncate .Data.Meta.Description 200)}}</p>
         {{else}}
             {{if .Description}}
-                <p class="is-marginless">{{truncate .Description 200}}</p>
+                <p class="is-marginless">{{htmlSafe (truncate .Description 200)}}</p>
             {{else if .BaseURLData.Meta.Description}}
-                <p class="is-marginless">{{truncate .BaseURLData.Meta.Description 200}}</p>
+                <p class="is-marginless">{{htmlSafe (truncate .BaseURLData.Meta.Description 200)}}</p>
             {{end}}
         {{end}}
         {{if .Tags}}
-- 
2.47.2