Re: scanner / lexer problem in GUI

View: New views
5 Messages — Rating Filter:   Alert me  

Parent Message unknown Re: scanner / lexer problem in GUI

by Ben Pfaff :: Rate this Message:

| View Threaded | Show Only this Message

John Darrington <john@...> writes:

> Looking at the bug recently reported on bug-gnu-pspp I notice the following.
>
> Valgrind reports:
>
> Invalid read of size 1
> ==25266==    at 0x41AC189: u8_mbtouc (u8-mbtouc.c:33)
> ==25266==    by 0x40495FD: count_columns (lexer.c:977)
> ==25266==    by 0x4049777: lex_source_get_last_column (lexer.c:1010)
> ==25266==    by 0x404A10E: lex_source_error_valist (lexer.c:1328)
> ==25266==    by 0x4048810: lex_next_error_valist (lexer.c:392)
> ==25266==    by 0x40482C5: lex_error (lexer.c:247)
> ==25266==    by 0x4048E62: lex_force_string (lexer.c:623)
> ==25266==    by 0x405E8CC: cmd_variable_labels (variable-label.c:50)
> ==25266==    by 0x40468FE: do_parse_command (command.c:222)
> ==25266==    by 0x404662F: cmd_parse_in_state (command.c:136)
> ==25266==    by 0x4046713: cmd_parse (command.c:152)
> ==25266==    by 0x8097815: execute_syntax (executor.c:121)
> ==25266==  Address 0x69f27d8 is 0 bytes after a block of size 144 alloc'd
> ==25266==    at 0x4024046: realloc (vg_replace_malloc.c:525)
> ==25266==    by 0x41AD940: xrealloc (xmalloc.c:63)
> ==25266==    by 0x41AD89B: x2nrealloc (xalloc.h:215)
> ==25266==    by 0x41AD989: x2realloc (xmalloc.c:78)
> ==25266==    by 0x4049BE6: lex_source_expand__ (lexer.c:1197)
> ==25266==    by 0x4049C15: lex_source_read__ (lexer.c:1214)
> ==25266==    by 0x404A2C9: lex_source_get__ (lexer.c:1399)
> ==25266==    by 0x4048241: lex_get (lexer.c:228)
> ==25266==    by 0x4046982: do_parse_command (command.c:235)
> ==25266==    by 0x404662F: cmd_parse_in_state (command.c:136)
> ==25266==    by 0x4046713: cmd_parse (command.c:152)
> ==25266==    by 0x8097815: execute_syntax (executor.c:121)

Funny, I get different valgrind report:

==21886== Invalid read of size 1
==21886==    at 0x4E93697: segmenter_parse_string__ (segment.c:757)
==21886==    by 0x4E957C0: segmenter_parse_mid_command__ (segment.c:899)
==21886==    by 0x4E943F4: segmenter_push (segment.c:1546)
==21886==    by 0x4E9073B: lex_source_get__ (lexer.c:1396)
==21886==    by 0x4E912D8: lex_get (lexer.c:228)
==21886==    by 0x4E96887: parse_vs_variable_idx (variable-parser.c:72)
==21886==    by 0x4E96916: parse_var_idx_class (variable-parser.c:159)
==21886==    by 0x4E974EA: parse_var_set_vars (variable-parser.c:294)
==21886==    by 0x4E9793D: parse_variables (variable-parser.c:121)
==21886==    by 0x4EA3EBC: cmd_variable_labels (variable-label.c:47)
==21886==    by 0x4E8EB94: cmd_parse_in_state (command.c:222)
==21886==    by 0x4E8F027: cmd_parse (command.c:152)
==21886==    by 0x808EA1B: execute_syntax (executor.c:121)
==21886==    by 0x80AB1E3: on_run_all (psppire-syntax-window.c:446)
==21886==    by 0x78F1CAB: g_cclosure_marshal_VOID__VOID (gmarshal.c:77)
==21886==    by 0x78E4139: g_closure_invoke (gclosure.c:767)
==21886==    by 0x78FA61C: signal_emit_unlocked_R (gsignal.c:3248)
==21886==    by 0x78FBBFB: g_signal_emit_valist (gsignal.c:2981)
==21886==    by 0x78FC075: g_signal_emit (gsignal.c:3038)
==21886==    by 0x7257BB4: _gtk_action_emit_activate (gtkaction.c:755)
==21886==    by 0x7259CBC: gtk_action_activate (gtkaction.c:785)
==21886==    by 0x78F1CAB: g_cclosure_marshal_VOID__VOID (gmarshal.c:77)
==21886==    by 0x78E27A8: g_type_class_meta_marshal (gclosure.c:878)
==21886==    by 0x78E4139: g_closure_invoke (gclosure.c:767)
==21886==    by 0x78F9EB9: signal_emit_unlocked_R (gsignal.c:3178)
==21886==    by 0x78FBBFB: g_signal_emit_valist (gsignal.c:2981)
==21886==    by 0x78FC075: g_signal_emit (gsignal.c:3038)
==21886==    by 0x745FF04: gtk_widget_activate (gtkwidget.c:4974)
==21886==    by 0x733F3FF: gtk_menu_shell_activate_item (gtkmenushell.c:1256)
==21886==    by 0x7340ECE: gtk_menu_shell_button_release (gtkmenushell.c:683)
==21886==    by 0x73366C3: gtk_menu_button_release (gtkmenu.c:3005)
==21886==    by 0x732FE73: _gtk_marshal_BOOLEAN__BOXED (gtkmarshalers.c:84)
==21886==    by 0x78E27A8: g_type_class_meta_marshal (gclosure.c:878)
==21886==    by 0x78E4139: g_closure_invoke (gclosure.c:767)
==21886==    by 0x78FA265: signal_emit_unlocked_R (gsignal.c:3286)
==21886==    by 0x78FBA7A: g_signal_emit_valist (gsignal.c:2991)
==21886==    by 0x78FC075: g_signal_emit (gsignal.c:3038)
==21886==    by 0x745C155: gtk_widget_event_internal (gtkwidget.c:4943)
==21886==    by 0x73284CC: gtk_propagate_event (gtkmain.c:2442)
==21886==    by 0x7329856: gtk_main_do_event (gtkmain.c:1647)
==21886==    by 0x761EDD9: gdk_event_dispatch (gdkevents-x11.c:2372)
==21886==    by 0x7F18304: g_main_context_dispatch (gmain.c:1960)
==21886==    by 0x7F1BFE7: g_main_context_iterate (gmain.c:2591)
==21886==    by 0x7F1C526: g_main_loop_run (gmain.c:2799)
==21886==    by 0x7329E18: gtk_main (gtkmain.c:1219)
==21886==    by 0x809292C: run_inner_loop (main.c:233)
==21886==    by 0x7329F80: gtk_main (gtkmain.c:2339)
==21886==    by 0x8092862: main (main.c:333)
==21886==  Address 0xd803d60 is 0 bytes after a block of size 144 alloc'd
==21886==    at 0x49E0046: realloc (vg_replace_malloc.c:525)
==21886==    by 0x4FCAD9C: xrealloc (xmalloc.c:63)
==21886==    by 0x4FCAE1E: x2realloc (xalloc.h:215)
==21886==    by 0x4E9000C: lex_source_expand__ (lexer.c:1197)
==21886==    by 0x4E907B6: lex_source_get__ (lexer.c:1214)
==21886==    by 0x4E912D8: lex_get (lexer.c:228)
==21886==    by 0x4E8E81F: cmd_parse_in_state (command.c:235)
==21886==    by 0x4E8F027: cmd_parse (command.c:152)
==21886==    by 0x808EA1B: execute_syntax (executor.c:121)
==21886==    by 0x80AB1E3: on_run_all (psppire-syntax-window.c:446)
==21886==    by 0x78F1CAB: g_cclosure_marshal_VOID__VOID (gmarshal.c:77)
==21886==    by 0x78E4139: g_closure_invoke (gclosure.c:767)
==21886==    by 0x78FA61C: signal_emit_unlocked_R (gsignal.c:3248)
==21886==    by 0x78FBBFB: g_signal_emit_valist (gsignal.c:2981)
==21886==    by 0x78FC075: g_signal_emit (gsignal.c:3038)
==21886==    by 0x7257BB4: _gtk_action_emit_activate (gtkaction.c:755)
==21886==    by 0x7259CBC: gtk_action_activate (gtkaction.c:785)
==21886==    by 0x78F1CAB: g_cclosure_marshal_VOID__VOID (gmarshal.c:77)
==21886==    by 0x78E27A8: g_type_class_meta_marshal (gclosure.c:878)
==21886==    by 0x78E4139: g_closure_invoke (gclosure.c:767)
==21886==    by 0x78F9EB9: signal_emit_unlocked_R (gsignal.c:3178)
==21886==    by 0x78FBBFB: g_signal_emit_valist (gsignal.c:2981)
==21886==    by 0x78FC075: g_signal_emit (gsignal.c:3038)
==21886==    by 0x745FF04: gtk_widget_activate (gtkwidget.c:4974)
==21886==    by 0x733F3FF: gtk_menu_shell_activate_item (gtkmenushell.c:1256)
==21886==    by 0x7340ECE: gtk_menu_shell_button_release (gtkmenushell.c:683)
==21886==    by 0x73366C3: gtk_menu_button_release (gtkmenu.c:3005)
==21886==    by 0x732FE73: _gtk_marshal_BOOLEAN__BOXED (gtkmarshalers.c:84)
==21886==    by 0x78E27A8: g_type_class_meta_marshal (gclosure.c:878)
==21886==    by 0x78E4139: g_closure_invoke (gclosure.c:767)
==21886==    by 0x78FA265: signal_emit_unlocked_R (gsignal.c:3286)
==21886==    by 0x78FBA7A: g_signal_emit_valist (gsignal.c:2991)
==21886==    by 0x78FC075: g_signal_emit (gsignal.c:3038)
==21886==    by 0x745C155: gtk_widget_event_internal (gtkwidget.c:4943)
==21886==    by 0x73284CC: gtk_propagate_event (gtkmain.c:2442)
==21886==    by 0x7329856: gtk_main_do_event (gtkmain.c:1647)
==21886==    by 0x761EDD9: gdk_event_dispatch (gdkevents-x11.c:2372)
==21886==    by 0x7F18304: g_main_context_dispatch (gmain.c:1960)
==21886==    by 0x7F1BFE7: g_main_context_iterate (gmain.c:2591)
==21886==    by 0x7F1C526: g_main_loop_run (gmain.c:2799)
==21886==    by 0x7329E18: gtk_main (gtkmain.c:1219)
==21886==    by 0x809292C: run_inner_loop (main.c:233)
==21886==    by 0x7329F80: gtk_main (gtkmain.c:2339)
==21886==    by 0x8092862: main (main.c:333)

Anyhow, I'll look into it.

Thanks,

Ben.

_______________________________________________
pspp-dev mailing list
pspp-dev@...
https://lists.gnu.org/mailman/listinfo/pspp-dev

Parent Message unknown Re: scanner / lexer problem in GUI

by Ben Pfaff :: Rate this Message:

| View Threaded | Show Only this Message

John Darrington <john@...> writes:

> Looking at the bug recently reported on bug-gnu-pspp I notice the following.
>
> Valgrind reports:

I sent out a 2-patch series that fixes the problem that I see,
with and without valgrind.  Does it fix the problem you see too?

Thanks,

Ben.

_______________________________________________
pspp-dev mailing list
pspp-dev@...
https://lists.gnu.org/mailman/listinfo/pspp-dev

Re: scanner / lexer problem in GUI

by John Darrington-4 :: Rate this Message:

| View Threaded | Show Only this Message

As it happened, I had a prepared a similar patch.  Attached.
Perhaps we could compare patches.

J'

On Sat, May 05, 2012 at 10:14:57PM -0700, Ben Pfaff wrote:
     John Darrington <john@...> writes:
     
     > Looking at the bug recently reported on bug-gnu-pspp I notice the following.
     >
     > Valgrind reports:
     
     I sent out a 2-patch series that fixes the problem that I see,
     with and without valgrind.  Does it fix the problem you see too?
     
     Thanks,
     
     Ben.

--
PGP Public key ID: 1024D/2DE827B3
fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
See http://keys.gnupg.net or any PGP keyserver for public key.



diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c
index e72a3e4..7048d8a 100644
--- a/src/language/lexer/lexer.c
+++ b/src/language/lexer/lexer.c
@@ -1217,6 +1217,9 @@ lex_source_read__ (struct lex_source *src)
       n = src->reader->class->read (src->reader, &src->buffer[head_ofs],
                                     src->allocated - head_ofs,
                                     segmenter_get_prompt (&src->segmenter));
+
+      assert (n <= src->allocated - head_ofs);
+
       if (n == 0)
         {
           /* End of input.
diff --git a/src/ui/gui/psppire-lex-reader.c b/src/ui/gui/psppire-lex-reader.c
index ae043b0..6351094 100644
--- a/src/ui/gui/psppire-lex-reader.c
+++ b/src/ui/gui/psppire-lex-reader.c
@@ -66,26 +66,47 @@ lex_gtk_text_buffer_read (struct lex_reader *r_, char *buf, size_t n,
                  enum prompt_style prompt_style UNUSED)
 {
   struct lex_gtk_text_buffer_reader *r = lex_gtk_text_buffer_reader_cast (r_);
-  int n_chars = n;
   char *s;
 
   GtkTextIter iter = r->start ;
   
-  int offset = gtk_text_iter_get_offset (&iter);
-  int end_offset = gtk_text_iter_get_offset (&r->stop);
-
-  if ( end_offset - offset < n)
-    n_chars = end_offset - offset;
-  
-  gtk_text_iter_set_offset (&iter, offset + n_chars);
-
-  s = gtk_text_iter_get_text (&r->start, &iter);
-
-  strncpy (buf, s, n_chars);
+  const gint offset = gtk_text_iter_get_offset (&iter);
+  const gint end_offset = gtk_text_iter_get_offset (&r->stop);
+  const gint n_bytes = (end_offset - offset < n) ? end_offset - offset : n;
+
+  /* We want to get no more than n_bytes from the buffer.
+     However, since gtk_text_iter deals in chars, not bytes, we cannot possibly
+     set an iter which we know will not fetch too many bytes.  Thus, we start
+     by assuming that n_chars == n_bytes and step backwards if we end up fetching
+     too many.
+   */
+  gint n_chars = n_bytes;
+  gint backstep = 4;
+  gint bytes_read = 0;
+  do
+    {
+      gtk_text_iter_set_offset (&iter, offset + n_chars);
+
+      s = gtk_text_iter_get_text (&r->start, &iter);
+      bytes_read = strlen (s);
+      if ( n_chars == 1 && bytes_read > n_bytes)
+ {
+  g_critical ("Reading a single character returned %d bytes, but only %d bytes"
+      " were requested", bytes_read, n_bytes);
+  return 0;
+ }
+      n_chars -= backstep;
+      if ( n_chars < 1)
+ n_chars = 1;
+      backstep *= 2;
+    }
+  while (bytes_read > n_bytes);
+
+  strncpy (buf, s, bytes_read);
 
   r->start = iter;
 
-  return strlen (s);
+  return bytes_read;
 }
 
 



_______________________________________________
pspp-dev mailing list
pspp-dev@...
https://lists.gnu.org/mailman/listinfo/pspp-dev

signature.asc (196 bytes) Download Attachment

Re: scanner / lexer problem in GUI

by John Darrington-4 :: Rate this Message:

| View Threaded | Show Only this Message

OK.  I like your solution better.

Please push it when you're ready.

J'

On Sun, May 06, 2012 at 05:34:48AM +0000, John Darrington wrote:
     As it happened, I had a prepared a similar patch.  Attached.
     Perhaps we could compare patches.
     
     J'
     
     On Sat, May 05, 2012 at 10:14:57PM -0700, Ben Pfaff wrote:
          John Darrington <john@...> writes:
         
          > Looking at the bug recently reported on bug-gnu-pspp I notice the following.
          >
          > Valgrind reports:
         
          I sent out a 2-patch series that fixes the problem that I see,
          with and without valgrind.  Does it fix the problem you see too?
         
          Thanks,
         
          Ben.
     
     --
     PGP Public key ID: 1024D/2DE827B3
     fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
     See http://keys.gnupg.net or any PGP keyserver for public key.
     

     diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c
     index e72a3e4..7048d8a 100644
     --- a/src/language/lexer/lexer.c
     +++ b/src/language/lexer/lexer.c
     @@ -1217,6 +1217,9 @@ lex_source_read__ (struct lex_source *src)
            n = src->reader->class->read (src->reader, &src->buffer[head_ofs],
                                          src->allocated - head_ofs,
                                          segmenter_get_prompt (&src->segmenter));
     +
     +      assert (n <= src->allocated - head_ofs);
     +
            if (n == 0)
              {
                /* End of input.
     diff --git a/src/ui/gui/psppire-lex-reader.c b/src/ui/gui/psppire-lex-reader.c
     index ae043b0..6351094 100644
     --- a/src/ui/gui/psppire-lex-reader.c
     +++ b/src/ui/gui/psppire-lex-reader.c
     @@ -66,26 +66,47 @@ lex_gtk_text_buffer_read (struct lex_reader *r_, char *buf, size_t n,
                       enum prompt_style prompt_style UNUSED)
      {
        struct lex_gtk_text_buffer_reader *r = lex_gtk_text_buffer_reader_cast (r_);
     -  int n_chars = n;
        char *s;
     
        GtkTextIter iter = r->start ;
       
     -  int offset = gtk_text_iter_get_offset (&iter);
     -  int end_offset = gtk_text_iter_get_offset (&r->stop);
     -
     -  if ( end_offset - offset < n)
     -    n_chars = end_offset - offset;
     -  
     -  gtk_text_iter_set_offset (&iter, offset + n_chars);
     -
     -  s = gtk_text_iter_get_text (&r->start, &iter);
     -
     -  strncpy (buf, s, n_chars);
     +  const gint offset = gtk_text_iter_get_offset (&iter);
     +  const gint end_offset = gtk_text_iter_get_offset (&r->stop);
     +  const gint n_bytes = (end_offset - offset < n) ? end_offset - offset : n;
     +
     +  /* We want to get no more than n_bytes from the buffer.
     +     However, since gtk_text_iter deals in chars, not bytes, we cannot possibly
     +     set an iter which we know will not fetch too many bytes.  Thus, we start
     +     by assuming that n_chars == n_bytes and step backwards if we end up fetching
     +     too many.
     +   */
     +  gint n_chars = n_bytes;
     +  gint backstep = 4;
     +  gint bytes_read = 0;
     +  do
     +    {
     +      gtk_text_iter_set_offset (&iter, offset + n_chars);
     +
     +      s = gtk_text_iter_get_text (&r->start, &iter);
     +      bytes_read = strlen (s);
     +      if ( n_chars == 1 && bytes_read > n_bytes)
     + {
     +  g_critical ("Reading a single character returned %d bytes, but only %d bytes"
     +      " were requested", bytes_read, n_bytes);
     +  return 0;
     + }
     +      n_chars -= backstep;
     +      if ( n_chars < 1)
     + n_chars = 1;
     +      backstep *= 2;
     +    }
     +  while (bytes_read > n_bytes);
     +
     +  strncpy (buf, s, bytes_read);
     
        r->start = iter;
     
     -  return strlen (s);
     +  return bytes_read;
      }
     
     




--
PGP Public key ID: 1024D/2DE827B3
fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
See http://keys.gnupg.net or any PGP keyserver for public key.



_______________________________________________
pspp-dev mailing list
pspp-dev@...
https://lists.gnu.org/mailman/listinfo/pspp-dev

signature.asc (196 bytes) Download Attachment

Re: scanner / lexer problem in GUI

by Ben Pfaff :: Rate this Message:

| View Threaded | Show Only this Message

Thanks for investigating and reviewing.  I pushed my patches.

John Darrington <john@...> writes:

> OK.  I like your solution better.
>
> Please push it when you're ready.
>
> J'
>
> On Sun, May 06, 2012 at 05:34:48AM +0000, John Darrington wrote:
>      As it happened, I had a prepared a similar patch.  Attached.
>      Perhaps we could compare patches.
>      
>      J'
>      
>      On Sat, May 05, 2012 at 10:14:57PM -0700, Ben Pfaff wrote:
>           John Darrington <john@...> writes:
>          
>           > Looking at the bug recently reported on bug-gnu-pspp I notice the following.
>           >
>           > Valgrind reports:
>          
>           I sent out a 2-patch series that fixes the problem that I see,
>           with and without valgrind.  Does it fix the problem you see too?
>          
>           Thanks,
>          
>           Ben.
>      
>      --
>      PGP Public key ID: 1024D/2DE827B3
>      fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
>      See http://keys.gnupg.net or any PGP keyserver for public key.
>      
>
>      diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c
>      index e72a3e4..7048d8a 100644
>      --- a/src/language/lexer/lexer.c
>      +++ b/src/language/lexer/lexer.c
>      @@ -1217,6 +1217,9 @@ lex_source_read__ (struct lex_source *src)
>             n = src->reader->class->read (src->reader, &src->buffer[head_ofs],
>                                           src->allocated - head_ofs,
>                                           segmenter_get_prompt (&src->segmenter));
>      +
>      +      assert (n <= src->allocated - head_ofs);
>      +
>             if (n == 0)
>               {
>                 /* End of input.
>      diff --git a/src/ui/gui/psppire-lex-reader.c b/src/ui/gui/psppire-lex-reader.c
>      index ae043b0..6351094 100644
>      --- a/src/ui/gui/psppire-lex-reader.c
>      +++ b/src/ui/gui/psppire-lex-reader.c
>      @@ -66,26 +66,47 @@ lex_gtk_text_buffer_read (struct lex_reader *r_, char *buf, size_t n,
>                        enum prompt_style prompt_style UNUSED)
>       {
>         struct lex_gtk_text_buffer_reader *r = lex_gtk_text_buffer_reader_cast (r_);
>      -  int n_chars = n;
>         char *s;
>      
>         GtkTextIter iter = r->start ;
>        
>      -  int offset = gtk_text_iter_get_offset (&iter);
>      -  int end_offset = gtk_text_iter_get_offset (&r->stop);
>      -
>      -  if ( end_offset - offset < n)
>      -    n_chars = end_offset - offset;
>      -  
>      -  gtk_text_iter_set_offset (&iter, offset + n_chars);
>      -
>      -  s = gtk_text_iter_get_text (&r->start, &iter);
>      -
>      -  strncpy (buf, s, n_chars);
>      +  const gint offset = gtk_text_iter_get_offset (&iter);
>      +  const gint end_offset = gtk_text_iter_get_offset (&r->stop);
>      +  const gint n_bytes = (end_offset - offset < n) ? end_offset - offset : n;
>      +
>      +  /* We want to get no more than n_bytes from the buffer.
>      +     However, since gtk_text_iter deals in chars, not bytes, we cannot possibly
>      +     set an iter which we know will not fetch too many bytes.  Thus, we start
>      +     by assuming that n_chars == n_bytes and step backwards if we end up fetching
>      +     too many.
>      +   */
>      +  gint n_chars = n_bytes;
>      +  gint backstep = 4;
>      +  gint bytes_read = 0;
>      +  do
>      +    {
>      +      gtk_text_iter_set_offset (&iter, offset + n_chars);
>      +
>      +      s = gtk_text_iter_get_text (&r->start, &iter);
>      +      bytes_read = strlen (s);
>      +      if ( n_chars == 1 && bytes_read > n_bytes)
>      + {
>      +  g_critical ("Reading a single character returned %d bytes, but only %d bytes"
>      +      " were requested", bytes_read, n_bytes);
>      +  return 0;
>      + }
>      +      n_chars -= backstep;
>      +      if ( n_chars < 1)
>      + n_chars = 1;
>      +      backstep *= 2;
>      +    }
>      +  while (bytes_read > n_bytes);
>      +
>      +  strncpy (buf, s, bytes_read);
>      
>         r->start = iter;
>      
>      -  return strlen (s);
>      +  return bytes_read;
>       }

_______________________________________________
pspp-dev mailing list
pspp-dev@...
https://lists.gnu.org/mailman/listinfo/pspp-dev