--- lbbs/src/lml.c 2025/06/14 02:59:34 1.7 +++ lbbs/src/lml.c 2025/07/16 05:24:08 1.14 @@ -14,9 +14,9 @@ * * ***************************************************************************/ +#include "common.h" #include "lml.h" #include "log.h" -#include "common.h" #include #include #include @@ -81,7 +81,8 @@ static int lml_tag_quote_filter(const ch { lml_tag_quote_level++; } - return snprintf(tag_output_buf, tag_output_buf_len, lml_tag_quote_color[lml_tag_quote_level % LML_TAG_QUOTE_LEVEL_LOOP]); + return snprintf(tag_output_buf, tag_output_buf_len, "%s", + lml_tag_quote_color[lml_tag_quote_level % LML_TAG_QUOTE_LEVEL_LOOP]); } else if (strcasecmp(tag_name, "/quote") == 0) { @@ -89,7 +90,7 @@ static int lml_tag_quote_filter(const ch { lml_tag_quote_level--; } - return snprintf(tag_output_buf, tag_output_buf_len, + return snprintf(tag_output_buf, tag_output_buf_len, "%s", (lml_tag_quote_level > 0 ? lml_tag_quote_color[lml_tag_quote_level % LML_TAG_QUOTE_LEVEL_LOOP] : "\033[m")); } @@ -116,16 +117,16 @@ const static char *LML_tag_def[][3] = { {"quote", NULL, (const char *)lml_tag_quote_filter}, {"/quote", NULL, (const char *)lml_tag_quote_filter}, {"url", "", ""}, - {"/url", "(链接: %s)", NULL}, + {"/url", "(閾炬帴: %s)", NULL}, {"link", "", ""}, - {"/link", "(链接: %s)", NULL}, + {"/link", "(閾炬帴: %s)", NULL}, {"email", "", ""}, {"/email", "(Email: %s)", NULL}, {"user", "", ""}, - {"/user", "(用户: %s)", NULL}, + {"/user", "(鐢ㄦ埛: %s)", NULL}, {"article", "", ""}, - {"/article", "(文章: %s)", NULL}, - {"image", "(图片: %s)", ""}, + {"/article", "(鏂囩珷: %s)", NULL}, + {"image", "(鍥剧墖: %s)", ""}, {"flash", "(Flash: %s)", ""}, {"bwf", "\033[1;31m****\033[m", ""}, }; @@ -152,6 +153,7 @@ inline static void lml_init(void) int lml_plain(const char *str_in, char *str_out, int buf_len) { + char c; char tag_param_buf[LML_TAG_PARAM_BUF_LEN]; char tag_output_buf[LML_TAG_OUTPUT_BUF_LEN]; int i; @@ -176,11 +178,11 @@ int lml_plain(const char *str_in, char * { lml_tag_quote_level -= fb_quote_level; - tag_output_len = snprintf(tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, + tag_output_len = snprintf(tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, "%s", (lml_tag_quote_level > 0 ? lml_tag_quote_color[lml_tag_quote_level % LML_TAG_QUOTE_LEVEL_LOOP] : "\033[m")); - if (j + tag_output_len >= buf_len - 1) + if (j + tag_output_len >= buf_len) { - log_error("Buffer is not longer enough for output string %d >= %d\n", j + tag_output_len, buf_len - 1); + log_error("Buffer is not longer enough for output string %d >= %d\n", j + tag_output_len, buf_len); str_out[j] = '\0'; return j; } @@ -199,11 +201,11 @@ int lml_plain(const char *str_in, char * { lml_tag_quote_level += fb_quote_level; - tag_output_len = snprintf(tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, + tag_output_len = snprintf(tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, "%s", lml_tag_quote_color[(lml_tag_quote_level) % LML_TAG_QUOTE_LEVEL_LOOP]); - if (j + tag_output_len >= buf_len - 1) + if (j + tag_output_len >= buf_len) { - log_error("Buffer is not longer enough for output string %d >= %d\n", j + tag_output_len, buf_len - 1); + log_error("Buffer is not longer enough for output string %d >= %d\n", j + tag_output_len, buf_len); str_out[j] = '\0'; return j; } @@ -214,6 +216,30 @@ int lml_plain(const char *str_in, char * new_line = 0; } + if (str_in[i] == '\033' && str_in[i + 1] == '[') // Escape sequence -- copy directly + { + for (k = i + 2; str_in[k] != '\0' && str_in[k] != 'm'; k++) + ; + + if (str_in[k] == 'm') // Valid + { + if (j + (k - i + 1) >= buf_len) + { + log_error("Buffer is not longer enough for output string %d >= %d\n", j + (k - i + 1), buf_len); + str_out[j] = '\0'; + return j; + } + memcpy(str_out + j, str_in + i, (size_t)(k - i + 1)); + j += (k - i + 1); + i = k; + continue; + } + else // reach end of string + { + break; + } + } + if (str_in[i] == '\n') { tag_start_pos = -1; // jump out of tag at end of line @@ -270,9 +296,9 @@ int lml_plain(const char *str_in, char * tag_output_len = ((lml_tag_filter_cb)LML_tag_def[k][2])( LML_tag_def[k][0], tag_param_buf, tag_output_buf, LML_TAG_OUTPUT_BUF_LEN); } - if (j + tag_output_len >= buf_len - 1) + if (j + tag_output_len >= buf_len) { - log_error("Buffer is not longer enough for output string %d >= %d\n", j + tag_output_len, buf_len - 1); + log_error("Buffer is not longer enough for output string %d >= %d\n", j + tag_output_len, buf_len); str_out[j] = '\0'; return j; } @@ -291,25 +317,31 @@ int lml_plain(const char *str_in, char * } else if (tag_start_pos == -1) // not in LML tag { - if (str_in[i] < 0 || str_in[i] > 127) // GBK chinese character + if (str_in[i] & 0b10000000) // head of multi-byte character { - if (j + 2 >= buf_len - 1) + if (j + 4 >= buf_len) // Assuming UTF-8 CJK characters use 4 bytes, though most of them actually use 3 bytes { - log_error("Buffer is not longer enough for output string %ld >= %d\n", j + 2, buf_len - 1); + log_error("Buffer is not longer enough for output string %ld >= %d\n", j + 4, buf_len); str_out[j] = '\0'; return j; } - str_out[j++] = str_in[i++]; - if (str_in[i] == '\0') + + c = (str_in[i] & 0b01110000) << 1; + while (c & 0b10000000) { - str_out[j] = '\0'; - return j; + str_out[j++] = str_in[i++]; + if (str_in[i] == '\0') + { + str_out[j] = '\0'; + return j; + } + c = (c & 0b01111111) << 1; } } - if (j + 1 >= buf_len - 1) + if (j + 1 >= buf_len) { - log_error("Buffer is not longer enough for output string %ld >= %d\n", j + 1, buf_len - 1); + log_error("Buffer is not longer enough for output string %ld >= %d\n", j + 1, buf_len); str_out[j] = '\0'; return j; } @@ -324,9 +356,9 @@ int lml_plain(const char *str_in, char * if (lml_tag_quote_level > 0) { tag_output_len = snprintf(tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, "\033[m"); - if (j + tag_output_len >= buf_len - 1) + if (j + tag_output_len >= buf_len) { - log_error("Buffer is not longer enough for output string %d >= %d\n", j + tag_output_len, buf_len - 1); + log_error("Buffer is not longer enough for output string %d >= %d\n", j + tag_output_len, buf_len); str_out[j] = '\0'; return j; }