[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: scanner / lexer problem in GUI
From: |
Ben Pfaff |
Subject: |
Re: scanner / lexer problem in GUI |
Date: |
Sun, 06 May 2012 08:59:36 -0700 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) |
Thanks for investigating and reviewing. I pushed my patches.
John Darrington <address@hidden> 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 <address@hidden> 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;
> }