Re: Buffer contents well-defined after fgets() reaches EOF ?

Liste des GroupesRevenir à cl c 
Sujet : Re: Buffer contents well-defined after fgets() reaches EOF ?
De : 643-408-1753 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.lang.c
Date : 14. Feb 2025, 18:22:59
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <20250214085627.815@kylheku.com>
References : 1 2 3 4 5 6 7 8 9
User-Agent : slrn/pre1.0.4-9 (Linux)
On 2025-02-14, Michael S <already5chosen@yahoo.com> wrote:
For starter, it looks like designers of fgets() did not believe in
their own motto about files being just streams of bytes.

They obviously did, which is exactly why they painstakingly preserved
the annoying line terminators in the returned data.

I don't know the history, so, may be, the function was defined this way
for portability with systems where text files have special record-based
structure?

You are sliding into muddled thinking here.

Then, everything about it feels inelegant.
A return value carries just 1 bit of information, success or failure.

Why would you assert a claim for which the standard library alone
is replete with counterexamples: getchar, malloc, getenv, pow, sin.

Did you mean /the/ return value (of fgets)?

So why did they encode this information in baroque way instead of
something obvious, 0 and 1?

Because you can express this concept:

   char work_area[SIZE];
   char *line;

   while ((line = fgets(work_area, sizeof work_area, stream)))
   {
      /* process line */
   }

The work_area just provides storage for the operation: line is the
returned line.

The loop would work even if fgets sometimes returned pointers that
are not the to first byte of work_area. It just so happens that
they always are.

It is meaningful to capture the returned value and work with
it as if it were distinct from the buffer.

Appending zero at the end also feels like a hack, but it is necessary
because of the main problem.

Appending zero is necessary so that the result meets the definition
of a C character string, without which it cannot be passed into
string-manipulating functions like strlen.

Home-grown functions that resemble fgets, but forget to add a null
byte sometimes, are the subjects of security CVEs.

And the main problem is: how the user is
supposed to figure out how many bytes were read?

Yes, how are they, if you take away the null byte?

In well-designed API this question should be answered in O(1) time.

In the context of C strings, that buys you almost nothing.
Even if you know the length, it's going to get measured numerous
more times.

It would be good if fgets nuked the terminating newline.

Many uses of fgets, after every operation, look for the newline
and nuke it, before doing anything else.

There is a nice idiom for that, by the way, which avoids an
temporary variable and if test:

   line[strcspn(line, "\n")] = 0;

strcspn(line, "\n") calculates the length of the prefix of line
which consists of non-newlines. That value is precisely the
array index of the first newline, if there is one, or else
of the terminating null, if there isn't a newline. Either
way, you can clobber that with a newline.

Once you see the above, you will never do this again:

   newline = strchr(line, '\n');
   if (newline)
     *newline = 0;

With fgets(), it can be answered in O(N) time when input is trusted to
contain no zeros.

We have decided in the C world that text does not contain zeros.

This has become so pervasive that the remaining naysayers can safely
regarded as part of a lunatic fringe.

Software that tries to support the presence of raw nulls in text is
actively harmful for security.

For instance, a piece of text with embedded nulls might have valid
overall syntax which makes it immune to an injection attack.

But when it is sent to another piece of software which interprets
the null as a terminator, the syntax is chopped in half, allowing
it to be completed by a malicious actor.

When input is arbitrary, finding out the answer is
even harder and requires quirks.

When input is arbitrary, don't use fgets? It's for text.

The function foo() is more generic than fgets(). For use instead of
fgets() it should be accompanied by standard constant EOL_CHAR.
>
I am not completely satisfied with proposed solution. The API is
still less obvious than it could be. But it is much better than fgets().

If last_c is '\n', you're still writing the pesky newline that
the caller will often want to remove.

Adding a terminating null and returning a pointer to that null
would be better.

You could then call the operation again with the returned dst
pointer, and it would continue extending the string,
without obliterating the last character.

I'm sure I've seen a foo-like function in software before:
reading delimited by an arbitrary byte, with length signaling.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

Date Sujet#  Auteur
9 Feb 25 * Buffer contents well-defined after fgets() reaches EOF ?83Janis Papanagnou
9 Feb 25 +- Re: Buffer contents well-defined after fgets() reaches EOF ?1Kaz Kylheku
9 Feb 25 +* Re: Buffer contents well-defined after fgets() reaches EOF ?79Andrey Tarasevich
9 Feb 25 i+* Re: Buffer contents well-defined after fgets() reaches EOF ?61Andrey Tarasevich
10 Feb 25 ii`* Re: Buffer contents well-defined after fgets() reaches EOF ?60Lawrence D'Oliveiro
10 Feb 25 ii `* Re: Buffer contents well-defined after fgets() reaches EOF ?59Andrey Tarasevich
10 Feb 25 ii  +* Re: Buffer contents well-defined after fgets() reaches EOF ?37Andrey Tarasevich
10 Feb 25 ii  i+* Re: Buffer contents well-defined after fgets() reaches EOF ?35Michael S
13 Feb 25 ii  ii`* Re: Buffer contents well-defined after fgets() reaches EOF ?34Tim Rentsch
14 Feb 25 ii  ii `* Re: Buffer contents well-defined after fgets() reaches EOF ?33Michael S
14 Feb 25 ii  ii  +* Re: Buffer contents well-defined after fgets() reaches EOF ?2Michael S
14 Feb 25 ii  ii  i`- Re: Buffer contents well-defined after fgets() reaches EOF ?1Kaz Kylheku
14 Feb 25 ii  ii  +* Re: Buffer contents well-defined after fgets() reaches EOF ?21Kaz Kylheku
14 Feb 25 ii  ii  i+* Re: Buffer contents well-defined after fgets() reaches EOF ?3Keith Thompson
14 Feb 25 ii  ii  ii`* Re: Buffer contents well-defined after fgets() reaches EOF ?2Kaz Kylheku
15 Feb 25 ii  ii  ii `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Michael S
14 Feb 25 ii  ii  i+* Re: Buffer contents well-defined after fgets() reaches EOF ?14Janis Papanagnou
15 Feb 25 ii  ii  ii+- Re: Buffer contents well-defined after fgets() reaches EOF ?1Michael S
15 Feb 25 ii  ii  ii`* Re: Buffer contents well-defined after fgets() reaches EOF ?12Michael S
16 Feb 25 ii  ii  ii +* Re: Buffer contents well-defined after fgets() reaches EOF ?7Janis Papanagnou
16 Feb 25 ii  ii  ii i+* Re: Buffer contents well-defined after fgets() reaches EOF ?3James Kuyper
16 Feb 25 ii  ii  ii ii+- Re: Buffer contents well-defined after fgets() reaches EOF ?1Kaz Kylheku
16 Feb 25 ii  ii  ii ii`- Re: Buffer contents well-defined after fgets() reaches EOF ?1Janis Papanagnou
16 Feb 25 ii  ii  ii i`* Re: Buffer contents well-defined after fgets() reaches EOF ?3Michael S
16 Feb 25 ii  ii  ii i `* Re: Buffer contents well-defined after fgets() reaches EOF ?2Janis Papanagnou
17 Feb 25 ii  ii  ii i  `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Michael S
16 Feb 25 ii  ii  ii `* Re: Buffer contents well-defined after fgets() reaches EOF ?4Kaz Kylheku
16 Feb 25 ii  ii  ii  +* Re: Buffer contents well-defined after fgets() reaches EOF ?2Michael S
16 Feb 25 ii  ii  ii  i`- Re: Buffer contents well-defined after fgets() reaches EOF ?1Janis Papanagnou
16 Feb 25 ii  ii  ii  `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Janis Papanagnou
15 Feb 25 ii  ii  i+- Re: Buffer contents well-defined after fgets() reaches EOF ?1Michael S
15 Feb 25 ii  ii  i`* Re: Buffer contents well-defined after fgets() reaches EOF ?2Michael S
16 Feb 25 ii  ii  i `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Janis Papanagnou
14 Feb 25 ii  ii  +* Re: Buffer contents well-defined after fgets() reaches EOF ?5Janis Papanagnou
14 Feb 25 ii  ii  i`* Re: Buffer contents well-defined after fgets() reaches EOF ?4James Kuyper
14 Feb 25 ii  ii  i `* Re: Buffer contents well-defined after fgets() reaches EOF ?3Janis Papanagnou
15 Feb 25 ii  ii  i  `* Re: Buffer contents well-defined after fgets() reaches EOF ?2Michael S
16 Feb 25 ii  ii  i   `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Janis Papanagnou
15 Feb 25 ii  ii  +* Re: Buffer contents well-defined after fgets() reaches EOF ?3Tim Rentsch
15 Feb 25 ii  ii  i`* Re: Buffer contents well-defined after fgets() reaches EOF ?2Michael S
19 Feb 25 ii  ii  i `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Tim Rentsch
21 Feb 25 ii  ii  `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Lawrence D'Oliveiro
15 Feb 25 ii  i`- Re: Buffer contents well-defined after fgets() reaches EOF ?1Tim Rentsch
10 Feb 25 ii  +- Re: Buffer contents well-defined after fgets() reaches EOF ?1Janis Papanagnou
10 Feb 25 ii  `* Re: Buffer contents well-defined after fgets() reaches EOF ?20Lawrence D'Oliveiro
10 Feb 25 ii   `* Re: Buffer contents well-defined after fgets() reaches EOF ?19Andrey Tarasevich
10 Feb 25 ii    `* Re: Buffer contents well-defined after fgets() reaches EOF ?18Lawrence D'Oliveiro
10 Feb 25 ii     `* Re: Buffer contents well-defined after fgets() reaches EOF ?17James Kuyper
11 Feb 25 ii      `* Re: Buffer contents well-defined after fgets() reaches EOF ?16Lawrence D'Oliveiro
11 Feb 25 ii       +* Re: Buffer contents well-defined after fgets() reaches EOF ?11James Kuyper
11 Feb 25 ii       i+- Re: Buffer contents well-defined after fgets() reaches EOF ?1Kaz Kylheku
11 Feb 25 ii       i`* Re: Buffer contents well-defined after fgets() reaches EOF ?9Lawrence D'Oliveiro
11 Feb 25 ii       i `* Re: Buffer contents well-defined after fgets() reaches EOF ?8James Kuyper
11 Feb 25 ii       i  +* Re: Buffer contents well-defined after fgets() reaches EOF ?3Lawrence D'Oliveiro
11 Feb 25 ii       i  i`* Re: Buffer contents well-defined after fgets() reaches EOF ?2James Kuyper
12 Feb 25 ii       i  i `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Lawrence D'Oliveiro
11 Feb 25 ii       i  `* Re: Buffer contents well-defined after fgets() reaches EOF ?4Keith Thompson
11 Feb 25 ii       i   `* Re: Buffer contents well-defined after fgets() reaches EOF ?3James Kuyper
12 Feb 25 ii       i    `* Re: Buffer contents well-defined after fgets() reaches EOF ?2Keith Thompson
18 Feb 25 ii       i     `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Tim Rentsch
11 Feb 25 ii       `* Re: Buffer contents well-defined after fgets() reaches EOF ?4Andrey Tarasevich
11 Feb 25 ii        +- Re: Buffer contents well-defined after fgets() reaches EOF ?1Andrey Tarasevich
11 Feb 25 ii        +- Re: Buffer contents well-defined after fgets() reaches EOF ?1Kaz Kylheku
13 Feb 25 ii        `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Tim Rentsch
9 Feb 25 i`* Re: Buffer contents well-defined after fgets() reaches EOF ?17Janis Papanagnou
9 Feb 25 i +* Re: Buffer contents well-defined after fgets() reaches EOF ?3Michael S
9 Feb 25 i i`* Re: Buffer contents well-defined after fgets() reaches EOF ?2Janis Papanagnou
10 Feb 25 i i `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Mark Bourne
9 Feb 25 i +* Re: Buffer contents well-defined after fgets() reaches EOF ?11Andrey Tarasevich
9 Feb 25 i i`* Re: Buffer contents well-defined after fgets() reaches EOF ?10Janis Papanagnou
10 Feb 25 i i `* Re: Buffer contents well-defined after fgets() reaches EOF ?9Keith Thompson
10 Feb 25 i i  `* Re: Buffer contents well-defined after fgets() reaches EOF ?8Janis Papanagnou
10 Feb 25 i i   `* Re: Buffer contents well-defined after fgets() reaches EOF ?7Keith Thompson
10 Feb 25 i i    `* Re: Buffer contents well-defined after fgets() reaches EOF ?6Janis Papanagnou
10 Feb 25 i i     `* Re: Buffer contents well-defined after fgets() reaches EOF ?5Keith Thompson
10 Feb 25 i i      +* Re: Buffer contents well-defined after fgets() reaches EOF ?3Janis Papanagnou
11 Feb 25 i i      i+- Re: Buffer contents well-defined after fgets() reaches EOF ?1Mark Bourne
11 Feb 25 i i      i`- Re: Buffer contents well-defined after fgets() reaches EOF ?1Kaz Kylheku
17 Feb 25 i i      `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Lawrence D'Oliveiro
10 Feb 25 i `* Re: Buffer contents well-defined after fgets() reaches EOF ?2Mark Bourne
11 Feb 25 i  `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Mark Bourne
10 Feb 25 `* Re: Buffer contents well-defined after fgets() reaches EOF ?2Ben Bacarisse
10 Feb 25  `- Re: Buffer contents well-defined after fgets() reaches EOF ?1Janis Papanagnou

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal