这似乎是一种相当常见的模式,例如在 hexchat 中(可能无法编译,另请参阅插件文档。另请注意hexchat_plugin_get_info
一直没有被使用,所以为了简单起见我省略了它):
static hexchat_plugin *ph;
static int timer_cb(void *userdata) {
if (hexchat_set_context(ph, userdata)) { /* <-- is this line UB? */
/* omitted */
}
return 0;
}
static int do_ub(char *word[], char *word_eol[], void *userdata) {
void *context = hexchat_get_context(ph);
hexchat_hook_timer(ph, 1000, timer_cb, context);
hexchat_command(ph, "close"); /* free the context - in practice this would be done by another plugin or by the user, not like this, but for the purposes of this example this simulates the user closing the context. */
return HEXCHAT_EAT_ALL;
}
int hexchat_plugin_init(hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg) {
*plugin_name = "do_ub";
*plugin_desc = "does ub when you /do_ub";
*plugin_version = "1.0.0";
ph = plugin_handle;
/* etc */
hexchat_hook_command(ph, "do_ub", 0, do_ub, "does UB", NULL);
return 1;
}
该行在timer_cb
导致 hexchat 比较 (在本例中可能已释放 - 绝对已释放,请参阅中的评论do_ub
) 与另一个指针的指针,如果您遵循 from这里(plugin.c#L1089,hexchat_set_context)你最终会在这里(hexchat.c#L191,is_session)。要调用此代码,请运行/do_ub
在十六进制聊天中。
相关代码:
int
hexchat_set_context (hexchat_plugin *ph, hexchat_context *context)
{
if (is_session (context))
{
ph->context = context;
return 1;
}
return 0;
}
int
is_session (session * sess)
{
return g_slist_find (sess_list, sess) ? 1 : 0;
}
这是UB的事情吗?