Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #61639 > unrolled thread
| Started by | mathog <dmathog@gmail.com> |
|---|---|
| First post | 2015-05-06 12:35 -0700 |
| Last post | 2015-05-07 15:28 -0700 |
| Articles | 18 on this page of 38 — 12 participants |
Back to article view | Back to comp.lang.c
Method other than strlen to check for truncation with fgets? mathog <dmathog@gmail.com> - 2015-05-06 12:35 -0700
Re: Method other than strlen to check for truncation with fgets? Barry Schwarz <schwarzb@dqel.com> - 2015-05-06 15:14 -0700
Re: Method other than strlen to check for truncation with fgets? mathog <dmathog@gmail.com> - 2015-05-06 16:14 -0700
Re: Method other than strlen to check for truncation with fgets? Barry Schwarz <schwarzb@dqel.com> - 2015-05-06 17:51 -0700
Re: Method other than strlen to check for truncation with fgets? Tim Rentsch <txr@alumni.caltech.edu> - 2015-05-06 18:23 -0700
Re: Method other than strlen to check for truncation with fgets? mathog <dmathog@gmail.com> - 2015-05-07 10:07 -0700
Re: Method other than strlen to check for truncation with fgets? Tim Rentsch <txr@alumni.caltech.edu> - 2015-05-07 16:06 -0700
Re: Method other than strlen to check for truncation with fgets? James Kuyper <jameskuyper@verizon.net> - 2015-05-06 22:20 -0400
Re: Method other than strlen to check for truncation with fgets? mathog <dmathog@gmail.com> - 2015-05-07 10:29 -0700
Re: Method other than strlen to check for truncation with fgets? James Kuyper <jameskuyper@verizon.net> - 2015-05-07 14:09 -0400
Re: Method other than strlen to check for truncation with fgets? mathog <dmathog@gmail.com> - 2015-05-07 12:48 -0700
Re: Method other than strlen to check for truncation with fgets? James Kuyper <jameskuyper@verizon.net> - 2015-05-07 17:01 -0400
Re: Method other than strlen to check for truncation with fgets? mathog <dmathog@gmail.com> - 2015-05-08 10:59 -0700
Re: Method other than strlen to check for truncation with fgets? James Kuyper <jameskuyper@verizon.net> - 2015-05-08 14:48 -0400
Re: Method other than strlen to check for truncation with fgets? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-05-08 18:37 +0000
Re: Method other than strlen to check for truncation with fgets? James Kuyper <jameskuyper@verizon.net> - 2015-05-08 15:06 -0400
Re: Method other than strlen to check for truncation with fgets? Lőrinczy Zsigmond <nospam@for.me> - 2015-05-07 07:04 +0200
Re: Method other than strlen to check for truncation with fgets? Richard Heathfield <rjh@cpax.org.uk> - 2015-05-07 06:52 +0100
Re: Method other than strlen to check for truncation with fgets? Lőrinczy Zsigmond <zsiga@nospam.for.me> - 2015-05-07 09:58 +0200
Re: Method other than strlen to check for truncation with fgets? Stephen Sprunk <stephen@sprunk.org> - 2015-05-07 09:12 -0500
Re: Method other than strlen to check for truncation with fgets? Keith Thompson <kst-u@mib.org> - 2015-05-07 08:51 -0700
Re: Method other than strlen to check for truncation with fgets? Lőrinczy Zsigmond <zsiga@nospam.for.me> - 2015-05-07 19:09 +0200
Re: Method other than strlen to check for truncation with fgets? James Kuyper <jameskuyper@verizon.net> - 2015-05-07 14:15 -0400
Re: Method other than strlen to check for truncation with fgets? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-07 11:31 +0100
Re: Method other than strlen to check for truncation with fgets? Lőrinczy Zsigmond <zsiga@nospam.for.me> - 2015-05-07 15:41 +0200
Re: Method other than strlen to check for truncation with fgets? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-08 02:44 +0100
Re: Method other than strlen to check for truncation with fgets? James Kuyper <jameskuyper@verizon.net> - 2015-05-07 23:24 -0400
Re: Method other than strlen to check for truncation with fgets? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-08 04:41 +0100
Re: Method other than strlen to check for truncation with fgets? Keith Thompson <kst-u@mib.org> - 2015-05-07 08:49 -0700
Re: Method other than strlen to check for truncation with fgets? James Kuyper <jameskuyper@verizon.net> - 2015-05-07 12:19 -0400
Re: Method other than strlen to check for truncation with fgets? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-05-07 18:08 +0000
Re: Method other than strlen to check for truncation with fgets? James Kuyper <jameskuyper@verizon.net> - 2015-05-07 12:19 -0400
Re: Method other than strlen to check for truncation with fgets? mathog <dmathog@gmail.com> - 2015-05-07 09:57 -0700
Re: Method other than strlen to check for truncation with fgets? Siri Cruz <chine.bleu@yahoo.com> - 2015-05-07 11:31 -0700
Re: Method other than strlen to check for truncation with fgets? Keith Thompson <kst-u@mib.org> - 2015-05-07 12:00 -0700
Re: Method other than strlen to check for truncation with fgets? Siri Cruz <chine.bleu@yahoo.com> - 2015-05-07 12:44 -0700
Re: Method other than strlen to check for truncation with fgets? Keith Thompson <kst-u@mib.org> - 2015-05-07 14:03 -0700
Re: Method other than strlen to check for truncation with fgets? Siri Cruz <chine.bleu@yahoo.com> - 2015-05-07 15:28 -0700
Page 2 of 2 — ← Prev page 1 [2]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-05-07 08:51 -0700 |
| Message-ID | <87oalwjsh4.fsf@kst-u.example.com> |
| In reply to | #61670 |
Lőrinczy Zsigmond <zsiga@nospam.for.me> writes:
>> 1) The fgets function works on text streams, which are not supposed to
>> contain null characters;
>
> Still, they *might* contain binary zeroes;
> gcc for example handles this situation:
>
> nulla.c:5:4: warning: null character(s) ignored
[...]
To be clear, that's gcc compile-time behavior when processing a source
file containing null characters. Handling of C source files needn't be
consistent with run-time handling of text streams; compilers don't even
have to be implemented in C.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Lőrinczy Zsigmond <zsiga@nospam.for.me> |
|---|---|
| Date | 2015-05-07 19:09 +0200 |
| Message-ID | <mig68n$798$1@speranza.aioe.org> |
| In reply to | #61688 |
> To be clear, that's gcc compile-time behavior when processing a source > file containing null characters. Handling of C source files needn't be > consistent with run-time handling of text streams; compilers don't even > have to be implemented in C. You are right in every point, but neither of them disproves my statements: 1. (supposed) text-files might contain binary zeroes 2. it is still possible to handle them in C
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-05-07 14:15 -0400 |
| Message-ID | <miga1f$ndc$1@dont-email.me> |
| In reply to | #61698 |
On 05/07/2015 01:09 PM, Lőrinczy Zsigmond wrote: >> To be clear, that's gcc compile-time behavior when processing a source >> file containing null characters. Handling of C source files needn't be >> consistent with run-time handling of text streams; compilers don't even >> have to be implemented in C. > > You are right in every point, > but neither of them disproves my statements: > > 1. (supposed) text-files might contain binary zeroes > 2. it is still possible to handle them in C Useful handling of files opened in text mode that violate the requirements specified in 7.21.2 might be possible, but if so, only because some source other than the C standard provides an alternative to the guarantee that 7.21.2 fails to provide for such files. If you can't be sure that the data you're reading in matches the data that was written to the file, what useful processing can you do with that data? -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-05-07 11:31 +0100 |
| Message-ID | <87fv788yrv.fsf@bsb.me.uk> |
| In reply to | #61663 |
Lőrinczy Zsigmond <nospam@for.me> writes: > On 2015.05.06. 21:35, mathog wrote: >> If fgets reads a line larger than the buffer then the >> buffer will end with "...\0" instead of the usual >> "...\n\0". This is usually handled something like: > > The input might contain \0 so this method is unreliable. The method is reliable even if there are nulls in the input (provided fgets processes them just like any other character). -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Lőrinczy Zsigmond <zsiga@nospam.for.me> |
|---|---|
| Date | 2015-05-07 15:41 +0200 |
| Message-ID | <mifq32$7fd$1@speranza.aioe.org> |
| In reply to | #61677 |
>> The input might contain \0 so this method is unreliable. > > The method is reliable even if there are nulls in the input (provided > fgets processes them just like any other character). fgets does that alright, strlen doesn't. You still could check for more data after the first \0 and find out how many \0 the input contained, but this method is neither efficient nor elegant.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-05-08 02:44 +0100 |
| Message-ID | <877fsjx2q0.fsf@bsb.me.uk> |
| In reply to | #61683 |
Lőrinczy Zsigmond <zsiga@nospam.for.me> writes: >>> The input might contain \0 so this method is unreliable. >> >> The method is reliable even if there are nulls in the input (provided >> fgets processes them just like any other character). > > fgets does that alright, strlen doesn't. > > You still could check for more data after the first \0 > and find out how many \0 the input contained, > but this method is neither efficient nor elegant. So why use it? I think I'm losing track of the point you are making. The idea of marking the last buffer element with a non-null value is reliable even in the presence of nulls in the input (which was, I thought, your point). The length of the input can be recovered very simply -- it's sizeof buffer - 1 if the last element is now null, and memchr(buffer, '\n', sizeof buffer) - buffer + 1 otherwise. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-05-07 23:24 -0400 |
| Message-ID | <miha74$4aq$1@dont-email.me> |
| In reply to | #61744 |
On 05/07/2015 09:44 PM, Ben Bacarisse wrote: > Lőrinczy Zsigmond <zsiga@nospam.for.me> writes: > >>>> The input might contain \0 so this method is unreliable. >>> >>> The method is reliable even if there are nulls in the input (provided >>> fgets processes them just like any other character). >> >> fgets does that alright, strlen doesn't. >> >> You still could check for more data after the first \0 >> and find out how many \0 the input contained, >> but this method is neither efficient nor elegant. > > So why use it? I think I'm losing track of the point you are making. > The idea of marking the last buffer element with a non-null value is > reliable even in the presence of nulls in the input (which was, I > thought, your point). The length of the input can be recovered very > simply -- it's sizeof buffer - 1 if the last element is now null, and > memchr(buffer, '\n', sizeof buffer) - buffer + 1 otherwise. > if fgets() reaches end-of-file before reading in a newline, and before reaching the end of the buffer, then the last element will not be null, and memchr(buffer, '\n', sizeof buffer) will either return a null pointer (in which case your expression has undefined behavior), or it will return a pointer to a newline character that was already in the buffer before the call to fgets(), and didn't get overwritten by the read (in which case your expression will produce a number larger than the length of the input). -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-05-08 04:41 +0100 |
| Message-ID | <87pp6bviqe.fsf@bsb.me.uk> |
| In reply to | #61746 |
James Kuyper <jameskuyper@verizon.net> writes: > On 05/07/2015 09:44 PM, Ben Bacarisse wrote: >> Lőrinczy Zsigmond <zsiga@nospam.for.me> writes: >> >>>>> The input might contain \0 so this method is unreliable. >>>> >>>> The method is reliable even if there are nulls in the input (provided >>>> fgets processes them just like any other character). >>> >>> fgets does that alright, strlen doesn't. >>> >>> You still could check for more data after the first \0 >>> and find out how many \0 the input contained, >>> but this method is neither efficient nor elegant. >> >> So why use it? I think I'm losing track of the point you are making. >> The idea of marking the last buffer element with a non-null value is >> reliable even in the presence of nulls in the input (which was, I >> thought, your point). The length of the input can be recovered very >> simply -- it's sizeof buffer - 1 if the last element is now null, and >> memchr(buffer, '\n', sizeof buffer) - buffer + 1 otherwise. >> > > if fgets() reaches end-of-file before reading in a newline, and before > reaching the end of the buffer, then the last element will not be > null, Yes, good point. It's too late for me (the election is keeping me up) but a test for eof() could be used to about undefined behaviour. Nulls in an incomplete last line would still be a problem. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-05-07 08:49 -0700 |
| Message-ID | <87sib8jskj.fsf@kst-u.example.com> |
| In reply to | #61677 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Lőrinczy Zsigmond <nospam@for.me> writes:
>> On 2015.05.06. 21:35, mathog wrote:
>>> If fgets reads a line larger than the buffer then the
>>> buffer will end with "...\0" instead of the usual
>>> "...\n\0". This is usually handled something like:
>>
>> The input might contain \0 so this method is unreliable.
>
> The method is reliable even if there are nulls in the input (provided
> fgets processes them just like any other character).
But fgets is not required to do so.
N1570 7.21.2:
Data read in from a text stream will necessarily compare equal to
the data that were earlier written out to that stream only if:
the data consist only of printing characters and the control
characters horizontal tab and new-line; no new-line character
is immediately preceded by space characters; and the last
character is a new-line character. Whether space characters
that are written out immediately before a new-line character
appear when read in is implementation-defined.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-05-07 12:19 -0400 |
| Message-ID | <mig392$pa0$2@dont-email.me> |
| In reply to | #61687 |
On 05/07/2015 11:49 AM, Keith Thompson wrote: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >> Lőrinczy Zsigmond <nospam@for.me> writes: >>> On 2015.05.06. 21:35, mathog wrote: >>>> If fgets reads a line larger than the buffer then the >>>> buffer will end with "...\0" instead of the usual >>>> "...\n\0". This is usually handled something like: >>> >>> The input might contain \0 so this method is unreliable. >> >> The method is reliable even if there are nulls in the input (provided >> fgets processes them just like any other character). > > But fgets is not required to do so. > > N1570 7.21.2: > > Data read in from a text stream will necessarily compare equal to > the data that were earlier written out to that stream only if: > the data consist only of printing characters and the control > characters horizontal tab and new-line; no new-line character > is immediately preceded by space characters; and the last > character is a new-line character. Whether space characters > that are written out immediately before a new-line character > appear when read in is implementation-defined. Which is why files violating any of those restrictions should be accessed in binary mode. fgets() on a binary stream should process null characters normally. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2015-05-07 18:08 +0000 |
| Message-ID | <mig9nf$gdh$2@speranza.aioe.org> |
| In reply to | #61687 |
Keith Thompson <kst-u@mib.org> wrote: (snip) > But fgets is not required to do so. > N1570 7.21.2: > Data read in from a text stream will necessarily compare equal to > the data that were earlier written out to that stream only if: > the data consist only of printing characters and the control > characters horizontal tab and new-line; no new-line character > is immediately preceded by space characters; and the last > character is a new-line character. Whether space characters > that are written out immediately before a new-line character > appear when read in is implementation-defined. That will, at least, be true writing to RECFM=F (fixed length records) on IBM mainframe systems, related to OS/360. I have known text editors that would remove trailing blanks on lines, such that they weren't written back out after editing. But that isn't the OS or C. -- glen
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-05-07 12:19 -0400 |
| Message-ID | <mig38i$pa0$1@dont-email.me> |
| In reply to | #61663 |
On 05/07/2015 01:04 AM, Lőrinczy Zsigmond wrote: > On 2015.05.06. 21:35, mathog wrote: >> If fgets reads a line larger than the buffer then the >> buffer will end with "...\0" instead of the usual >> "...\n\0". This is usually handled something like: > > The input might contain \0 so this method is unreliable. Use getline(3). fgets() is normally intended to be used on streams containing text, and that suggestion was aimed at the normal usage. If you use fgets() to read a stream that might contain '\0', you should read into a buffer containing no '\0' characters, so you can be sure that the last one you find in the buffer is the one placed there by fgets() to mark the end of the data transferred. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | mathog <dmathog@gmail.com> |
|---|---|
| Date | 2015-05-07 09:57 -0700 |
| Message-ID | <mig5hb$3gk$1@dont-email.me> |
| In reply to | #61692 |
James Kuyper wrote: > On 05/07/2015 01:04 AM, Lőrinczy Zsigmond wrote: >> On 2015.05.06. 21:35, mathog wrote: >>> If fgets reads a line larger than the buffer then the >>> buffer will end with "...\0" instead of the usual >>> "...\n\0". This is usually handled something like: >> >> The input might contain \0 so this method is unreliable. Use getline(3). I have seen files like that, actually. They sometimes show up in cases where people doing crazy things, packing multiple entries into a header line in a quasi-text data format. > > fgets() is normally intended to be used on streams containing text, and > that suggestion was aimed at the normal usage. If you use fgets() to > read a stream that might contain '\0', you should read into a buffer > containing no '\0' characters, so you can be sure that the last one you > find in the buffer is the one placed there by fgets() to mark the end of > the data transferred. My hack is ugly enough, having to set one byte in the buffer before each read. Very inefficient to have to write the entire buffer before each read. At that point one might as well go with fgetc(). I often wonder what they were thinking when they wrote fgets(). Its return value is pretty much wasted - it has all the bits a pointer uses but has only 1 bit of information. The end user never needs to use this pointer directly since the calling code always knows where the buffer started. Seems like a lot of pain could have been avoided if the function had been something like this instead: int figets(char *s, int size, FILE *stream, int *status); The value returned is the number of char's read, or 0, and status would have one of these bits set for problem reads: 1 error on read 2 eof 4 truncated read 8 buffer contains internal \0 Maybe not the last one, since that would require the function to test each byte, and in many instances it may just be doing some sort of memcpy(). One could test after the fact with if(strlen(buffer) != returned_length) A function like the hypothetical figets would save a lot of fgets() scaffold code for handling these sorts of events. Case in point, the topic of this thread. Regards, David Mathog
[toc] | [prev] | [next] | [standalone]
| From | Siri Cruz <chine.bleu@yahoo.com> |
|---|---|
| Date | 2015-05-07 11:31 -0700 |
| Message-ID | <chine.bleu-B62ADF.11305507052015@news.eternal-september.org> |
| In reply to | #61639 |
In article <midqe0$62n$1@dont-email.me>, mathog <dmathog@gmail.com> wrote:
> It should work when the input line is truncated. The problem is that,
> from my reading of the fgets man page, there is no guarantee that the
> library will not write something beyond the \0 in the buffer. I don't
> expect that would happen, but also do not see anything saying that it
> cannot.
If this is critical to you, use fgetline instead.
/*
Read and return the next line from input.
The line is mallocked; caller is responsibile for freeing.
The line ends in \n if the line from the input file did.
Returns NULL on EOF.
*/
char *fgetline (FILE *input) {
int c; char *line = NULL; int m = 0, n = 0;
while ((c=fgetc(input))!=EOF) {
if (c==0) abort();
if (n+1>=m) {m = 2*(n+1); line = realloc(line, m);}
if (!line) abort();
line[n++] = c;
if (c=='\n') break;
}
if (line) {line = realloc(line, n+1); line[n] = 0;}
return line;
}
--
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
'I desire mercy, not sacrifice.'
Icke's razor: Given two equally plausible explanations, choose the weirder.
That's People's Commissioner Siri Cruz now. Punch!
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-05-07 12:00 -0700 |
| Message-ID | <878ud0jjri.fsf@kst-u.example.com> |
| In reply to | #61707 |
Siri Cruz <chine.bleu@yahoo.com> writes:
> In article <midqe0$62n$1@dont-email.me>, mathog <dmathog@gmail.com> wrote:
>> It should work when the input line is truncated. The problem is that,
>> from my reading of the fgets man page, there is no guarantee that the
>> library will not write something beyond the \0 in the buffer. I don't
>> expect that would happen, but also do not see anything saying that it
>> cannot.
>
> If this is critical to you, use fgetline instead.
>
> /*
> Read and return the next line from input.
> The line is mallocked; caller is responsibile for freeing.
> The line ends in \n if the line from the input file did.
> Returns NULL on EOF.
> */
>
> char *fgetline (FILE *input) {
> int c; char *line = NULL; int m = 0, n = 0;
> while ((c=fgetc(input))!=EOF) {
> if (c==0) abort();
> if (n+1>=m) {m = 2*(n+1); line = realloc(line, m);}
> if (!line) abort();
> line[n++] = c;
> if (c=='\n') break;
> }
> if (line) {line = realloc(line, n+1); line[n] = 0;}
> return line;
> }
This doesn't check for allocation failures.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Siri Cruz <chine.bleu@yahoo.com> |
|---|---|
| Date | 2015-05-07 12:44 -0700 |
| Message-ID | <chine.bleu-F01A91.12435807052015@news.eternal-september.org> |
| In reply to | #61712 |
In article <878ud0jjri.fsf@kst-u.example.com>, Keith Thompson <kst-u@mib.org>
wrote:
> Siri Cruz <chine.bleu@yahoo.com> writes:
> > In article <midqe0$62n$1@dont-email.me>, mathog <dmathog@gmail.com> wrote:
> >> It should work when the input line is truncated. The problem is that,
> >> from my reading of the fgets man page, there is no guarantee that the
> >> library will not write something beyond the \0 in the buffer. I don't
> >> expect that would happen, but also do not see anything saying that it
> >> cannot.
> >
> > If this is critical to you, use fgetline instead.
> >
> > /*
> > Read and return the next line from input.
> > The line is mallocked; caller is responsibile for freeing.
> > The line ends in \n if the line from the input file did.
> > Returns NULL on EOF.
> > */
> >
> > char *fgetline (FILE *input) {
> > int c; char *line = NULL; int m = 0, n = 0;
> > while ((c=fgetc(input))!=EOF) {
> > if (c==0) abort();
> > if (n+1>=m) {m = 2*(n+1); line = realloc(line, m);}
> > if (!line) abort();
Ummm.......
> > line[n++] = c;
> > if (c=='\n') break;
> > }
> > if (line) {line = realloc(line, n+1); line[n] = 0;}
> > return line;
> > }
>
> This doesn't check for allocation failures.
--
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
'I desire mercy, not sacrifice.'
Icke's razor: Given two equally plausible explanations, choose the weirder.
That's People's Commissioner Siri Cruz now. Punch!
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-05-07 14:03 -0700 |
| Message-ID | <87vbg4hzgv.fsf@kst-u.example.com> |
| In reply to | #61718 |
Siri Cruz <chine.bleu@yahoo.com> writes:
> In article <878ud0jjri.fsf@kst-u.example.com>, Keith Thompson <kst-u@mib.org>
> wrote:
>> Siri Cruz <chine.bleu@yahoo.com> writes:
>> > In article <midqe0$62n$1@dont-email.me>, mathog <dmathog@gmail.com> wrote:
>> >> It should work when the input line is truncated. The problem is that,
>> >> from my reading of the fgets man page, there is no guarantee that the
>> >> library will not write something beyond the \0 in the buffer. I don't
>> >> expect that would happen, but also do not see anything saying that it
>> >> cannot.
>> >
>> > If this is critical to you, use fgetline instead.
>> >
>> > /*
>> > Read and return the next line from input.
>> > The line is mallocked; caller is responsibile for freeing.
>> > The line ends in \n if the line from the input file did.
>> > Returns NULL on EOF.
>> > */
>> >
>> > char *fgetline (FILE *input) {
>> > int c; char *line = NULL; int m = 0, n = 0;
>> > while ((c=fgetc(input))!=EOF) {
>> > if (c==0) abort();
>> > if (n+1>=m) {m = 2*(n+1); line = realloc(line, m);}
>> > if (!line) abort();
>
> Ummm.......
Ok, I didn't notice that. I'd suggest returning NULL or some other
error indication on an allocation failure.
Assigning the result of realloc() to the same pointer object you pass to
it means that if the reallocation fails, you've just lost the pointer
to the original data, which is still there. If your response is to
abort the program, that doesn't necessarily matter.
>> > line[n++] = c;
>> > if (c=='\n') break;
>> > }
>> > if (line) {line = realloc(line, n+1); line[n] = 0;}
And this allocation is not checked.
>> > return line;
>> > }
>>
>> This doesn't check for allocation failures.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Siri Cruz <chine.bleu@yahoo.com> |
|---|---|
| Date | 2015-05-07 15:28 -0700 |
| Message-ID | <chine.bleu-9ACF93.15280007052015@news.eternal-september.org> |
| In reply to | #61727 |
In article <87vbg4hzgv.fsf@kst-u.example.com>, Keith Thompson <kst-u@mib.org>
wrote:
> Siri Cruz <chine.bleu@yahoo.com> writes:
> > In article <878ud0jjri.fsf@kst-u.example.com>, Keith Thompson
> > <kst-u@mib.org>
> > wrote:
> >> Siri Cruz <chine.bleu@yahoo.com> writes:
> >> > In article <midqe0$62n$1@dont-email.me>, mathog <dmathog@gmail.com>
> >> > wrote:
> >> >> It should work when the input line is truncated. The problem is that,
> >> >> from my reading of the fgets man page, there is no guarantee that the
> >> >> library will not write something beyond the \0 in the buffer. I don't
> >> >> expect that would happen, but also do not see anything saying that it
> >> >> cannot.
> >> >
> >> > If this is critical to you, use fgetline instead.
> >> >
> >> > /*
> >> > Read and return the next line from input.
> >> > The line is mallocked; caller is responsibile for freeing.
> >> > The line ends in \n if the line from the input file did.
> >> > Returns NULL on EOF.
> >> > */
> >> >
> >> > char *fgetline (FILE *input) {
> >> > int c; char *line = NULL; int m = 0, n = 0;
> >> > while ((c=fgetc(input))!=EOF) {
> >> > if (c==0) abort();
> >> > if (n+1>=m) {m = 2*(n+1); line = realloc(line, m);}
> >> > if (!line) abort();
> >
> > Ummm.......
>
> Ok, I didn't notice that. I'd suggest returning NULL or some other
> error indication on an allocation failure.
Since the source code is available (see above), it's easy to adapt to other
styles.
> Assigning the result of realloc() to the same pointer object you pass to
> it means that if the reallocation fails, you've just lost the pointer
> to the original data, which is still there. If your response is to
> abort the program, that doesn't necessarily matter.
>
> >> > line[n++] = c;
> >> > if (c=='\n') break;
> >> > }
> >> > if (line) {line = realloc(line, n+1); line[n] = 0;}
>
> And this allocation is not checked.
n+1 <= m. If n+1 = m, the line size will be unchanged. If n+1 < m, the line size
will shrink. If your realloc runs out of memory when not changing or shrinking a
block, I suggest getting another realloc.
--
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
'I desire mercy, not sacrifice.'
Icke's razor: Given two equally plausible explanations, choose the weirder.
That's People's Commissioner Siri Cruz now. Punch!
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web