--- lbbs/src/article_favor.c 2025/10/15 02:25:13 1.2 +++ lbbs/src/article_favor.c 2025/11/04 14:58:56 1.8 @@ -1,18 +1,10 @@ -/*************************************************************************** - article_favor.c - description - ------------------- - Copyright : (C) 2004-2025 by Leaflet - Email : leaflet@leafok.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 3 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * article_favor + * - data model and basic operations of user favorite articles + * + * Copyright (C) 2004-2025 Leaflet + */ #include "article_favor.h" #include "common.h" @@ -20,6 +12,7 @@ #include "log.h" #include #include +#include ARTICLE_FAVOR BBS_article_favor; @@ -147,9 +140,9 @@ int article_favor_save_inc(const ARTICLE "DELETE FROM article_favorite WHERE UID = %d AND AID IN (", p_favor->uid); - for (i = 0, j = 0; i < p_favor->aid_base_cnt && j < p_favor->aid_inc_cnt;) + for (i = 0, j = 0; j < p_favor->aid_inc_cnt;) { - if (p_favor->aid_base[i] == p_favor->aid_inc[j]) // XOR - delete record + if (i < p_favor->aid_base_cnt && p_favor->aid_base[i] == p_favor->aid_inc[j]) // XOR - delete record { snprintf(tuple_tmp, sizeof(tuple_tmp), "%d, ", p_favor->aid_inc[j]); strncat(sql_del, tuple_tmp, sizeof(sql_del) - 1 - strnlen(sql_del, sizeof(sql_del))); @@ -158,11 +151,11 @@ int article_favor_save_inc(const ARTICLE i++; j++; } - else if (p_favor->aid_base[i] < p_favor->aid_inc[j]) // skip existing record + else if (i < p_favor->aid_base_cnt && p_favor->aid_base[i] < p_favor->aid_inc[j]) // skip existing record { i++; } - else // if (p_favor->aid_base[i] > p_favor->aid_inc[j]) + else // if (i >= p_favor->aid_base_cnt || p_favor->aid_base[i] > p_favor->aid_inc[j]) { snprintf(tuple_tmp, sizeof(tuple_tmp), "(%d, %d), ", @@ -227,6 +220,7 @@ int article_favor_merge_inc(ARTICLE_FAVO { int32_t aid_new[MAX_FAVOR_AID_BASE_CNT]; int i, j, k; + int len; if (p_favor == NULL) { @@ -256,18 +250,26 @@ int article_favor_merge_inc(ARTICLE_FAVO } } - while (i < p_favor->aid_base_cnt && k < MAX_FAVOR_AID_BASE_CNT) + len = MIN(p_favor->aid_base_cnt - i, MAX_FAVOR_AID_BASE_CNT - k); + if (len > 0) { - aid_new[k++] = p_favor->aid_base[i++]; + memcpy(aid_new + k, p_favor->aid_base + i, + sizeof(int32_t) * (size_t)len); + i += len; + k += len; } if (i < p_favor->aid_base_cnt) { log_error("Too many base aids, %d will be discarded\n", p_favor->aid_base_cnt - i); } - while (j < p_favor->aid_inc_cnt && k < MAX_FAVOR_AID_BASE_CNT) + len = MIN(p_favor->aid_inc_cnt - j, MAX_FAVOR_AID_BASE_CNT - k); + if (len > 0) { - aid_new[k++] = p_favor->aid_inc[j++]; + memcpy(aid_new + k, p_favor->aid_inc + j, + sizeof(int32_t) * (size_t)len); + j += len; + k += len; } if (j < p_favor->aid_inc_cnt) { @@ -311,7 +313,7 @@ int article_favor_check(int32_t aid, con mid = (left + right) / 2; if (aid < (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid])) { - right = mid; + right = mid - 1; } else if (aid > (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid])) { @@ -362,7 +364,7 @@ int article_favor_set(int32_t aid, ARTIC mid = (left + right) / 2; if (aid < (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid])) { - right = mid; + right = mid - 1; } else if (aid > (i == 0 ? p_favor->aid_base[mid] : p_favor->aid_inc[mid])) { @@ -388,9 +390,11 @@ int article_favor_set(int32_t aid, ARTIC if (aid == p_favor->aid_inc[left] && p_favor->aid_inc_cnt > 0) // Unset { - for (i = left; i < p_favor->aid_inc_cnt - 1; i++) + if (p_favor->aid_inc_cnt > left + 1) { - p_favor->aid_inc[i] = p_favor->aid_inc[i + 1]; + memmove(p_favor->aid_inc + left, + p_favor->aid_inc + left + 1, + sizeof(int32_t) * (size_t)(p_favor->aid_inc_cnt - left - 1)); } (p_favor->aid_inc_cnt)--; @@ -424,9 +428,11 @@ int article_favor_set(int32_t aid, ARTIC right = left + 1; } - for (i = p_favor->aid_inc_cnt - 1; i >= right; i--) + if (p_favor->aid_inc_cnt > right) { - p_favor->aid_inc[i + 1] = p_favor->aid_inc[i]; + memmove(p_favor->aid_inc + right + 1, + p_favor->aid_inc + right, + sizeof(int32_t) * (size_t)(p_favor->aid_inc_cnt - right)); } p_favor->aid_inc[right] = aid; @@ -494,19 +500,9 @@ int query_favor_articles(ARTICLE_FAVOR * return -3; } - // acquire lock of section - if (section_list_rd_lock(p_section) < 0) - { - log_error("section_list_rd_lock(sid = %d) error\n", p_section->sid); - return -4; - } - - memcpy(p_snames[i], p_section->sname, sizeof(p_snames[i])); - - // release lock of section - if (section_list_rd_unlock(p_section) < 0) + if (get_section_info(p_section, p_snames[i], NULL, NULL) < 0) { - log_error("section_list_rd_unlock(sid = %d) error\n", p_section->sid); + log_error("get_section_info(sid=%d) error\n", p_section->sid); return -4; } }