Merged branch ritschwumm-wip/escape into master

This commit is contained in:
Naoki Takezoe
2016-01-31 12:26:37 +09:00
2 changed files with 38 additions and 4 deletions

View File

@@ -9,7 +9,7 @@ import gitbucket.core.plugin.{RenderRequest, PluginRegistry}
import gitbucket.core.service.{RepositoryService, RequestCache}
import gitbucket.core.util.{FileUtil, JGitUtil, StringUtil}
import play.twirl.api.Html
import play.twirl.api.{Html, HtmlFormat}
/**
* Provides helper methods for Twirl templates.
@@ -306,6 +306,19 @@ object helpers extends AvatarImageProvider with LinkConverter with RequestCache
private[this] val detectAndRenderLinksRegex = """(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,13}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))""".r
def detectAndRenderLinks(text: String): Html = {
Html(detectAndRenderLinksRegex.replaceAllIn(text, m => s"""<a href="${m.group(0)}">${m.group(0)}</a>"""))
val matches = detectAndRenderLinksRegex.findAllMatchIn(text).toSeq
val (x, pos) = matches.foldLeft((collection.immutable.Seq.empty[Html], 0)){ case ((x, pos), m) =>
val url = m.group(0)
val href = url.replace("\"", "&quot;")
(x ++ (Seq(
if(pos < m.start) Some(HtmlFormat.escape(text.substring(pos, m.start))) else None,
Some(Html(s"""<a href="${href}">${url}</a>"""))
).flatten), m.end)
}
// append rest fragment
val out = if (pos < text.length) x :+ HtmlFormat.escape(text.substring(pos)) else x
HtmlFormat.fill(out)
}
}

View File

@@ -32,7 +32,28 @@ class HelpersSpec extends Specification {
after mustEqual """Example Project. <a href="http://example.com">http://example.com</a>. (See also <a href="https://github.com/">https://github.com/</a>)"""
}
"properly escape html metacharacters" in {
val before = "<>&"
val after = detectAndRenderLinks(before).toString()
after mustEqual """&lt;&gt;&amp;"""
}
"escape html metacharacters adjacent to a link" in {
val before = "<http://example.com>"
val after = detectAndRenderLinks(before).toString()
after mustEqual """&lt;<a href="http://example.com">http://example.com</a>&gt;"""
}
"stop link recognition at a metacharacter" in {
val before = "http://exa<mple.com"
val after = detectAndRenderLinks(before).toString()
after mustEqual """<a href="http://exa">http://exa</a>&lt;mple.com"""
}
"make sure there are no double quotes in the href attribute" in {
val before = "http://exa\"mple.com"
val after = detectAndRenderLinks(before).toString()
after mustEqual """<a href="http://exa&quot;mple.com">http://exa"mple.com</a>"""
}
}
}