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 <j...@darrington.wattle.id.au> 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; }
signature.asc
Description: Digital signature
_______________________________________________ pspp-dev mailing list pspp-dev@gnu.org https://lists.gnu.org/mailman/listinfo/pspp-dev