support youtu.be urls

add noscript tags for video embeds
support youtube timestamps
validate youtube video parameters

add more parser tests
This commit is contained in:
Azareal 2020-06-25 17:46:09 +10:00
parent 7f1cd665ca
commit c4f2f0df90
2 changed files with 120 additions and 17 deletions

View File

@ -1037,6 +1037,7 @@ func parseMediaString(data string, settings *ParseSettings) (media MediaEmbed, o
media.Trusted = samesite media.Trusted = samesite
path := uurl.EscapedPath() path := uurl.EscapedPath()
//fmt.Println("path:", path)
pathFrags := strings.Split(path, "/") pathFrags := strings.Split(path, "/")
if len(pathFrags) >= 2 { if len(pathFrags) >= 2 {
if samesite && pathFrags[1] == "attachs" && (scheme == "http:" || scheme == "https:") { if samesite && pathFrags[1] == "attachs" && (scheme == "http:" || scheme == "https:") {
@ -1067,22 +1068,90 @@ func parseMediaString(data string, settings *ParseSettings) (media MediaEmbed, o
} }
} }
//fmt.Printf("settings.NoEmbed: %+v\n", settings.NoEmbed)
//settings.NoEmbed = false
if !settings.NoEmbed { if !settings.NoEmbed {
// ? - I don't think this hostname will hit every YT domain // ? - I don't think this hostname will hit every YT domain
// TODO: Make this a more customisable handler rather than hard-coding it in here // TODO: Make this a more customisable handler rather than hard-coding it in here
ytInvalid := func(v string) bool {
for _, ch := range v {
if !((ch > 47 && ch < 58) || (ch > 64 && ch < 91) || (ch > 96 && ch < 123) || ch == '-' || ch == '_') {
var sport string
if port != "443" && port != "80" && port != "" {
sport = ":" + port
}
var q string
if len(uurl.RawQuery) > 0 {
q = "?" + uurl.RawQuery
}
var frag string
if len(uurl.Fragment) > 0 {
frag = "#" + uurl.Fragment
}
media.FURL = host + sport + path + q + frag
media.URL = scheme + "//" + media.FURL
//fmt.Printf("ytInvalid true: %+v\n",v)
return true
}
}
return false
}
ytInvalid2 := func(t string) bool {
for _, ch := range t {
if !((ch > 47 && ch < 58) || ch == 'h' || ch =='m' || ch =='s') {
//fmt.Printf("ytInvalid2 true: %+v\n",t)
return true
}
}
return false
}
if strings.HasSuffix(host, ".youtube.com") && path == "/watch" { if strings.HasSuffix(host, ".youtube.com") && path == "/watch" {
video, ok := query["v"] video, ok := query["v"]
if ok && len(video) >= 1 && video[0] != "" { if ok && len(video) >= 1 && video[0] != "" {
media.Type = ERawExternal v := video[0]
// TODO: Filter the URL to make sure no nasties end up in there if ytInvalid(v) {
media.Body = "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/" + video[0] + "'frameborder=0 allowfullscreen></iframe>"
return media, true return media, true
} }
var t,t2 string
tt, ok := query["t"]
if ok && len(tt) >= 1 {
t, t2 = tt[0], tt[0]
}
media.Type = ERawExternal
if t != "" && !ytInvalid2(t) {
s,m,h := parseDuration(t2)
calc := s + (m * 60) + (h * 60 * 60)
if calc > 0 {
t = "&t="+t
t2 = "?start="+strconv.Itoa(calc)
} else {
t, t2 = "",""
}
}
l := "https://"+ host + path+"?v="+v+t
media.Body = "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/" + v+t2 + "'frameborder=0 allowfullscreen></iframe><noscript><a href='" + l+"'>"+l+"</a></noscript>"
return media, true
}
} else if host == "youtu.be" {
v := strings.TrimPrefix(path,"/")
if ytInvalid(v) {
return media, true
}
l := "https://youtu.be/"+v
media.Type = ERawExternal
media.Body = "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/" + v + "'frameborder=0 allowfullscreen></iframe><noscript><a href='" + l+"'>"+l+"</a></noscript>"
return media, true
} else if strings.HasPrefix(host, "www.nicovideo.jp") && strings.HasPrefix(path, "/watch/sm") { } else if strings.HasPrefix(host, "www.nicovideo.jp") && strings.HasPrefix(path, "/watch/sm") {
vid, err := strconv.ParseInt(strings.TrimPrefix(path, "/watch/sm"), 10, 64) vid, err := strconv.ParseInt(strings.TrimPrefix(path, "/watch/sm"), 10, 64)
if err == nil { if err == nil {
var sport string
if port != "443" && port != "80" && port != "" {
sport = ":" + port
}
media.Type = ERawExternal media.Type = ERawExternal
media.Body = "<iframe class='postIframe'src='https://embed.nicovideo.jp/watch/sm" + strconv.FormatInt(vid, 10) + "?jsapi=1&amp;playerId=1'frameborder=0 allowfullscreen></iframe>" sm := strconv.FormatInt(vid, 10)
l := "https://"+ host + sport + path
media.Body = "<iframe class='postIframe'src='https://embed.nicovideo.jp/watch/sm" + sm + "?jsapi=1&amp;playerId=1'frameborder=0 allowfullscreen></iframe><noscript><a href='" + l+"'>"+l+"</a></noscript>"
return media, true return media, true
} }
} }
@ -1123,6 +1192,30 @@ func parseMediaString(data string, settings *ParseSettings) (media MediaEmbed, o
return media, true return media, true
} }
func parseDuration(dur string) (s,m,h int) {
var ibuf []byte
for _, ch := range dur {
switch {
case ch > 47 && ch < 58:
ibuf = append(ibuf,byte(ch))
case ch == 'h':
h, _ = strconv.Atoi(string(ibuf))
ibuf = ibuf[:0]
case ch == 'm':
m, _ = strconv.Atoi(string(ibuf))
ibuf = ibuf[:0]
case ch == 's':
s, _ = strconv.Atoi(string(ibuf))
ibuf = ibuf[:0]
}
}
// Stop accidental uses of timestamps
if h == 0 && m == 0 && s < 2 {
s = 0
}
return s,m,h
}
// TODO: Write a test for this // TODO: Write a test for this
func CoerceIntString(data string) (res, length int) { func CoerceIntString(data string) (res, length int) {
if !(data[0] > 47 && data[0] < 58) { if !(data[0] > 47 && data[0] < 58) {

View File

@ -263,28 +263,38 @@ func TestParser(t *testing.T) {
local("127.0.0.1") local("127.0.0.1")
local("[::1]") local("[::1]")
l.Add("https://www.youtube.com/watch?v=lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe>") l.Add("https://www.youtube.com/watch?v=lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala'>https://www.youtube.com/watch?v=lalalalala</a></noscript>")
//l.Add("https://www.youtube.com/watch?v=;","<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/;'frameborder=0 allowfullscreen></iframe>") l.Add("https://www.youtube.com/watch?v=lalalalala&t=30s", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala?start=30'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala&t=30s'>https://www.youtube.com/watch?v=lalalalala&t=30s</a></noscript>")
l.Add("https://www.youtube.com/watch?v=d;", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/d'frameborder=0 allowfullscreen></iframe>") l.Add("https://www.youtube.com/watch?v=lalalalala&t=1s", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala'>https://www.youtube.com/watch?v=lalalalala</a></noscript>")
l.Add("https://www.youtube.com/watch?v=d;d", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/d'frameborder=0 allowfullscreen></iframe>") l.Add("https://www.youtube.com/watch?v=lalalalala&t=1", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala'>https://www.youtube.com/watch?v=lalalalala</a></noscript>")
//l.Add("https://www.youtube.com/watch?v=;","<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/;'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch'>https://www.youtube.com/watch</a></noscript>")
l.Add("https://www.youtube.com/watch?v=d;", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/d'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=d'>https://www.youtube.com/watch?v=d</a></noscript>")
l.Add("https://www.youtube.com/watch?v=d;d", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/d'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=d'>https://www.youtube.com/watch?v=d</a></noscript>")
l.Add("https://www.youtube.com/watch?v=alert()", "<red>[Invalid URL]</red>()") l.Add("https://www.youtube.com/watch?v=alert()", "<red>[Invalid URL]</red>()")
l.Add("https://www.youtube.com/watch?v=alert()()", "<red>[Invalid URL]</red>()()") l.Add("https://www.youtube.com/watch?v=alert()()", "<red>[Invalid URL]</red>()()")
l.Add("https://www.youtube.com/watch?v=js:alert()", "<red>[Invalid URL]</red>()") l.Add("https://www.youtube.com/watch?v=js:alert()", "<red>[Invalid URL]</red>()")
l.Add("https://www.youtube.com/watch?v='+><script>alert(\"\")</script><+'", "<red>[Invalid URL]</red>'+><script>alert(\"\")</script><+'") l.Add("https://www.youtube.com/watch?v='+><script>alert(\"\")</script><+'", "<red>[Invalid URL]</red>'+><script>alert(\"\")</script><+'")
l.Add("https://www.youtube.com/watch?v='+onready='alert(\"\")'+'", "<red>[Invalid URL]</red>'+onready='alert(\"\")'+'") l.Add("https://www.youtube.com/watch?v='+onready='alert(\"\")'+'", "<red>[Invalid URL]</red>'+onready='alert(\"\")'+'")
l.Add(" https://www.youtube.com/watch?v=lalalalala", " <iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe>") l.Add(" https://www.youtube.com/watch?v=lalalalala", " <iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala'>https://www.youtube.com/watch?v=lalalalala</a></noscript>")
l.Add("https://www.youtube.com/watch?v=lalalalala tt", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe> tt") l.Add("https://www.youtube.com/watch?v=lalalalala tt", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala'>https://www.youtube.com/watch?v=lalalalala</a></noscript> tt")
l.Add("https://www.youtube.com/watch?v=lalalalala&d=haha", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe>") l.Add("https://www.youtube.com/watch?v=lalalalala&d=haha", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala'>https://www.youtube.com/watch?v=lalalalala</a></noscript>")
l.Add("https://gaming.youtube.com/watch?v=lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe>") l.Add("https://gaming.youtube.com/watch?v=lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://gaming.youtube.com/watch?v=lalalalala'>https://gaming.youtube.com/watch?v=lalalalala</a></noscript>")
l.Add("https://gaming.youtube.com/watch?v=lalalalala&d=haha", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe>") l.Add("https://gaming.youtube.com/watch?v=lalalalala&d=haha", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://gaming.youtube.com/watch?v=lalalalala'>https://gaming.youtube.com/watch?v=lalalalala</a></noscript>")
l.Add("https://m.youtube.com/watch?v=lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe>") l.Add("https://youtu.be/lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://youtu.be/lalalalala'>https://youtu.be/lalalalala</a></noscript>")
l.Add("https://m.youtube.com/watch?v=lalalalala&d=haha", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe>") l.Add("https://m.youtube.com/watch?v=lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://m.youtube.com/watch?v=lalalalala'>https://m.youtube.com/watch?v=lalalalala</a></noscript>")
l.Add("http://www.youtube.com/watch?v=lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe>") l.Add("https://m.youtube.com/watch?v=lalalalala&d=haha", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://m.youtube.com/watch?v=lalalalala'>https://m.youtube.com/watch?v=lalalalala</a></noscript>")
l.Add("//www.youtube.com/watch?v=lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe>") l.Add("http://www.youtube.com/watch?v=lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala'>https://www.youtube.com/watch?v=lalalalala</a></noscript>")
//l.Add("www.youtube.com/watch?v=lalalalala","<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe>") l.Add("//www.youtube.com/watch?v=lalalalala", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala'>https://www.youtube.com/watch?v=lalalalala</a></noscript>")
//l.Add("www.youtube.com/watch?v=lalalalala","<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala'>https://www.youtube.com/watch?v=lalalalala</a></noscript>")
l.Add("https://www.nicovideo.jp/watch/sm111111", "<iframe class='postIframe'src='https://embed.nicovideo.jp/watch/sm111111?jsapi=1&amp;playerId=1'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.nicovideo.jp/watch/sm111111'>https://www.nicovideo.jp/watch/sm111111</a></noscript>")
//l.Add("www.nicovideo.jp/watch/sm111111", "<iframe class='postIframe'src='https://embed.nicovideo.jp/watch/sm111111?jsapi=1&amp;playerId=1'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.nicovideo.jp/watch/sm111111'>www.nicovideo.jp/watch/sm111111</a></noscript>")
//l.Add("www.nicovideo.jp/watch/smlalalalala", "<a href='www.nicovideo.jp/watch/smlalalalala'>www.nicovideo.jp/watch/smlalalalala</a>")
l.Add("https://www.nicovideo.jp/watch/smlalalalala", "<a rel='ugc'href='https://www.nicovideo.jp/watch/smlalalalala'>www.nicovideo.jp/watch/smlalalalala</a>")
l.Add("//www.youtube.com/watch?v=lalalalala&t=30s", "<iframe class='postIframe'src='https://www.youtube-nocookie.com/embed/lalalalala?start=30'frameborder=0 allowfullscreen></iframe><noscript><a href='https://www.youtube.com/watch?v=lalalalala&t=30s'>https://www.youtube.com/watch?v=lalalalala&t=30s</a></noscript>")
l.Add("#tid-1", "<a href='/topic/1'>#tid-1</a>") l.Add("#tid-1", "<a href='/topic/1'>#tid-1</a>")
l.Add("##tid-1", "##tid-1") l.Add("##tid-1", "##tid-1")
l.Add("#@tid-1", "#@tid-1")
l.Add("# #tid-1", "# #tid-1") l.Add("# #tid-1", "# #tid-1")
l.Add("@ #tid-1", "<red>[Invalid Profile]</red>#tid-1") l.Add("@ #tid-1", "<red>[Invalid Profile]</red>#tid-1")
l.Add("@#tid-1", "<red>[Invalid Profile]</red>tid-1") l.Add("@#tid-1", "<red>[Invalid Profile]</red>tid-1")