From 43040f1fda012aad3fdd47f4108a54990bd4c914 Mon Sep 17 00:00:00 2001 From: Michael Vitz Date: Mon, 29 Dec 2014 10:16:38 +0100 Subject: [PATCH 1/2] Add URI escaping for hashtags. Hashtags are now able to contain characters which aren't valid as query parameter because these are now escaped. Fixes #157. --- src/statuses/views/common.clj | 6 ++++-- test/linkification.clj | 13 ++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/statuses/views/common.clj b/src/statuses/views/common.clj index 82b19a1..45d2c60 100644 --- a/src/statuses/views/common.clj +++ b/src/statuses/views/common.clj @@ -1,5 +1,7 @@ (ns statuses.views.common - (:require [hiccup.util :refer [escape-html]])) + (:require [hiccup.core :refer [html]] + [hiccup.element :refer [link-to]] + [hiccup.util :refer [escape-html url]])) (defn icon [icon-name] [:span {:class (str "fa fa-" icon-name)}]) @@ -11,7 +13,7 @@ (defn linkify [text] (let [handle (fn [[_ m]] (str "@" m "")) - hashtag (fn [[_ m]] (str "#" m "")) + hashtag (fn [[_ m]] (html "#" (link-to (url "/statuses/updates" {:query (str "#" m)}) m))) anchor (fn [[m _]] (str "" m "")) mailto (fn [[m _]] (str "" m ""))] (-> text diff --git a/test/linkification.clj b/test/linkification.clj index a9cfa1a..4c1ad5c 100644 --- a/test/linkification.clj +++ b/test/linkification.clj @@ -19,13 +19,16 @@ (deftest linkify-hashtags (is (= (linkify "lorem #hashtag ipsum") - "lorem #hashtag ipsum")) + "lorem #hashtag ipsum")) (is (= (linkify "#hashtag lipsum") - "#hashtag lipsum")) + "#hashtag lipsum")) (is (= (linkify "lipsum #hashtag") - "lipsum #hashtag"))) + "lipsum #hashtag")) + (is (= + (linkify "#WTF^2") + "#WTF^2"))) (deftest linkify-uris-with-fragment-identifier (is (= @@ -33,10 +36,10 @@ "lorem http://example.org#anchor ipsum"))) (is (= (linkify "#hashtag lipsum http://example.org#anchor-name") - "#hashtag lipsum http://example.org#anchor-name")) + "#hashtag lipsum http://example.org#anchor-name")) (is (= (linkify "lipsum http://example.org#anchor-name #hashtag") - "lipsum http://example.org#anchor-name #hashtag")) + "lipsum http://example.org#anchor-name #hashtag")) (deftest linkify-email-addresses (is (= From 09accfeda4894dfaf10ca72db3ace0caff5fdb71 Mon Sep 17 00:00:00 2001 From: Michael Vitz Date: Mon, 29 Dec 2014 10:32:07 +0100 Subject: [PATCH 2/2] Use hiccup for linkifying. Using hiccup deals with many URL related stuff like escaping which should be safer than assembling links by ourself. --- src/statuses/views/common.clj | 10 +++++----- test/linkification.clj | 26 +++++++++++++------------- test/statuses/views/test/atom.clj | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/statuses/views/common.clj b/src/statuses/views/common.clj index 45d2c60..4f617e6 100644 --- a/src/statuses/views/common.clj +++ b/src/statuses/views/common.clj @@ -1,6 +1,6 @@ (ns statuses.views.common (:require [hiccup.core :refer [html]] - [hiccup.element :refer [link-to]] + [hiccup.element :refer [link-to mail-to]] [hiccup.util :refer [escape-html url]])) (defn icon [icon-name] @@ -12,10 +12,10 @@ (def email #"([a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)") (defn linkify [text] - (let [handle (fn [[_ m]] (str "@" m "")) - hashtag (fn [[_ m]] (html "#" (link-to (url "/statuses/updates" {:query (str "#" m)}) m))) - anchor (fn [[m _]] (str "" m "")) - mailto (fn [[m _]] (str "" m ""))] + (letfn [(handle [[_ m]] (html "@" (link-to (url "/statuses/updates" {:author m}) m))) + (hashtag [[_ m]] (html "#" (link-to (url "/statuses/updates" {:query (str "#" m)}) m))) + (anchor [[m _]] (html (link-to m m))) + (mailto [[m _]] (html (mail-to m)))] (-> text escape-html (clojure.string/replace #"(?:^|(?<=\s))@(\w+)" handle) diff --git a/test/linkification.clj b/test/linkification.clj index 4c1ad5c..ffda2f1 100644 --- a/test/linkification.clj +++ b/test/linkification.clj @@ -8,13 +8,13 @@ (deftest linkify-uris (is (= (linkify "lorem http://example.org ipsum") - "lorem http://example.org ipsum")) + "lorem http://example.org ipsum")) (is (= (linkify "http://example.org lipsum") - "http://example.org lipsum")) + "http://example.org lipsum")) (is (= (linkify "lipsum http://example.org") - "lipsum http://example.org"))) + "lipsum http://example.org"))) (deftest linkify-hashtags (is (= @@ -33,38 +33,38 @@ (deftest linkify-uris-with-fragment-identifier (is (= (linkify "lorem http://example.org#anchor ipsum") - "lorem http://example.org#anchor ipsum"))) + "lorem http://example.org#anchor ipsum"))) (is (= (linkify "#hashtag lipsum http://example.org#anchor-name") - "#hashtag lipsum http://example.org#anchor-name")) + "#hashtag lipsum http://example.org#anchor-name")) (is (= (linkify "lipsum http://example.org#anchor-name #hashtag") - "lipsum http://example.org#anchor-name #hashtag")) + "lipsum http://example.org#anchor-name #hashtag")) (deftest linkify-email-addresses (is (= (linkify "hello foo@example.org how are you") - "hello foo@example.org how are you"))) + "hello foo@example.org how are you"))) (deftest linkify-mentions (is (= (linkify "@foo") - "@foo")) + "@foo")) (is (= (linkify "@foo how are you") - "@foo how are you")) + "@foo how are you")) (is (= (linkify "how are you @foo") - "how are you @foo")) + "how are you @foo")) (is (= (linkify "nice to see @foo again") - "nice to see @foo again")) + "nice to see @foo again")) (is (= (linkify "@?") "@?")) (is (= (linkify "@foo: test") - "@foo: test")) + "@foo: test")) (is (= (linkify "@foo.bar test") - "@foo.bar test"))) + "@foo.bar test"))) diff --git a/test/statuses/views/test/atom.clj b/test/statuses/views/test/atom.clj index 6718d62..145fd87 100644 --- a/test/statuses/views/test/atom.clj +++ b/test/statuses/views/test/atom.clj @@ -56,7 +56,7 @@ (is (= (get (entry (feed-with-entry {:text "@bar: http://www.test.de"})) 3) [:content {:type "html"} - "@<a href='/statuses/updates?author=bar'>bar</a>: <a href='http://www.test.de'>http://www.test.de</a>"]) + "@<a href="/statuses/updates?author=bar">bar</a>: <a href="http://www.test.de">http://www.test.de</a>"]) "content is linkified and escaped") (is (= (get (entry (feed-with-entry {:id 1337})) 4)