aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/help.c
diff options
context:
space:
mode:
authorRobin Haberkorn <rhaberkorn@fmsbw.de>2026-10-16 00:50:48 +0200
committerRobin Haberkorn <rhaberkorn@fmsbw.de>2026-10-16 00:50:48 +0200
commit8e4af72622e4a9bb3383085fce28c55444a9d8ee (patch)
tree5535ecb62b1a528788fa0383059a7afd51dd8970 /src/help.c
parent8b54d2c31410fcac43c8903007fe0738312834b0 (diff)
always check the result of rb3_insert(), i.e. detect collisions in RB treesHEADmaster-fmsbw-cimaster
This was already done for the goto table, but by first looking up whether a label already exists in the table. Since the insert operation already reports entries with the same key in the tree, we should rather check that. This saves one goto table lookup per label definition, but on the other hand results in excess allocations in case of encountering a label twice. In teco_help_set(), we did not check for collisions at all. Even thouch they are very unlikely, we could encounter them if a topic is defined on exactly the same position as in .SCITECO_TOPIC foo .SCITECO_TOPIC foo In this case, we leaked memory.
Diffstat (limited to 'src/help.c')
-rw-r--r--src/help.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/help.c b/src/help.c
index e7e674c..1e4a766 100644
--- a/src/help.c
+++ b/src/help.c
@@ -225,7 +225,7 @@ teco_help_find(const gchar *topic_name)
* Alternatively, we'd have to keep lists in each teco_help_topic_t.
*/
static gint
-teco_help_casecmp(const teco_help_topic_t *topic, const teco_help_topic_t *data)
+teco_help_topic_casecmp(const teco_help_topic_t *topic, const teco_help_topic_t *data)
{
return teco_string_casecmp(topic->head.key, data->head.key.data, data->head.key.len)
? : strcasecmp(topic->filename, data->filename)
@@ -240,7 +240,13 @@ static inline void
teco_help_set(const gchar *topic_name, const gchar *filename, gsize pos)
{
teco_help_topic_t *topic = teco_help_topic_new(topic_name, filename, pos);
- rb3_insert(&teco_help.tree, &topic->head.head, (rb3_cmp *)teco_help_casecmp, topic);
+ if (G_UNLIKELY(rb3_insert(&teco_help.tree, &topic->head.head,
+ (rb3_cmp *)teco_help_topic_casecmp, topic) != NULL))
+ /*
+ * Should not happen - just keep the old entry.
+ * This will "leak" some memory in the teco_help.chunk, though.
+ */
+ teco_help_topic_free(topic);
}
gboolean