зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1444571 - Prevent IIIM module from being unloaded with grabbing GtkIMContextIIIM class with static variable r=karlt
IIIMF is really old IME framework. In these days, it's not used as default IM module of any major distributions. However, ATOK X which is old proprietary IME requires IIIMF and it's still used by some Japanese IME users. Therefore, we need to take back the hack to prevent crash caused by IIIMF. We did increment refcount of GtkIMContextIIIM class to prevent IIIM module from being unloaded. However, it was not ported when we changed default toolkit from GTK2 to GTK3. So, this is doing the porting. Unfortunately, the instance of GtkIMContextIIIM is wrapped by opacity struct. So, it's not safe to access the pointer with declaring a mimic struct. Therefore, we should directly get GType from the name with calling g_type_from_name("GtkIMContextIIIM") instead of using G_TYPE_FROM_INSTANCE() and g_type_name(). MozReview-Commit-ID: GCZaSUtPiS9 --HG-- extra : rebase_source : 3b959023bf47fa26393fc04e722c9da79a50991d
This commit is contained in:
Родитель
e3b03845cc
Коммит
7744988cce
|
@ -584,40 +584,39 @@ IMContextWrapper::OnDestroyWindow(nsWindow* aWindow)
|
||||||
this));
|
this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Work around gtk bug http://bugzilla.gnome.org/show_bug.cgi?id=483223:
|
|
||||||
// (and the similar issue of GTK+ IIIM)
|
|
||||||
// The GTK+ XIM and IIIM modules register handlers for the "closed" signal
|
|
||||||
// on the display, but:
|
|
||||||
// * The signal handlers are not disconnected when the module is unloaded.
|
|
||||||
//
|
|
||||||
// The GTK+ XIM module has another problem:
|
|
||||||
// * When the signal handler is run (with the module loaded) it tries
|
|
||||||
// XFree (and fails) on a pointer that did not come from Xmalloc.
|
|
||||||
//
|
|
||||||
// To prevent these modules from being unloaded, use static variables to
|
|
||||||
// hold ref of GtkIMContext class.
|
|
||||||
// For GTK+ XIM module, to prevent the signal handler from being run,
|
|
||||||
// find the signal handlers and remove them.
|
|
||||||
//
|
|
||||||
// GtkIMContextXIMs share XOpenIM connections and display closed signal
|
|
||||||
// handlers (where possible).
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IMContextWrapper::PrepareToDestroyContext(GtkIMContext* aContext)
|
IMContextWrapper::PrepareToDestroyContext(GtkIMContext* aContext)
|
||||||
{
|
{
|
||||||
GtkIMContext *slave = nullptr; //TODO GTK3
|
if (mIMContextID == IMContextID::eIIIMF) {
|
||||||
if (!slave) {
|
// IIIM module registers handlers for the "closed" signal on the
|
||||||
return;
|
// display, but the signal handler is not disconnected when the module
|
||||||
}
|
// is unloaded. To prevent the module from being unloaded, use static
|
||||||
|
// variable to hold reference of slave context class declared by IIIM.
|
||||||
GType slaveType = G_TYPE_FROM_INSTANCE(slave);
|
// Note that this does not grab any instance, it grabs the "class".
|
||||||
const gchar *im_type_name = g_type_name(slaveType);
|
static gpointer sGtkIIIMContextClass = nullptr;
|
||||||
if (strcmp(im_type_name, "GtkIMContextIIIM") == 0) {
|
if (!sGtkIIIMContextClass) {
|
||||||
// Add a reference to prevent the IIIM module from being unloaded
|
// We retrieved slave context class with g_type_name() and actual
|
||||||
static gpointer gtk_iiim_context_class =
|
// slave context instance when our widget was GTK2. That must be
|
||||||
g_type_class_ref(slaveType);
|
// _GtkIMContext::priv::slave in GTK3. However, _GtkIMContext::priv
|
||||||
// Mute unused variable warning:
|
// is an opacity struct named _GtkIMMulticontextPrivate, i.e., it's
|
||||||
(void)gtk_iiim_context_class;
|
// not exposed by GTK3. Therefore, we cannot access the instance
|
||||||
|
// safely. So, we need to retrieve the slave context class with
|
||||||
|
// g_type_from_name("GtkIMContextIIIM") directly (anyway, we needed
|
||||||
|
// to compare the class name with "GtkIMContextIIIM").
|
||||||
|
GType IIMContextType = g_type_from_name("GtkIMContextIIIM");
|
||||||
|
if (IIMContextType) {
|
||||||
|
sGtkIIIMContextClass = g_type_class_ref(IIMContextType);
|
||||||
|
MOZ_LOG(gGtkIMLog, LogLevel::Info,
|
||||||
|
("0x%p PrepareToDestroyContext(), added to reference to "
|
||||||
|
"GtkIMContextIIIM class to prevent it from being unloaded",
|
||||||
|
this));
|
||||||
|
} else {
|
||||||
|
MOZ_LOG(gGtkIMLog, LogLevel::Error,
|
||||||
|
("0x%p PrepareToDestroyContext(), FAILED to prevent the "
|
||||||
|
"IIIM module from being uploaded",
|
||||||
|
this));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче