From d1500de2094e42e1d461ecfdd0b69fca4af511bf Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 19 Feb 2008 06:45:11 +0000 Subject: [PATCH] (ds_read_line): Add argument to limit the length of the line to be read. Update all callers. --- src/language/data-io/data-reader.c | 2 +- src/language/syntax-file.c | 3 +- src/libpspp/ChangeLog | 7 ++++ src/libpspp/str.c | 57 +++++++++++++++++++----------- src/libpspp/str.h | 2 +- src/ui/terminal/read-line.c | 2 +- 6 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/language/data-io/data-reader.c b/src/language/data-io/data-reader.c index 9b08625e..7fd722a8 100644 --- a/src/language/data-io/data-reader.c +++ b/src/language/data-io/data-reader.c @@ -340,7 +340,7 @@ read_file_record (struct dfm_reader *r) switch (fh_get_mode (r->fh)) { case FH_MODE_TEXT: - if (ds_read_line (&r->line, r->file)) + if (ds_read_line (&r->line, r->file, SIZE_MAX)) { ds_chomp (&r->line, '\n'); return true; diff --git a/src/language/syntax-file.c b/src/language/syntax-file.c index a48dba4a..678d2f51 100644 --- a/src/language/syntax-file.c +++ b/src/language/syntax-file.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -99,7 +100,7 @@ read_syntax_file (struct getl_interface *s, do { sfs->ln++; - if (!ds_read_line (line, sfs->syntax_file)) + if (!ds_read_line (line, sfs->syntax_file, SIZE_MAX)) { if (ferror (sfs->syntax_file)) msg (ME, _("Reading `%s': %s."), sfs->fn, strerror (errno)); diff --git a/src/libpspp/ChangeLog b/src/libpspp/ChangeLog index 8547567e..7f224610 100644 --- a/src/libpspp/ChangeLog +++ b/src/libpspp/ChangeLog @@ -1,3 +1,10 @@ +2008-02-18 Ben Pfaff + + Patch #6426. Thanks to John Darrington for review. + + * str.c (ds_read_line): Add argument to limit the length of the + line to be read. Update all callers. + 2008-02-01 Ben Pfaff Patch #6386. Thanks to John Darrington for review. diff --git a/src/libpspp/str.c b/src/libpspp/str.c index b169f0d7..b88493d4 100644 --- a/src/libpspp/str.c +++ b/src/libpspp/str.c @@ -1170,30 +1170,47 @@ ds_cstr (const struct string *st_) return st->ss.string; } -/* Appends to ST a newline-terminated line read from STREAM. - Newline is the last character of ST on return, unless an I/O error - or end of file is encountered after reading some characters. - Returns true if a line is successfully read, false if no characters at - all were read before an I/O error or end of file was - encountered. */ +/* Appends to ST a newline-terminated line read from STREAM, but + no more than MAX_LENGTH characters. + Newline is the last character of ST on return, if encountering + a newline was the reason for terminating. + Returns true if at least one character was read from STREAM + and appended to ST, false if no characters at all were read + before an I/O error or end of file was encountered (or + MAX_LENGTH was 0). */ bool -ds_read_line (struct string *st, FILE *stream) +ds_read_line (struct string *st, FILE *stream, size_t max_length) { - int c; + if (!st->ss.length && max_length == SIZE_MAX) + { + size_t capacity = st->capacity ? st->capacity + 1 : 0; + ssize_t n = getline (&st->ss.string, &capacity, stream); + if (capacity) + st->capacity = capacity - 1; + if (n > 0) + { + st->ss.length = n; + return true; + } + else + return false; + } + else + { + size_t length; - c = getc (stream); - if (c == EOF) - return false; + for (length = 0; length < max_length; length++) + { + int c = getc (stream); + if (c == EOF) + break; - for (;;) - { - ds_put_char (st, c); - if (c == '\n') - return true; + ds_put_char (st, c); + if (c == '\n') + return true; + } - c = getc (stream); - if (c == EOF) - return true; + return length > 0; } } @@ -1240,7 +1257,7 @@ ds_read_config_line (struct string *st, int *line_number, FILE *stream) ds_clear (st); do { - if (!ds_read_line (st, stream)) + if (!ds_read_line (st, stream, SIZE_MAX)) return false; (*line_number)++; ds_rtrim (st, ss_cstr (CC_SPACES)); diff --git a/src/libpspp/str.h b/src/libpspp/str.h index 50671d90..0d48bd9b 100644 --- a/src/libpspp/str.h +++ b/src/libpspp/str.h @@ -202,7 +202,7 @@ size_t ds_capacity (const struct string *); char *ds_cstr (const struct string *); /* File input. */ -bool ds_read_line (struct string *, FILE *); +bool ds_read_line (struct string *, FILE *, size_t max_length); bool ds_read_config_line (struct string *, int *line_number, FILE *); bool ds_read_stream (struct string *, size_t size, size_t cnt, FILE *stream); diff --git a/src/ui/terminal/read-line.c b/src/ui/terminal/read-line.c index e72f1145..1cd65c0a 100644 --- a/src/ui/terminal/read-line.c +++ b/src/ui/terminal/read-line.c @@ -173,7 +173,7 @@ readln_read (struct string *line, enum prompt_style style) #else fputs (prompt, stdout); fflush (stdout); - if (ds_read_line (line, stdin)) + if (ds_read_line (line, stdin, SIZE_MAX)) { ds_chomp (line, '\n'); eof = false; -- 2.30.2