Added limited support for HTML in posts.

Newlines are now stripped from usernames, topic titles, and emails.
This commit is contained in:
Azareal 2017-12-31 07:01:44 +00:00
parent 0fcc1bc04d
commit 1639d81618
5 changed files with 80 additions and 15 deletions

View File

@ -4,6 +4,7 @@ import (
//"fmt"
"bytes"
"html"
"log"
"net/url"
"regexp"
"strconv"
@ -166,28 +167,74 @@ func shortcodeToUnicode(msg string) string {
}
// TODO: Write tests for this
// TODO: Preparse Markdown and normalize it into HTML?
func PreparseMessage(msg string) string {
msg = strings.Replace(msg, "<p><br>", "\n\n", -1)
msg = strings.Replace(msg, "<p>", "\n\n", -1)
msg = strings.Replace(msg, "</p>", "", -1)
msg = strings.Replace(msg, "<br>", "\n\n", -1)
msg = strings.TrimSpace(msg) // There are a few useful cases for having spaces, but I'd like to stop the WYSIWYG from inserting random lines here and there
if Sshooks["preparse_preassign"] != nil {
msg = RunSshook("preparse_preassign", msg)
}
msg = html.EscapeString(msg)
/*var runes = []rune(msg)
var runes = []rune(msg)
msg = ""
//var inBold = false
//var unclosedBolds = 0
var inBold = false
var inItalic = false
var stepForward = func(i int, step int, runes []rune) int {
i += step
if i < len(runes) {
return i
}
return i - step
}
for i := 0; i < len(runes); i++ {
char := runes[i]
if char == '&' && peek(i, 1, runes) == 'l' && peek(i, 2, runes) == 't' && peek(i, 2, runes) == ';' {
i += 2
log.Print("string(char): ", string(char))
if char == '&' && peek(i, 1, runes) == 'l' && peek(i, 2, runes) == 't' && peek(i, 3, runes) == ';' {
log.Print("past less than")
i = stepForward(i, 4, runes)
char := runes[i]
if char == '/' {
log.Print("in /")
i = stepForward(i, 1, runes)
char := runes[i]
if inItalic && char == 'e' && peekMatch(i, "m&gt;", runes) {
log.Print("in inItalic")
i += 5
inItalic = false
msg += "</em>"
} else if inBold && char == 's' && peekMatch(i, "trong&gt;", runes) {
log.Print("in inBold")
i += 9
inBold = false
msg += "</strong>"
}
} else if !inItalic && char == 'e' && peekMatch(i, "m&gt;", runes) {
log.Print("in !inItalic")
i += 5
inItalic = true
msg += "<em>"
} else if !inBold && char == 's' && peekMatch(i, "trong&gt;", runes) {
log.Print("in !inBold")
i += 9
inBold = true
msg += "<strong>"
}
} else {
msg += string(char)
}
}*/
}
if inItalic {
msg += "</em>"
}
if inBold {
msg += "</strong>"
}
return shortcodeToUnicode(msg)
}
@ -200,6 +247,19 @@ func peek(cur int, skip int, runes []rune) rune {
return 0 // null byte
}
// TODO: Test this
func peekMatch(cur int, phrase string, runes []rune) bool {
if cur+len(phrase) > len(runes) {
return false
}
for i, char := range phrase {
if runes[cur+i+1] != char {
return false
}
}
return true
}
// TODO: Write a test for this
// TODO: We need a lot more hooks here. E.g. To add custom media types and handlers.
func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/) string {

View File

@ -11,6 +11,7 @@ import (
"html"
"html/template"
"strconv"
"strings"
"time"
"../query_gen/lib"
@ -238,7 +239,7 @@ func (topic *Topic) Delete() error {
// TODO: Write tests for this
func (topic *Topic) Update(name string, content string) error {
name = html.EscapeString(html.UnescapeString(name))
name = html.EscapeString(strings.Replace(html.UnescapeString(name), "\n", "", -1))
content = PreparseMessage(html.UnescapeString(content))
parsedContent := ParseMessage(content, topic.ParentID, "forums")
_, err := topicStmts.edit.Exec(name, content, parsedContent, topic.ID)

View File

@ -132,7 +132,7 @@ func routeTopicCreateSubmit(w http.ResponseWriter, r *http.Request, user common.
return common.NoPermissions(w, r, user)
}
topicName := html.EscapeString(r.PostFormValue("topic-name"))
topicName := html.EscapeString(strings.Replace(r.PostFormValue("topic-name"), "\n", "", -1))
content := common.PreparseMessage(r.PostFormValue("topic-content"))
// TODO: Fully parse the post and store it in the parsed column
tid, err := common.Topics.Create(fid, topicName, content, user.ID, user.LastIP)
@ -828,7 +828,7 @@ func routeAccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user
return ferr
}
newUsername := html.EscapeString(r.PostFormValue("account-new-username"))
newUsername := html.EscapeString(strings.Replace(r.PostFormValue("account-new-username"), "\n", "", -1))
err := user.ChangeName(newUsername)
if err != nil {
return common.LocalError("Unable to change the username. Does someone else already have this name?", w, r, user)

View File

@ -1039,12 +1039,14 @@ func routePanelUsersEditSubmit(w http.ResponseWriter, r *http.Request, user comm
return common.LocalError("Only administrators can edit the account of other administrators.", w, r, user)
}
newname := html.EscapeString(r.PostFormValue("user-name"))
newname := html.EscapeString(strings.Replace(r.PostFormValue("user-name"), "\n", "", -1))
if newname == "" {
return common.LocalError("You didn't put in a username.", w, r, user)
}
newemail := html.EscapeString(r.PostFormValue("user-email"))
// TODO: How should activation factor into admin set emails?
// TODO: How should we handle secondary emails? Do we even have secondary emails implemented?
newemail := html.EscapeString(strings.Replace(r.PostFormValue("user-email"), "\n", "", -1))
if newemail == "" {
return common.LocalError("You didn't put in an email address.", w, r, user)
}

View File

@ -749,7 +749,8 @@ func routeLoginSubmit(w http.ResponseWriter, r *http.Request, user common.User)
return common.LocalError("Bad Form", w, r, user)
}
uid, err := common.Auth.Authenticate(html.EscapeString(r.PostFormValue("username")), r.PostFormValue("password"))
username := html.EscapeString(strings.Replace(r.PostFormValue("username"), "\n", "", -1))
uid, err := common.Auth.Authenticate(username, r.PostFormValue("password"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
}
@ -808,11 +809,11 @@ func routeRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.Use
if err != nil {
return common.LocalError("Bad Form", w, r, user)
}
username := html.EscapeString(r.PostFormValue("username"))
username := html.EscapeString(strings.Replace(r.PostFormValue("username"), "\n", "", -1))
if username == "" {
return common.LocalError("You didn't put in a username.", w, r, user)
}
email := html.EscapeString(r.PostFormValue("email"))
email := html.EscapeString(strings.Replace(r.PostFormValue("email"), "\n", "", -1))
if email == "" {
return common.LocalError("You didn't put in an email.", w, r, user)
}
@ -827,6 +828,7 @@ func routeRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.Use
return common.LocalError("You can't use your email as your password.", w, r, user)
}
// ? Move this into Create()? What if we want to programatically set weak passwords for tests?
err = common.WeakPassword(password)
if err != nil {
return common.LocalError(err.Error(), w, r, user)