--- lbbs/src/article_post.c 2025/11/05 03:17:12 1.40 +++ lbbs/src/article_post.c 2025/11/11 00:28:05 1.43 @@ -6,9 +6,14 @@ * Copyright (C) 2004-2025 Leaflet */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "article_cache.h" #include "article_post.h" #include "bbs.h" +#include "bwf.h" #include "database.h" #include "editor.h" #include "io.h" @@ -24,7 +29,7 @@ enum _article_post_constant_t { TITLE_INPUT_MAX_LEN = 72, - ARTICLE_QUOTE_MAX_LINES = 20, + ARTICLE_QUOTE_DEFAULT_LINES = 20, MODIFY_DT_MAX_LEN = 50, }; @@ -82,7 +87,7 @@ int article_post(const SECTION_LIST *p_s { clearscr(); moveto(21, 1); - prints("发表文章于 %s[%s] 讨论区,类型: %s,回复通知:%s", + prints("发表文章于 %s[%s] 讨论区,类型: %s,回复通知: %s", p_section->stitle, p_section->sname, (p_article_new->transship ? "转载" : "原创"), (reply_note ? "开启" : "关闭")); @@ -103,7 +108,7 @@ int article_post(const SECTION_LIST *p_s ch = 0; } - for (; !SYS_server_exit; ch = igetch_t(BBS_max_user_idle_time)) + while (!SYS_server_exit) { switch (toupper(ch)) { @@ -122,6 +127,15 @@ int article_post(const SECTION_LIST *p_s len = q - p; if (*p != '\0') { + if ((ret = check_badwords(p, '*')) < 0) + { + log_error("check_badwords(title) error\n"); + } + else if (ret > 0) + { + memcpy(title_input, p, (size_t)len + 1); + continue; + } memcpy(p_article_new->title, p, (size_t)len + 1); memcpy(title_input, p_article_new->title, (size_t)len + 1); } @@ -146,6 +160,7 @@ int article_post(const SECTION_LIST *p_s sign_id = ch - '0'; break; default: // Invalid selection + ch = igetch_t(BBS_max_user_idle_time); continue; } @@ -221,6 +236,13 @@ int article_post(const SECTION_LIST *p_s goto cleanup; } + if (check_badwords(content, '*') < 0) + { + log_error("check_badwords(content) error\n"); + ret = -1; + goto cleanup; + } + db = db_open(); if (db == NULL) { @@ -567,6 +589,13 @@ int article_modify(const SECTION_LIST *p goto cleanup; } + if (check_badwords(content, '*') < 0) + { + log_error("check_badwords(content) error\n"); + ret = -1; + goto cleanup; + } + time(&now); localtime_r(&now, &tm_modify_dt); strftime(str_modify_dt, sizeof(str_modify_dt), "%Y-%m-%d %H:%M:%S (UTC %z)", &tm_modify_dt); @@ -711,7 +740,7 @@ int article_reply(const SECTION_LIST *p_ MYSQL *db = NULL; MYSQL_RES *rs = NULL; MYSQL_ROW row; - long line_offsets[ARTICLE_QUOTE_MAX_LINES + 1]; + long line_offsets[MAX_EDITOR_DATA_LINES + 1]; char sql[SQL_BUFFER_LEN]; char *sql_content = NULL; EDITOR_DATA *p_editor_data = NULL; @@ -724,6 +753,7 @@ int article_reply(const SECTION_LIST *p_ char nickname_f[BBS_nickname_max_len * 2 + 1]; int sign_id = 0; int reply_note = 0; + int full_quote = 0; long len; int ch; char *p, *q; @@ -848,44 +878,6 @@ int article_reply(const SECTION_LIST *p_ // Remove control sequence len = str_filter(content_f, 0); - - len = snprintf(content, ARTICLE_CONTENT_MAX_LEN, - "\n\n【 在 %s (%s) 的大作中提到: 】\n", - p_article->username, p_article->nickname); - - quote_content_lines = split_data_lines(content_f, MAX_EDITOR_DATA_LINE_LENGTH - 2, line_offsets, ARTICLE_QUOTE_MAX_LINES + 1, 0, NULL); - for (i = 0; i < quote_content_lines; i++) - { - memcpy(content + len, ": ", 2); // quote line prefix - len += 2; - memcpy(content + len, content_f + line_offsets[i], (size_t)(line_offsets[i + 1] - line_offsets[i])); - len += (line_offsets[i + 1] - line_offsets[i]); - if (content[len - 1] != '\n') // Appennd \n if not exist - { - content[len] = '\n'; - len++; - } - } - if (content[len - 1] != '\n') // Appennd \n if not exist - { - content[len] = '\n'; - len++; - } - content[len] = '\0'; - - free(content_f); - content_f = NULL; - - p_editor_data = editor_data_load(content); - if (p_editor_data == NULL) - { - log_error("editor_data_load(aid=%d, cid=%d) error\n", p_article->aid, atoi(row[0])); - ret = -1; - goto cleanup; - } - - free(content); - content = NULL; } mysql_free_result(rs); rs = NULL; @@ -898,7 +890,10 @@ int article_reply(const SECTION_LIST *p_ { clearscr(); moveto(21, 1); - prints("回复文章于 %s[%s] 讨论区,回复通知:%s", p_section->stitle, p_section->sname, (reply_note ? "开启" : "关闭")); + prints("回复文章于 %s[%s] 讨论区, 回复通知: %s, 引用模式: %s", + p_section->stitle, p_section->sname, + (reply_note ? "开启" : "关闭"), + (full_quote ? "完整" : "精简")); moveto(22, 1); prints("标题: %s", (p_article_new->title[0] == '\0' ? "[无]" : p_article_new->title)); moveto(23, 1); @@ -909,13 +904,13 @@ int article_reply(const SECTION_LIST *p_ prints(" 按0~3选签名档(0表示不使用)"); moveto(24, 1); - prints("T改标题, C取消, N%s, Enter继续: ", - (reply_note ? "关闭回复通知" : "开启回复通知")); + prints("T改标题, C取消, N%s, Q%s, Enter继续: ", + (reply_note ? "关闭回复通知" : "开启回复通知"), (full_quote ? "精简引用" : "完整引用")); iflush(); ch = 0; } - for (; !SYS_server_exit; ch = igetch_t(BBS_max_user_idle_time)) + while (!SYS_server_exit) { switch (toupper(ch)) { @@ -934,6 +929,15 @@ int article_reply(const SECTION_LIST *p_ len = q - p; if (*p != '\0') { + if ((ret = check_badwords(p, '*')) < 0) + { + log_error("check_badwords(title) error\n"); + } + else if (ret > 0) + { + memcpy(title_input, p, (size_t)len + 1); + continue; + } memcpy(p_article_new->title, p, (size_t)len + 1); memcpy(title_input, p_article_new->title, (size_t)len + 1); } @@ -948,6 +952,9 @@ int article_reply(const SECTION_LIST *p_ case 'N': reply_note = (reply_note ? 0 : 1); break; + case 'Q': + full_quote = (full_quote ? 0 : 1); + break; case '0': case '1': case '2': @@ -955,6 +962,7 @@ int article_reply(const SECTION_LIST *p_ sign_id = ch - '0'; break; default: // Invalid selection + ch = igetch_t(BBS_max_user_idle_time); continue; } @@ -966,6 +974,47 @@ int article_reply(const SECTION_LIST *p_ continue; } + len = snprintf(content, ARTICLE_CONTENT_MAX_LEN, + "\n\n【 在 %s (%s) 的大作中提到: 】\n", + p_article->username, p_article->nickname); + + quote_content_lines = split_data_lines(content_f, + MAX_EDITOR_DATA_LINE_LENGTH - 2, line_offsets, + (full_quote ? MAX_EDITOR_DATA_LINES : ARTICLE_QUOTE_DEFAULT_LINES) + 1, + 0, NULL); + for (i = 0; i < quote_content_lines; i++) + { + memcpy(content + len, ": ", 2); // quote line prefix + len += 2; + memcpy(content + len, content_f + line_offsets[i], (size_t)(line_offsets[i + 1] - line_offsets[i])); + len += (line_offsets[i + 1] - line_offsets[i]); + if (content[len - 1] != '\n') // Appennd \n if not exist + { + content[len] = '\n'; + len++; + } + } + if (content[len - 1] != '\n') // Appennd \n if not exist + { + content[len] = '\n'; + len++; + } + content[len] = '\0'; + + free(content_f); + content_f = NULL; + + p_editor_data = editor_data_load(content); + if (p_editor_data == NULL) + { + log_error("editor_data_load(aid=%d, cid=%d) error\n", p_article->aid, atoi(row[0])); + ret = -1; + goto cleanup; + } + + free(content); + content = NULL; + for (ch = 'E'; !SYS_server_exit && toupper(ch) == 'E';) { editor_display(p_editor_data); @@ -1029,6 +1078,13 @@ int article_reply(const SECTION_LIST *p_ ret = -1; goto cleanup; } + + if (check_badwords(content, '*') < 0) + { + log_error("check_badwords(content) error\n"); + ret = -1; + goto cleanup; + } db = db_open(); if (db == NULL)