summaryrefslogtreecommitdiff
path: root/src/domain/search.c
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-06-29 21:43:54 +0900
committertanaka takashi <isazaka@gmail.com>2026-06-30 01:23:51 +0900
commit4bc721c3bf7589b519c5730d093f704ce56e3f09 (patch)
tree38da055ab15fd70f5c92584560ea73486e5ddce0 /src/domain/search.c
parent4c6a831aa2a57e2bcc20aa3fc2f1b7172f5be285 (diff)
refactor: MCP層をmcpc APIベースに刷新
- 独自JSON-RPC処理をmcpcへ置き換え - 各MCPツールを個別ソースへ分離 - 共通コンテキストと登録処理を整理 - mcpc互換修正と統合テストを更新
Diffstat (limited to 'src/domain/search.c')
-rw-r--r--src/domain/search.c53
1 files changed, 47 insertions, 6 deletions
diff --git a/src/domain/search.c b/src/domain/search.c
index a24b667..b0ac440 100644
--- a/src/domain/search.c
+++ b/src/domain/search.c
@@ -4,6 +4,8 @@
#include <stdlib.h>
#include <string.h>
+#include "base/allocator.h"
+
typedef struct gram_bucket
{
uint64_t hash;
@@ -25,9 +27,25 @@ struct tiny_search_index
static bool
decode_codepoints(const char *text, uint32_t **output, size_t *count)
{
- const size_t bytes = strlen(text);
+ size_t bytes;
size_t offset = 0, used = 0;
- uint32_t *points = malloc((bytes + 1) * sizeof(uint32_t));
+ uint32_t *points;
+ if (output == NULL || count == NULL)
+ {
+ return false;
+ }
+ *output = NULL;
+ *count = 0;
+ if (text == NULL)
+ {
+ return false;
+ }
+ bytes = strlen(text);
+ if (!tiny_utf8_valid(text, bytes) || bytes > SIZE_MAX / sizeof(uint32_t) - 1)
+ {
+ return false;
+ }
+ points = malloc((bytes + 1) * sizeof(uint32_t));
if (points == NULL)
{
return false;
@@ -198,6 +216,12 @@ tiny_search_index_add(tiny_search_index_t *index,
size_t message_index)
{
size_t tag;
+ if (index == NULL || message == NULL || message->content == NULL
+ || (message->metadata.tag_count != 0 && message->metadata.tags == NULL)
+ || message_index == SIZE_MAX)
+ {
+ return false;
+ }
if (!index_text(index, message->content, message_index))
{
return false;
@@ -226,8 +250,16 @@ tiny_search_index_candidates(const tiny_search_index_t *index,
size_t point_count = 0, width, offset, used = 0;
bool *seen;
size_t *items;
+ if (output == NULL || count == NULL)
+ {
+ return false;
+ }
*output = NULL;
*count = 0;
+ if (index == NULL || query == NULL || index->message_count > SIZE_MAX / sizeof(*items))
+ {
+ return false;
+ }
if (!decode_codepoints(query, &points, &point_count))
{
return false;
@@ -283,10 +315,20 @@ tiny_search_score(const char *query, const tiny_message_t *message)
size_t query_count = 0, message_count = 0, width, query_offset, message_offset, matches = 0,
total, tag;
double score = 0.0;
- if (!decode_codepoints(query, &query_points, &query_count)
- || !decode_codepoints(message->content, &message_points, &message_count) || query_count == 0)
+ if (query == NULL || message == NULL || message->content == NULL
+ || (message->metadata.tag_count != 0 && message->metadata.tags == NULL))
+ {
+ return 0.0;
+ }
+ if (!decode_codepoints(query, &query_points, &query_count) || query_count == 0)
+ {
+ free(query_points);
+ return 0.0;
+ }
+ if (!decode_codepoints(message->content, &message_points, &message_count))
{
- goto done;
+ free(query_points);
+ return 0.0;
}
width = query_count >= 3 ? 3 : (query_count >= 2 ? 2 : 1);
total = query_count - width + 1;
@@ -343,7 +385,6 @@ tiny_search_score(const char *query, const tiny_message_t *message)
}
}
}
-done:
free(query_points);
free(message_points);
return score;