package httpd
import (
"net/http/httptest"
"regexp"
"strings"
"testing"
"time"
"gitbay.org/gitbay/internal/config"
"gitbay.org/gitbay/internal/store"
)
func TestMarkdownMath(t *testing.T) {
cases := []struct {
name, src string
want []string
not []string
}{
{"inline", "Euler: $e^{i\\pi}+1=0$.", []string{`.`}, nil},
{"display inline", "so $$x^2$$ here", []string{`
", "y $$
"}, []string{"ab`}, nil},
{"markup is escaped", "$\\text{&}$", []string{`<b>&</b>`}, []string{""}},
}
for _, c := range cases {
out := string(ugcHTML(c.src, "md"))
for _, w := range c.want {
if !strings.Contains(out, w) {
t.Errorf("%s: lacks %q:\n%s", c.name, w, out)
}
}
for _, w := range c.not {
if strings.Contains(out, w) {
t.Errorf("%s: has %q:\n%s", c.name, w, out)
}
}
}
}
func TestOrgMath(t *testing.T) {
cases := []struct {
name, src string
want []string
not []string
}{
{"dollar", "Euler: $e^x$ here", []string{`ex here`}, nil},
{"paren", `a \(x_1\) b`, []string{``}, []string{`\(`}},
{"bracket", `a \[x^2\] b`, []string{``}, []string{`\[`}},
{"double dollar", `a $$x$$ b`, []string{`x`}, nil},
{"environment block", "\\begin{equation}\nx = \\frac{1}{2}\n\\end{equation}\n", []string{`x=`}, []string{`\begin`}},
{"matrix block", "\\begin{pmatrix}\na & b \\\\\nc & d\n\\end{pmatrix}\n", []string{`a`}, nil},
{"prices", "costs $5 and $10 today", []string{"costs $5 and $10 today"}, []string{"$x^2$", "$y$"}, []string{"\begin{tabular}`}, []string{"` +
`x` +
`(` +
`
` +
`yz` +
``
out := mathPolicy.Sanitize(hostile)
for _, bad := range []string{"href", "xlink", "style", "onclick", "onmouseover", "onerror", "javascript",
"annotation", "semantics", "maction", "mstyle", "mathcolor", "script", "expression",
`mathvariant="bold"`, `stretchy="true"`, "form=", `display="inline"`} {
if strings.Contains(out, bad) {
t.Errorf("sanitized MathML keeps %q:\n%s", bad, out)
}
}
for _, good := range []string{``, ``, "x", "y"} {
if !strings.Contains(out, good) {
t.Errorf("sanitized MathML lacks %q:\n%s", good, out)
}
}
}
// Hostile TeX is refused and shown as escaped source, in bounded time and
// size, on both syntaxes.
func TestHostileMath(t *testing.T) {
long := strings.Repeat(`x+`, 1<<19) // 1 MiB in one expression
deep := strings.Repeat("{", 50000) + "x" + strings.Repeat("}", 50000)
for _, tex := range []string{
`\href{javascript:alert(1)}{x}`, `\url{javascript:alert(1)}`, `\style{color:red}{x}`,
`\color{red" onmouseover="alert(1)}{x}`, `\class{a"b}{x}`, `\def\a{\a\a}\a`,
`\text{}`, `\text{
}`,
deep, long, strings.Repeat(`\sqrt{`, 10000) + "x",
} {
for _, doc := range []struct{ src, format string }{
{"$" + tex + "$", "md"}, {"$$\n" + tex + "\n$$\n", "md"},
{`\(` + tex + `\)`, "org"}, {"\\[" + tex + "\\]", "org"},
} {
start := time.Now()
out := string(ugcHTML(doc.src, doc.format))
if d := time.Since(start); d > 2*time.Second {
t.Errorf("%.30q (%s) took %v", tex, doc.format, d)
}
if len(out) > 8*len(doc.src)+1024 {
t.Errorf("%.30q (%s): %d bytes out for %d in", tex, doc.format, len(out), len(doc.src))
}
for _, bad := range []string{"