Added limited support for HTML in posts.
Newlines are now stripped from usernames, topic titles, and emails.
This commit is contained in:
parent
0fcc1bc04d
commit
1639d81618
|
@ -4,6 +4,7 @@ import (
|
||||||
//"fmt"
|
//"fmt"
|
||||||
"bytes"
|
"bytes"
|
||||||
"html"
|
"html"
|
||||||
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -166,28 +167,74 @@ func shortcodeToUnicode(msg string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write tests for this
|
// TODO: Write tests for this
|
||||||
|
// TODO: Preparse Markdown and normalize it into HTML?
|
||||||
func PreparseMessage(msg string) string {
|
func PreparseMessage(msg string) string {
|
||||||
msg = strings.Replace(msg, "<p><br>", "\n\n", -1)
|
msg = strings.Replace(msg, "<p><br>", "\n\n", -1)
|
||||||
msg = strings.Replace(msg, "<p>", "\n\n", -1)
|
msg = strings.Replace(msg, "<p>", "\n\n", -1)
|
||||||
msg = strings.Replace(msg, "</p>", "", -1)
|
msg = strings.Replace(msg, "</p>", "", -1)
|
||||||
msg = strings.Replace(msg, "<br>", "\n\n", -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 {
|
if Sshooks["preparse_preassign"] != nil {
|
||||||
msg = RunSshook("preparse_preassign", msg)
|
msg = RunSshook("preparse_preassign", msg)
|
||||||
}
|
}
|
||||||
msg = html.EscapeString(msg)
|
msg = html.EscapeString(msg)
|
||||||
/*var runes = []rune(msg)
|
|
||||||
|
var runes = []rune(msg)
|
||||||
msg = ""
|
msg = ""
|
||||||
//var inBold = false
|
var inBold = false
|
||||||
//var unclosedBolds = 0
|
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++ {
|
for i := 0; i < len(runes); i++ {
|
||||||
char := runes[i]
|
char := runes[i]
|
||||||
if char == '&' && peek(i, 1, runes) == 'l' && peek(i, 2, runes) == 't' && peek(i, 2, runes) == ';' {
|
log.Print("string(char): ", string(char))
|
||||||
i += 2
|
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>", runes) {
|
||||||
|
log.Print("in inItalic")
|
||||||
|
i += 5
|
||||||
|
inItalic = false
|
||||||
|
msg += "</em>"
|
||||||
|
} else if inBold && char == 's' && peekMatch(i, "trong>", runes) {
|
||||||
|
log.Print("in inBold")
|
||||||
|
i += 9
|
||||||
|
inBold = false
|
||||||
|
msg += "</strong>"
|
||||||
|
}
|
||||||
|
} else if !inItalic && char == 'e' && peekMatch(i, "m>", runes) {
|
||||||
|
log.Print("in !inItalic")
|
||||||
|
i += 5
|
||||||
|
inItalic = true
|
||||||
|
msg += "<em>"
|
||||||
|
} else if !inBold && char == 's' && peekMatch(i, "trong>", runes) {
|
||||||
|
log.Print("in !inBold")
|
||||||
|
i += 9
|
||||||
|
inBold = true
|
||||||
|
msg += "<strong>"
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
msg += string(char)
|
msg += string(char)
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
if inItalic {
|
||||||
|
msg += "</em>"
|
||||||
|
}
|
||||||
|
if inBold {
|
||||||
|
msg += "</strong>"
|
||||||
|
}
|
||||||
|
|
||||||
return shortcodeToUnicode(msg)
|
return shortcodeToUnicode(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +247,19 @@ func peek(cur int, skip int, runes []rune) rune {
|
||||||
return 0 // null byte
|
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: Write a test for this
|
||||||
// TODO: We need a lot more hooks here. E.g. To add custom media types and handlers.
|
// 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 {
|
func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/) string {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"html"
|
"html"
|
||||||
"html/template"
|
"html/template"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"../query_gen/lib"
|
"../query_gen/lib"
|
||||||
|
@ -238,7 +239,7 @@ func (topic *Topic) Delete() error {
|
||||||
|
|
||||||
// TODO: Write tests for this
|
// TODO: Write tests for this
|
||||||
func (topic *Topic) Update(name string, content string) error {
|
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))
|
content = PreparseMessage(html.UnescapeString(content))
|
||||||
parsedContent := ParseMessage(content, topic.ParentID, "forums")
|
parsedContent := ParseMessage(content, topic.ParentID, "forums")
|
||||||
_, err := topicStmts.edit.Exec(name, content, parsedContent, topic.ID)
|
_, err := topicStmts.edit.Exec(name, content, parsedContent, topic.ID)
|
||||||
|
|
|
@ -132,7 +132,7 @@ func routeTopicCreateSubmit(w http.ResponseWriter, r *http.Request, user common.
|
||||||
return common.NoPermissions(w, r, user)
|
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"))
|
content := common.PreparseMessage(r.PostFormValue("topic-content"))
|
||||||
// TODO: Fully parse the post and store it in the parsed column
|
// TODO: Fully parse the post and store it in the parsed column
|
||||||
tid, err := common.Topics.Create(fid, topicName, content, user.ID, user.LastIP)
|
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
|
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)
|
err := user.ChangeName(newUsername)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("Unable to change the username. Does someone else already have this name?", w, r, user)
|
return common.LocalError("Unable to change the username. Does someone else already have this name?", w, r, user)
|
||||||
|
|
|
@ -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)
|
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 == "" {
|
if newname == "" {
|
||||||
return common.LocalError("You didn't put in a username.", w, r, user)
|
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 == "" {
|
if newemail == "" {
|
||||||
return common.LocalError("You didn't put in an email address.", w, r, user)
|
return common.LocalError("You didn't put in an email address.", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
|
@ -749,7 +749,8 @@ func routeLoginSubmit(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
return common.LocalError("Bad Form", w, r, 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 {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
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 {
|
if err != nil {
|
||||||
return common.LocalError("Bad Form", w, r, user)
|
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 == "" {
|
if username == "" {
|
||||||
return common.LocalError("You didn't put in a username.", w, r, user)
|
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 == "" {
|
if email == "" {
|
||||||
return common.LocalError("You didn't put in an email.", w, r, user)
|
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)
|
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)
|
err = common.WeakPassword(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return common.LocalError(err.Error(), w, r, user)
|
||||||
|
|
Loading…
Reference in New Issue