From 77fccc637a34ba3d7c48f4caf06f0602d8c15827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E8=83=9C?= <244212647@qq.com> Date: Mon, 20 Nov 2023 17:31:45 +0800 Subject: [PATCH 1/2] fix: cherry_markdown error (#908) * fix: first open document, cherryMarkdown not have theme * fix: modify prismjs style and improve image clarity * update cherry-markdown * optimiztion: cherry-markdown * feat: cherry-markdown add auto-save and update icon * fix: the mobile phone displays abnormally and Markdown does not allow conversion --------- Co-authored-by: zhangsheng.93 --- .github/workflows/build.yml | 2 +- conf/lang/en-us.ini | 3 ++- conf/lang/zh-cn.ini | 1 + controllers/BookController.go | 3 +++ static/css/markdown.css | 15 +++++++++++---- utils/html.go | 6 ++++-- 6 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 45202c0c..4e15ce0f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.20.0 - name: Build run: | diff --git a/conf/lang/en-us.ini b/conf/lang/en-us.ini index c6a7b715..40ea2147 100644 --- a/conf/lang/en-us.ini +++ b/conf/lang/en-us.ini @@ -224,6 +224,7 @@ project_label_desc = Allows up to 10 labels, use ";" to separate multiple tags cannot_change_own_status = Cannot change own status cannot_change_super_status = Cannot change super administrator status cannot_change_super_priv = Cannot change super administrator permissions +editors_not_compatible = two editors are not compatible [blog] author = Author @@ -571,4 +572,4 @@ create_time = Create Time creator = Creator doc_amount = Number of Document last_edit = Last Edit -delete_project = Delete Project \ No newline at end of file +delete_project = Delete Project diff --git a/conf/lang/zh-cn.ini b/conf/lang/zh-cn.ini index f08944bf..912e7419 100644 --- a/conf/lang/zh-cn.ini +++ b/conf/lang/zh-cn.ini @@ -224,6 +224,7 @@ project_label_desc = 最多允许添加10个标签,多个标签请用“;” cannot_change_own_status = 不能变更自己的状态 cannot_change_super_status = 不能变更超级管理员的状态 cannot_change_super_priv = 不能变更超级管理员的权限 +editors_not_compatible = 两种编辑器不兼容 [blog] author = 作者 diff --git a/controllers/BookController.go b/controllers/BookController.go index 0a4b2860..56a234c7 100644 --- a/controllers/BookController.go +++ b/controllers/BookController.go @@ -173,6 +173,9 @@ func (c *BookController) SaveBook() { book.CommentStatus = commentStatus book.Publisher = publisher //book.Label = tag + if book.Editor == EditorMarkdown && editor == EditorCherryMarkdown || book.Editor == EditorCherryMarkdown && editor == EditorMarkdown { + c.JsonResult(6006, i18n.Tr(c.Lang, "message.editors_not_compatible")) + } book.Editor = editor if editor == EditorCherryMarkdown { book.Theme = "cherry" diff --git a/static/css/markdown.css b/static/css/markdown.css index f2993192..345b0297 100644 --- a/static/css/markdown.css +++ b/static/css/markdown.css @@ -548,12 +548,13 @@ iframe.cherry-dialog-iframe { margin-right: 50px; } -.markdown-article-body { - margin-right: 200px !important; +@media screen and (min-width: 840px) { + .markdown-article { + margin-right: 200px !important; + } } .markdown-article-head { - margin-right: 200px !important; width: unset !important; padding: unset !important; padding-top: 10px !important; @@ -562,4 +563,10 @@ iframe.cherry-dialog-iframe { .markdown-title { padding: unset !important; width: 100% !important; -} \ No newline at end of file +} + +@media screen and (max-width: 839px) { + .toc { + display: none !important; + } +} diff --git a/utils/html.go b/utils/html.go index 18f6fe3b..dc326287 100644 --- a/utils/html.go +++ b/utils/html.go @@ -34,7 +34,7 @@ func StripTags(s string) string { return src } -//自动提取文章摘要 +// 自动提取文章摘要 func AutoSummary(body string, l int) string { //匹配图片,如果图片语法是在代码块中,这里同样会处理 @@ -60,7 +60,7 @@ func AutoSummary(body string, l int) string { return content } -//安全处理HTML文档,过滤危险标签和属性. +// 安全处理HTML文档,过滤危险标签和属性. func SafetyProcessor(html string) string { //安全过滤,移除危险标签和属性 @@ -117,6 +117,8 @@ func SafetyProcessor(html string) string { if selector := docQuery.Find("div.markdown-article").First(); selector.Size() <= 0 { if selector := docQuery.Find("div.markdown-toc").First(); selector.Size() > 0 { docQuery.Find("div.markdown-toc").NextAll().WrapAllHtml("
") + } else if selector := docQuery.Find("dir.toc").First(); selector.Size() > 0 { + docQuery.Find("dir.toc").NextAll().WrapAllHtml("
") } } From 0dbb5d7967ba767b7853269f455e45473c5e83c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=96=E4=BA=96=E4=BC=8D?= Date: Sat, 9 Dec 2023 14:40:58 +0800 Subject: [PATCH 2/2] escape underline and percent sign for DocumentSearchResult --- models/DocumentSearchResult.go | 54 ++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/models/DocumentSearchResult.go b/models/DocumentSearchResult.go index 5be74055..499bba55 100644 --- a/models/DocumentSearchResult.go +++ b/models/DocumentSearchResult.go @@ -1,12 +1,13 @@ package models import ( - "time" - + "regexp" "strings" + "time" "github.com/beego/beego/v2/client/orm" "github.com/beego/beego/v2/core/logs" + "github.com/beego/beego/v2/server/web" ) type DocumentSearchResult struct { @@ -24,11 +25,22 @@ type DocumentSearchResult struct { SearchType string `json:"search_type"` } +var escape_re = regexp.MustCompile(`(?mi)(\bLIKE\s+\?)`) +var escape_replace = "${1} ESCAPE '\\'" + +func need_escape(keyword string) bool { + dbadapter, _ := web.AppConfig.String("db_adapter") + if strings.EqualFold(dbadapter, "sqlite3") && (strings.Contains(keyword, "\\_") || strings.Contains(keyword, "\\%")) { + return true + } + return false +} + func NewDocumentSearchResult() *DocumentSearchResult { return &DocumentSearchResult{} } -//分页全局搜索. +// 分页全局搜索. func (m *DocumentSearchResult) FindToPager(keyword string, pageIndex, pageSize, memberId int) (searchResult []*DocumentSearchResult, totalCount int, err error) { o := orm.NewOrm() @@ -36,6 +48,14 @@ func (m *DocumentSearchResult) FindToPager(keyword string, pageIndex, pageSize, keyword = "%" + strings.Replace(keyword, " ", "%", -1) + "%" + _need_escape := need_escape(keyword) + escape_sql := func(sql string) string { + if _need_escape { + return escape_re.ReplaceAllString(sql, escape_replace) + } + return sql + } + if memberId <= 0 { sql1 := `SELECT count(doc.document_id) as total_count FROM md_documents AS doc LEFT JOIN md_books as book ON doc.book_id = book.book_id @@ -98,7 +118,7 @@ WHERE book.privately_owned = 0 AND (book.book_name LIKE ? OR book.description LI ORDER BY create_time DESC LIMIT ? OFFSET ?;` - err = o.Raw(sql1, keyword, keyword).QueryRow(&totalCount) + err = o.Raw(escape_sql(sql1), keyword, keyword).QueryRow(&totalCount) if err != nil { logs.Error("查询搜索结果失败 -> ", err) return @@ -109,7 +129,7 @@ LIMIT ? OFFSET ?;` WHERE blog.blog_status = 'public' AND (blog.blog_release LIKE ? OR blog.blog_title LIKE ?);` c := 0 - err = o.Raw(sql3, keyword, keyword).QueryRow(&c) + err = o.Raw(escape_sql(sql3), keyword, keyword).QueryRow(&c) if err != nil { logs.Error("查询搜索结果失败 -> ", err) return @@ -120,7 +140,7 @@ LIMIT ? OFFSET ?;` sql4 := `SELECT count(*) as total_count FROM md_books as book WHERE book.privately_owned = 0 AND (book.book_name LIKE ? OR book.description LIKE ?);` - err = o.Raw(sql4, keyword, keyword).QueryRow(&c) + err = o.Raw(escape_sql(sql4), keyword, keyword).QueryRow(&c) if err != nil { logs.Error("查询搜索结果失败 -> ", err) return @@ -128,7 +148,7 @@ WHERE book.privately_owned = 0 AND (book.book_name LIKE ? OR book.description LI totalCount += c - _, err = o.Raw(sql2, keyword, keyword, keyword, keyword, keyword, keyword, pageSize, offset).QueryRows(&searchResult) + _, err = o.Raw(escape_sql(sql2), keyword, keyword, keyword, keyword, keyword, keyword, pageSize, offset).QueryRows(&searchResult) if err != nil { logs.Error("查询搜索结果失败 -> ", err) return @@ -226,7 +246,7 @@ FROM ( ORDER BY create_time DESC LIMIT ? OFFSET ?;` - err = o.Raw(sql1, memberId, memberId, keyword, keyword).QueryRow(&totalCount) + err = o.Raw(escape_sql(sql1), memberId, memberId, keyword, keyword).QueryRow(&totalCount) if err != nil { return } @@ -237,7 +257,7 @@ LIMIT ? OFFSET ?;` (blog.blog_release LIKE ? OR blog.blog_title LIKE ?);` c := 0 - err = o.Raw(sql3, memberId, keyword, keyword).QueryRow(&c) + err = o.Raw(escape_sql(sql3), memberId, keyword, keyword).QueryRow(&c) if err != nil { logs.Error("查询搜索结果失败 -> ", err) return @@ -254,7 +274,7 @@ LIMIT ? OFFSET ?;` on team.book_id = book.book_id WHERE (book.privately_owned = 0 OR rel1.relationship_id > 0 or team.team_member_id > 0) AND (book.book_name LIKE ? OR book.description LIKE ?);` - err = o.Raw(sql4, memberId, memberId, keyword, keyword).QueryRow(&c) + err = o.Raw(escape_sql(sql4), memberId, memberId, keyword, keyword).QueryRow(&c) if err != nil { logs.Error("查询搜索结果失败 -> ", err) return @@ -262,7 +282,7 @@ WHERE (book.privately_owned = 0 OR rel1.relationship_id > 0 or team.team_member_ totalCount += c - _, err = o.Raw(sql2, memberId, memberId, keyword, keyword, memberId, memberId, keyword, keyword, memberId, keyword, keyword, pageSize, offset).QueryRows(&searchResult) + _, err = o.Raw(escape_sql(sql2), memberId, memberId, keyword, keyword, memberId, memberId, keyword, keyword, memberId, keyword, keyword, pageSize, offset).QueryRows(&searchResult) if err != nil { return } @@ -270,14 +290,22 @@ WHERE (book.privately_owned = 0 OR rel1.relationship_id > 0 or team.team_member_ return } -//项目内搜索. +// 项目内搜索. func (m *DocumentSearchResult) SearchDocument(keyword string, bookId int) (docs []*DocumentSearchResult, err error) { o := orm.NewOrm() sql := "SELECT * FROM md_documents WHERE book_id = ? AND (document_name LIKE ? OR `release` LIKE ?) " keyword = "%" + keyword + "%" - _, err = o.Raw(sql, bookId, keyword, keyword).QueryRows(&docs) + _need_escape := need_escape(keyword) + escape_sql := func(sql string) string { + if _need_escape { + return escape_re.ReplaceAllString(sql, escape_replace) + } + return sql + } + + _, err = o.Raw(escape_sql(sql), bookId, keyword, keyword).QueryRows(&docs) return }