Added numeric mentions. Username mentions will be automatically pre-parsed into numeric mentions in a future commit.

Added #rid for linking to a specific post.

Added a forum_exists function.
Removed the null bytes from the posts
The report system now uses #rid, #tid and numeric mentions instead of raw HTML.
Improved the custom parser to take control characters into account. It also now parses items at the start of the post.
Fixed the padding on the buttons on the profiles.
#tid now takes into account whether the topic it links to exists.
This commit is contained in:
Azareal 2017-03-14 10:57:40 +00:00
parent 3a68e07885
commit ca7c369e9e
14 changed files with 152 additions and 30 deletions

View File

@ -1,4 +1,5 @@
package main
//import "fmt"
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
@ -76,3 +77,11 @@ func delete_forum(fid int) error {
forums[fid].Name = ""
return nil
}
func forum_exists(fid int) bool {
//fmt.Println(fid)
//fmt.Println(fid <= forumCapCount)
//fmt.Println(fid >= 0)
//fmt.Println(forums[fid].Name!="")
return (fid <= forumCapCount) && (fid >= 0) && forums[fid].Name!=""
}

View File

@ -733,7 +733,7 @@ func route_panel_forums_delete(w http.ResponseWriter, r *http.Request){
return
}
if (fid > forumCapCount) || (fid < 0) || forums[fid].Name=="" {
if !forum_exists(fid) {
LocalError("The forum you're trying to delete doesn't exist.",w,r,user)
return
}
@ -764,7 +764,7 @@ func route_panel_forums_delete_submit(w http.ResponseWriter, r *http.Request) {
LocalError("The provided Forum ID is not a valid number.",w,r,user)
return
}
if (fid > forumCapCount) || (fid < 0) || forums[fid].Name=="" {
if !forum_exists(fid) {
LocalError("The forum you're trying to delete doesn't exist.",w,r,user)
return
}
@ -792,7 +792,7 @@ func route_panel_forums_edit(w http.ResponseWriter, r *http.Request) {
LocalError("The provided Forum ID is not a valid number.",w,r,user)
return
}
if (fid > forumCapCount) || (fid < 0) || forums[fid].Name=="" {
if !forum_exists(fid) {
LocalError("The forum you're trying to edit doesn't exist.",w,r,user)
return
}
@ -834,7 +834,7 @@ func route_panel_forums_edit_submit(w http.ResponseWriter, r *http.Request) {
forum_name := r.PostFormValue("forum-name")
forum_preset := strip_invalid_preset(r.PostFormValue("forum-preset"))
forum_active := r.PostFormValue("forum-active")
if (fid > forumCapCount) || (fid < 0) || forums[fid].Name=="" {
if !forum_exists(fid) {
LocalErrorJSQ("The forum you're trying to edit doesn't exist.",w,r,user,is_js)
return
}

110
pages.go
View File

@ -102,8 +102,12 @@ var space_gap []byte = []byte(" ")
var http_prot_b []byte = []byte("http://")
var invalid_url []byte = []byte("<span style='color: red;'>[Invalid URL]</span>")
var invalid_topic []byte = []byte("<span style='color: red;'>[Invalid Topic]</span>")
var invalid_profile []byte = []byte("<span style='color: red;'>[Invalid Profile]</span>")
var url_open []byte = []byte("<a href='")
var url_open2 []byte = []byte("'>")
var bytes_singlequote []byte = []byte("'")
var bytes_greaterthan []byte = []byte(">")
var url_mention []byte = []byte(" class='mention'")
var url_close []byte = []byte("</a>")
var urlpattern string = `(?s)([ {1}])((http|https|ftp|mailto)*)(:{??)\/\/([\.a-zA-Z\/]+)([ {1}])`
var url_reg *regexp.Regexp
@ -163,23 +167,51 @@ func preparse_message(msg string) string {
return shortcode_to_unicode(msg)
}
func parse_message(msg string) string {
//var msg_index int = 0
func parse_message(msg string/*, user User*/) string {
msg = strings.Replace(msg,":)","😀",-1)
msg = strings.Replace(msg,":D","😃",-1)
msg = strings.Replace(msg,":P","😛",-1)
//msg = url_reg.ReplaceAllString(msg,"<a href=\"$2$3//$4\" rel=\"nofollow\">$2$3//$4</a>")
// Search for URLs in the messages...
// Search for URLs, mentions and hashlinks in the messages...
//fmt.Println("Parser Loop!")
//fmt.Println("Message Index:")
//msg_index++
//fmt.Println(msg_index)
var msgbytes = []byte(msg)
outbytes := make([]byte, len(msgbytes))
var outbytes []byte
//fmt.Println("Outbytes Start:")
//fmt.Println(outbytes)
//fmt.Println(string(outbytes))
//fmt.Println("Outbytes Start End:")
msgbytes = append(msgbytes,space_gap...)
//fmt.Println(`"`+string(msgbytes)+`"`)
lastItem := 0
i := 0
for ; len(msgbytes) > (i + 1); i++ {
if i==0 || msgbytes[i] == 10 || (msgbytes[i] == ' ' && msgbytes[i + 1] != ' ') {
i++
//fmt.Println("Index:")
//fmt.Println(i)
//fmt.Println("Index Item:")
//fmt.Println(msgbytes[i])
//if msgbytes[i] == 10 {
// fmt.Println("NEWLINE")
//} else if msgbytes[i] == 32 {
// fmt.Println("SPACE")
//} else {
// fmt.Println(string(msgbytes[i]))
//}
//fmt.Println("End Index")
if (i==0 && (msgbytes[0] > 32)) || ((msgbytes[i] < 33) && (msgbytes[i + 1] > 32)) {
//fmt.Println("IN")
//fmt.Println(msgbytes[i])
//fmt.Println("STEP CONTINUE")
if (i != 0) || msgbytes[i] < 33 {
i++
}
if msgbytes[i]=='#' {
//fmt.Println("IN #")
if bytes.Equal(msgbytes[i+1:i+5],[]byte("tid-")) {
outbytes = append(outbytes,msgbytes[lastItem:i]...)
i += 5
@ -187,8 +219,8 @@ func parse_message(msg string) string {
tid, int_len := coerce_int_bytes(msgbytes[start:])
i += int_len
_, err := topics.CascadeGet(tid)
if err != nil {
topic, err := topics.CascadeGet(tid)
if err != nil || !forum_exists(topic.ParentID) {
outbytes = append(outbytes,invalid_topic...)
lastItem = i
continue
@ -202,10 +234,72 @@ func parse_message(msg string) string {
outbytes = append(outbytes, tid_bit...)
outbytes = append(outbytes, url_close...)
lastItem = i
//fmt.Println(string(msgbytes))
//fmt.Println(msgbytes)
//fmt.Println(msgbytes[lastItem - 1])
//fmt.Println(lastItem - 1)
//fmt.Println(msgbytes[lastItem])
//fmt.Println(lastItem)
} else if bytes.Equal(msgbytes[i+1:i+5],[]byte("rid-")) {
outbytes = append(outbytes,msgbytes[lastItem:i]...)
i += 5
start := i
rid, int_len := coerce_int_bytes(msgbytes[start:])
i += int_len
topic, err := get_topic_by_reply(rid)
if err != nil || !forum_exists(topic.ParentID) {
outbytes = append(outbytes,invalid_topic...)
lastItem = i
continue
}
outbytes = append(outbytes, url_open...)
var url_bit []byte = []byte(build_topic_url(topic.ID))
outbytes = append(outbytes, url_bit...)
outbytes = append(outbytes, url_open2...)
var rid_bit []byte = []byte("#rid-" + strconv.Itoa(rid))
outbytes = append(outbytes, rid_bit...)
outbytes = append(outbytes, url_close...)
lastItem = i
} else {
// TO-DO: Forum Link
}
} else if msgbytes[i]=='@' {
//fmt.Println("IN @")
outbytes = append(outbytes,msgbytes[lastItem:i]...)
i++
start := i
uid, int_len := coerce_int_bytes(msgbytes[start:])
i += int_len
menUser, err := users.CascadeGet(uid)
if err != nil {
outbytes = append(outbytes,invalid_profile...)
lastItem = i
continue
}
outbytes = append(outbytes, url_open...)
var url_bit []byte = []byte(build_profile_url(uid))
outbytes = append(outbytes, url_bit...)
outbytes = append(outbytes, bytes_singlequote...)
outbytes = append(outbytes, url_mention...)
outbytes = append(outbytes, bytes_greaterthan...)
var uid_bit []byte = []byte("@" + menUser.Name)
outbytes = append(outbytes, uid_bit...)
outbytes = append(outbytes, url_close...)
lastItem = i
//fmt.Println(string(msgbytes))
//fmt.Println(msgbytes)
//fmt.Println(msgbytes[lastItem - 1])
//fmt.Println(lastItem - 1)
//fmt.Println(msgbytes[lastItem])
//fmt.Println(lastItem)
} else if msgbytes[i]=='h' || msgbytes[i]=='f' || msgbytes[i]=='g' {
//fmt.Println("IN hfg")
if msgbytes[i + 1]=='t' && msgbytes[i + 2]=='t' && msgbytes[i + 3]=='p' {
if msgbytes[i + 4] == 's' && msgbytes[i + 5] == ':' && msgbytes[i + 6] == '/' && msgbytes[i + 7] == '/' {
// Do nothing
@ -416,7 +510,7 @@ func coerce_int_bytes(data []byte) (res int, length int) {
return 0, 1
}
i := 1
i := 0
for ;len(data) > i; i++ {
if !(data[i] > 47 && data[i] < 58) {
conv, err := strconv.Atoi(string(data[0:i]))

View File

@ -274,7 +274,7 @@ func bbcode_full_parse(data interface{}) interface{} {
i := 0
var start int
var lastTag int
outbytes := make([]byte, len(msgbytes))
var outbytes []byte
//fmt.Println("BBCode Pre:")
//fmt.Println("`"+string(msgbytes)+"`")
//fmt.Println("----")

View File

@ -1024,7 +1024,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r)
return
}
content = content + "<br><br>Original Post: <a href='/topic/" + strconv.Itoa(tid) + "'>" + title + "</a>"
content = content + "\n\nOriginal Post: #rid-" + strconv.Itoa(item_id)
} else if item_type == "user-reply" {
err = db.QueryRow("select uid, content from users_replies where rid = ?", item_id).Scan(&tid, &content)
if err == sql.ErrNoRows {
@ -1043,7 +1043,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r)
return
}
content = content + "<br><br>Original Post: <a href='/user/" + strconv.Itoa(tid) + "'>" + title + "</a>"
content = content + "\n\nOriginal Post: @" + strconv.Itoa(tid)
} else if item_type == "topic" {
err = db.QueryRow("select title, content from topics where tid = ?", item_id).Scan(&title,&content)
if err == sql.ErrNoRows {
@ -1053,7 +1053,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r)
return
}
content = content + "<br><br>Original Post: <a href='/topic/" + strconv.Itoa(item_id) + "'>" + title + "</a>"
content = content + "\n\nOriginal Post: #tid-" + strconv.Itoa(item_id)
} else {
if vhooks["report_preassign"] != nil {
run_vhook_noreturn("report_preassign", &item_id, &item_type)
@ -1084,7 +1084,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
}
title = "Report: " + title
res, err := create_report_stmt.Exec(title,content,content,user.ID,item_type + "_" + strconv.Itoa(item_id))
res, err := create_report_stmt.Exec(title,content,parse_message(content),user.ID,item_type + "_" + strconv.Itoa(item_id))
if err != nil {
InternalError(err,w,r)
return

View File

@ -139,7 +139,7 @@ var topic_53 []byte = []byte(`), url(/static/white-dot.jpg);background-position:
var topic_54 []byte = []byte(`-1`)
var topic_55 []byte = []byte(`0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;`)
var topic_56 []byte = []byte(`">
<p class="editable_block user_content" style="margin: 0;padding: 0;">`)
<p class="editable_block user_content" style="margin:0;padding:0;">`)
var topic_57 []byte = []byte(`</p>
<a href="/user/`)
var topic_58 []byte = []byte(`" class="username real_username">`)
@ -369,12 +369,12 @@ var profile_21 []byte = []byte(`</span>
<br /><br />
<a href="/user/`)
var profile_22 []byte = []byte(`" class="username">`)
var profile_23 []byte = []byte(`</a>
var profile_23 []byte = []byte(`</a>&nbsp;
`)
var profile_24 []byte = []byte(`<a href="/profile/reply/edit/submit/`)
var profile_25 []byte = []byte(`"><button class="username edit_item">Edit</button></a>
var profile_25 []byte = []byte(`" class="mod_button" title="Edit Item"><button class="username edit_item">Edit</button></a>&nbsp;
<a href="/profile/reply/delete/submit/`)
var profile_26 []byte = []byte(`"><button class="username delete_item">Delete</button></a>`)
var profile_26 []byte = []byte(`" class="mod_button" title="Delete Item"><button class="username delete_item">Delete</button></a>&nbsp;`)
var profile_27 []byte = []byte(`
<a href="/report/submit/`)
var profile_28 []byte = []byte(`?session=`)

View File

@ -19,11 +19,11 @@
<div class="rowitem passive deletable_block editable_parent simple" style="{{if .Avatar}}background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Css}}{{end}}">
<span class="editable_block user_content simple">{{.ContentHtml}}</span>
<br /><br />
<a href="/user/{{.CreatedBy}}" class="username">{{.CreatedByName}}</a>
{{if $.CurrentUser.Is_Mod}}<a href="/profile/reply/edit/submit/{{.ID}}"><button class="username edit_item">Edit</button></a>
<a href="/profile/reply/delete/submit/{{.ID}}"><button class="username delete_item">Delete</button></a>{{end}}
<a href="/user/{{.CreatedBy}}" class="username">{{.CreatedByName}}</a>&nbsp;
{{if $.CurrentUser.Is_Mod}}<a href="/profile/reply/edit/submit/{{.ID}}" class="mod_button" title="Edit Item"><button class="username edit_item">Edit</button></a>&nbsp;
<a href="/profile/reply/delete/submit/{{.ID}}" class="mod_button" title="Delete Item"><button class="username delete_item">Delete</button></a>&nbsp;{{end}}
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=user-reply"><button class="username report_item">Report</button></a>
{{ if .Tag }}<a class="username hide_on_mobile" style="float: right;">{{.Tag}}</a>{{end}}
{{if .Tag}}<a class="username hide_on_mobile" style="float: right;">{{.Tag}}</a>{{end}}
</div>
{{end}}</div>
<div class="colblock_right" style="border-top: none;">

View File

@ -34,7 +34,7 @@
</div><br />
<div class="rowblock post_container" style="overflow: hidden;">{{range .ItemList}}
<div class="rowitem passive deletable_block editable_parent post_item" style="{{if .Avatar}}background-image:url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;{{.Css}}{{end}}">
<p class="editable_block user_content" style="margin: 0;padding: 0;">{{.ContentHtml}}</p>
<p class="editable_block user_content" style="margin:0;padding:0;">{{.ContentHtml}}</p>
<a href="/user/{{.CreatedBy}}" class="username real_username">{{.CreatedByName}}</a>&nbsp;
{{if $.CurrentUser.Perms.LikeItem}}<a href="/reply/like/submit/{{.ID}}" class="mod_button" title="Love it" style="color:#202020;"><button class="username" style="{{if .Liked}}background-color:/*#eaffea*/#D6FFD6;{{end}}">😀</button></a>&nbsp;{{end}}
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="mod_button" title="Edit Reply"><button class="username edit_item">🖊️</button></a>&nbsp;{{end}}

View File

@ -459,6 +459,10 @@ button .big { padding: 6px; }*/
background: rgb(250,250,250);
}
.mention {
font-weight: bold;
}
.threadHidden { background: orange; }
.threadDeleted { background: rgba(255,0,0,0.5); }
@ -555,7 +559,7 @@ blockquote p
}
/* From Tempra Conflux */
.user_content {
.user_content:not(.simple) {
padding: 5px;
margin-top: 3px;
margin-bottom: 0;
@ -594,7 +598,6 @@ blockquote p
float: right;
border-left: solid 1px #eaeaea;
}
.post_item:not(.simple) {
background-color: #eaeaea;
}

View File

@ -449,6 +449,10 @@ button .big { padding: 6px; }*/
background: rgb(250,250,250);
}
.mention {
font-weight: bold;
}
.threadHidden { background: orange; }
.threadDeleted { background: rgba(255,0,0,0.5); }

View File

@ -366,6 +366,10 @@ button.username
border-width: 1px;
}
.mention {
font-weight: bold;
}
.tag-mini
{
text-transform: none;

View File

@ -361,6 +361,10 @@ button.username
margin-bottom: 8px;
}
.mention {
font-weight: bold;
}
.level {
float: right;
color: #505050;

View File

@ -357,6 +357,10 @@ button.username
margin-bottom: 8px;
}
.mention {
font-weight: bold;
}
.level {
float: right;
color: #505050;

View File

@ -321,7 +321,7 @@ func SendValidationEmail(username string, email string, token string) bool {
}
func SimpleForumSessionCheck(w http.ResponseWriter, r *http.Request, fid int) (user User, success bool) {
if (fid > forumCapCount) || (fid < 0) || forums[fid].Name=="" {
if !forum_exists(fid) {
PreError("The target forum doesn't exist.",w,r)
return user, false
}
@ -343,7 +343,7 @@ func SimpleForumSessionCheck(w http.ResponseWriter, r *http.Request, fid int) (u
}
func ForumSessionCheck(w http.ResponseWriter, r *http.Request, fid int) (user User, noticeList []string, success bool) {
if (fid > forumCapCount) || (fid < 0) || forums[fid].Name=="" {
if !forum_exists(fid) {
NotFound(w,r)
return user, noticeList, false
}