这似乎是一个相当常见的模式,例如在 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;
}
in 中的行timer_cb
导致 hexchat 将(可能已释放 - 在此示例中肯定已释放,请参阅 中的注释do_ub
)指针与另一个指针进行比较,如果您从此处 (plugin.c#L1089, hexchat_set_context) 开始,您将结束在这里 (hexchat.c#L191, is_session)。要调用此代码,/do_ub
请在 hexchat 中运行。
相关代码:
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吗?