After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 671438 - Gedit enters infinite loop on using %p in date/time in locale, which soesn't have AM/PM
Gedit enters infinite loop on using %p in date/time in locale, which soesn't ...
Status: RESOLVED FIXED
Product: gedit-plugins
Classification: Other
Component: General
3.3.x
Other Linux
: Normal major
: ---
Assigned To: Gedit maintainers
Gedit maintainers
Depends on:
Blocks:
 
 
Reported: 2012-03-06 04:21 UTC by Vadim Rutkovsky
Modified: 2019-03-23 20:57 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Avoid ininite loop (920 bytes, patch)
2012-12-06 01:46 UTC, Timothy Arceri
none Details | Review
Avoid-infinite-loop.patch (1.53 KB, patch)
2012-12-06 18:09 UTC, Timothy Arceri
none Details | Review
Avoid-infinite-loop.patch (1.55 KB, patch)
2012-12-06 18:43 UTC, Timothy Arceri
none Details | Review
Avoid-infinite-loop v3 (2.21 KB, patch)
2012-12-22 22:15 UTC, Timothy Arceri
none Details | Review

Description Vadim Rutkovsky 2012-03-06 04:21:18 UTC
gedit 3.2.3-0ubuntu0.1

to reproduce:
1) Switch to Russian locale
2) Enable "Insert Date/Time" plugin
3) Set "%p" format in plugin preferences
4) Select Edit -> Insert Date/Time from menu for new document

Result: gedit hangs up, stdout:
GLib-ERROR **: /build/buildd/glib2.0-2.30.0/./glib/gmem.c:239: failed to allocate 1660940460 bytes
Expected: No date is pasted instead of "%p"

Stackktrace:
  • #0 g_logv
    at /build/buildd/glib2.0-2.30.0/./glib/gmessages.c line 577
  • #1 g_log
    at /build/buildd/glib2.0-2.30.0/./glib/gmessages.c line 591
  • #2 g_realloc
    at /build/buildd/glib2.0-2.30.0/./glib/gmem.c line 238
  • #3 get_time
    at gedit-time-plugin.c line 402
  • #4 get_time
    at gedit-time-plugin.c line 376
  • #5 time_cb
    at gedit-time-plugin.c line 1090
  • #6 g_cclosure_marshal_VOID__VOID
    at /build/buildd/glib2.0-2.30.0/./gobject/gmarshal.c line 85
  • #7 g_closure_invoke
    at /build/buildd/glib2.0-2.30.0/./gobject/gclosure.c line 774
  • #8 signal_emit_unlocked_R
    at /build/buildd/glib2.0-2.30.0/./gobject/gsignal.c line 3272
  • #9 g_signal_emit_valist
    at /build/buildd/glib2.0-2.30.0/./gobject/gsignal.c line 3003
  • #10 g_signal_emit
    at /build/buildd/glib2.0-2.30.0/./gobject/gsignal.c line 3060
  • #11 _gtk_action_emit_activate
    at /build/buildd/gtk+3.0-3.2.0/./gtk/gtkaction.c line 799
  • #12 gtk_action_activate
    at /build/buildd/gtk+3.0-3.2.0/./gtk/gtkaction.c line 829
  • #13 gtk_real_menu_item_activate
    at /build/buildd/gtk+3.0-3.2.0/./gtk/gtkmenuitem.c line 1871
  • #14 g_cclosure_marshal_VOID__VOID
    at /build/buildd/glib2.0-2.30.0/./gobject/gmarshal.c line 85
  • #15 g_type_class_meta_marshal
    at /build/buildd/glib2.0-2.30.0/./gobject/gclosure.c line 885
  • #16 g_closure_invoke
    at /build/buildd/glib2.0-2.30.0/./gobject/gclosure.c line 774
  • #17 signal_emit_unlocked_R
    at /build/buildd/glib2.0-2.30.0/./gobject/gsignal.c line 3202
  • #18 g_signal_emit_valist
    at /build/buildd/glib2.0-2.30.0/./gobject/gsignal.c line 3003
  • #19 g_signal_emit
    at /build/buildd/glib2.0-2.30.0/./gobject/gsignal.c line 3060
  • #20 gtk_menu_item_activate
    at /build/buildd/gtk+3.0-3.2.0/./gtk/gtkmenuitem.c line 1437
  • #21 ??
    from /usr/lib/libdbusmenu-gtk3.so.4
  • #22 g_cclosure_marshal_VOID__UINT
    at /build/buildd/glib2.0-2.30.0/./gobject/gmarshal.c line 259
  • #23 g_closure_invoke
    at /build/buildd/glib2.0-2.30.0/./gobject/gclosure.c line 774
  • #24 signal_emit_unlocked_R
    at /build/buildd/glib2.0-2.30.0/./gobject/gsignal.c line 3272
  • #25 g_signal_emit_valist
    at /build/buildd/glib2.0-2.30.0/./gobject/gsignal.c line 3003
  • #26 g_signal_emit
    at /build/buildd/glib2.0-2.30.0/./gobject/gsignal.c line 3060
  • #27 ??
    from /usr/lib/libdbusmenu-glib.so.4
  • #28 dbusmenu_menuitem_handle_event
    from /usr/lib/libdbusmenu-glib.so.4
  • #29 ??
    from /usr/lib/libdbusmenu-glib.so.4
  • #30 g_timeout_dispatch
    at /build/buildd/glib2.0-2.30.0/./glib/gmain.c line 3907
  • #31 g_main_dispatch
    at /build/buildd/glib2.0-2.30.0/./glib/gmain.c line 2441
  • #32 g_main_context_dispatch
    at /build/buildd/glib2.0-2.30.0/./glib/gmain.c line 3011
  • #33 g_main_context_iterate
    at /build/buildd/glib2.0-2.30.0/./glib/gmain.c line 3089
  • #34 g_main_loop_run
    at /build/buildd/glib2.0-2.30.0/./glib/gmain.c line 3297
  • #35 gtk_main
    at /build/buildd/gtk+3.0-3.2.0/./gtk/gtkmain.c line 1367
  • #36 gedit_main
    at gedit.c line 199
  • #37 main
    at gedit.c line 290

Comment 1 Timothy Arceri 2012-12-06 01:35:06 UTC
It would seem this is cause by this loop:
http://git.gnome.org/browse/gedit/tree/plugins/time/gedit-time-plugin.c?h=gnome-3-6#n385

Maybe a limit should be added to this loop. 

From the strftime documentation:

       "Note that the return value 0 does not necessarily indicate an error; for
       example, in many locales %p yields an empty string."
Comment 2 Timothy Arceri 2012-12-06 01:46:11 UTC
Created attachment 230865 [details] [review]
Avoid ininite loop

I've attached a patch that should avoid and infinite loop.
Comment 3 Paolo Borelli 2012-12-06 09:43:06 UTC
isn't there an errno we can check to tell the case of a failed strftime from the %p case?
Comment 4 Timothy Arceri 2012-12-06 12:28:51 UTC
There doesn't seem to be one because the %p case is not an error. Also when the memory size is to small there still seems to be no errno.
Comment 5 Timothy Arceri 2012-12-06 18:09:53 UTC
Created attachment 230911 [details] [review]
Avoid-infinite-loop.patch

Ok, this patch is much better. No magic numbers this time.
Comment 6 Timothy Arceri 2012-12-06 18:43:34 UTC
Created attachment 230912 [details] [review]
Avoid-infinite-loop.patch

Forgot to allocate memory in the last patch.
This patch still needs some work as it doesn't fix the case where more than one %p is enter i.e if I enter %p%p and infinite loop is still entered.
Comment 7 Paolo Borelli 2012-12-09 11:32:31 UTC
Review of attachment 230912 [details] [review]:

::: plugins/time/gedit-time-plugin.c
@@ -385,1 +386,5 @@
-	do
+	out = g_malloc (out_length);
+	formated_time_length = strftime (out, out_length, locale_format, now);
+
... 2 more ...

What happens if one has two %p in the string format?... not that it makes much sense, but we could do this check inside the while loop no?

Also, you should use g_ascii_strcasecmp for portability
Comment 8 Timothy Arceri 2012-12-22 22:15:09 UTC
Created attachment 232134 [details] [review]
Avoid-infinite-loop v3

This patch uses g_ascii_strcasecmp and handles multiple instances of %p
Comment 9 Paolo Borelli 2012-12-23 10:00:22 UTC
I looked at the code and realized that we do not have to deal with all this complexity anymore: glib now has GDateTime which allows us to get a newly allocated utf8 string.

Timothy, thanks for your efforts on this and sorry for now having took a deeper look before.

I committed a rework of the code on master http://git.gnome.org/browse/gedit/commit/?id=121f02a3ea066565eeae5dd42868f822ecce4924

I tested with ru_RU and %p inserts " " without going in an infinite loop
Comment 10 Vadim Rutkovsky 2012-12-23 10:18:36 UTC
I can confirm that Paolo's fix works correctly, thanks!