On the development of C

J

jacob navia

Keith said:
jacob navia said:
Keith Thompson wrote: [...]
jacob's use of the word "lie" is, as usual, inexcusably rude, but
apart from that he has a valid point.
Well, but then you do not ask WHY Mr McIntyre is doing this?

No. I'm more interested in why you

Obviously if somebody says that MSVC supports C99
that is not a lie.

No.

It is an honest misunderstanding...
persist in throwing around the
word "lie" or "liar" after you've been told multiple times how
offensive it is.

So. Mr McIntyre says

MSVC supports C99

and I said that it is a lie. And YOU say that I am "offensive" because
I tell the truth, and get angry with me obviously.
> You accuse people of deliberately making false
statements with the intent of deceiving others.


Yes. When somebody says

MSVC supports C99

I answer that it is not true and that the person telling that is
telling lies.
You have no evidence
to support this, and you don't bother to ask for clarification before
making the accusation.

The evidence is the text of McIntyre

"MSVC supports C99"

as you noticed, that means

"MSVC supports the features of C99".
 
C

CBFalconer

jacob said:
.... snip ...

The operator overloading is only needed to make code like
Str[2] = 'a';
work, instead of forcing the user to write
strasgn(Str,2,'a');

I have rewritten the standard library string functions using
counted strings. Strcat replaces strcat, Strlen replaces
strlen, etc.

This is a marvellous illustration of wasted effort. Note:

#include <stdio.h>
char Str[200] = "nonsense";
...
Str[2] = 'a';
puts(Str);
...

should produce "noasense" on stdout.
 
K

Keith Thompson

jacob navia said:
Keith said:
jacob navia said:
Keith Thompson wrote: [...]
jacob's use of the word "lie" is, as usual, inexcusably rude, but
apart from that he has a valid point.
Well, but then you do not ask WHY Mr McIntyre is doing this?

No. I'm more interested in why you

Obviously if somebody says that MSVC supports C99
that is not a lie.

No.

It is an honest misunderstanding...
persist in throwing around the
word "lie" or "liar" after you've been told multiple times how
offensive it is.

So. Mr McIntyre says

MSVC supports C99

and I said that it is a lie. And YOU say that I am "offensive" because
I tell the truth, and get angry with me obviously.

You don't even consider the possibility of an honest mistake. You
assume that any false statement made by someone you personally dislike
must be a deliberate lie.

I'll let Mark speak for himself, if he chooses to do so (though I'll
certainly understand if he wants no further part of this thread).
 
J

jacob navia

I've never seen a "list" interface for C that wasn't more work and
trouble to use than just doing it myself.

Yes. then you do it yourself AGAIN.

And since you are using the library xxx, the developer of that
library uses ALSO a list, but instead of your

typedef struct taglist { void * Data; struct taglist *Next;} MYLIST;

THAT guy has

typedef struct taglist { struct taglist *Next; void *Data; } HISLIST;

so, you write

HISLIST *ConvertMyListToHisList(MYLIST *in);

GREAT!

And you spend hours debugging that, only to find out
that HISLIST has a bug, because it was never well tested.

And yours is buggy too.

GREAT!

Isn't the task of a STANDARD to promote programs that work well with
each other?

A STANDARD allows people to communicate. I can speak to you because I
use the standard dictionary.

Mr Jones.

I am very sad that this attitude is the attitude of a member of our
STANDARDS committee!

Please think this over.
 
J

jacob navia

Not necessarily, the code may not run with any kind of elevated
privileges or only be used internally, in which case there's little to
no benefit to fixing the vulnerability.

Yes, it is not so bad. Let's keep gets().

Why bother?
 
C

CBFalconer

jacob said:
.... snip ...

There are absolutely no new language features in C99. True,
boolean and complex types were added, but I am not impressed
really. The new keyword "restrict" was added. Other syntax sugar
in structure initialization and we are done. That's really no
new development, even if they are more than just cosmetic changes.

.... snip 150 odd lines of very little ...

And why should there be 'new features'. Do you require them to
make new compilers incompatible with older code? The sort of
features added in C99 do not (in general) make older code invalid.
This actually requires care. It is not intended to 'impress'
anyone.

Also, you may wish to read up on the changes installed in C99.
 
C

CBFalconer

Mark said:
jacob navia wrote:
.... snip ...


I hesitate to point it out but this is a deeply disingenuous
statement, given that a decade has past since C99 was published,
and many years ago both organizations added some but not all
features of C99 to their suites. gcc is close to claiming C99
conformance. MSVC isn't likely to, but does support much of C99.
Sure they're not doing much development *now* - but thats because
once you've implemented what you need to, there's nothing to do.

I suspect that is because they can no longer charge excessive
dollars and other currency for new versions, so there is no real
return. The only noticeable changes are to the library, and are
designed to make it incompatible with the ISO standard.
 
C

CBFalconer

jacob said:
.... snip ...

Yes, the regulars are ALWAYS complaining the eliminating gets()
would affect "millions of lines of code". Here you join Gwyn and
many others (CBFalconer for instance).

But you get the facts wrong:

(1) gets() is not used a lot.
(2) If it gets (no pun intended) used, it would be anyway better
to rewrite that code...

No, you have the conclusions wrong. Your facts (above) are fine.
However, deleting gets would make all code that already uses it,
regardless of safety, invalid.
 
C

CBFalconer

jacob said:
.... snip ...

If we had a STANDARD interface for lists, we could always use the
same and be done with it.

Do you find lists so complicated that you have problems writing the
20 or so lines that present a standard interface? I suggest you
start with:

typedef struct listnodeptr {
void *datum;
struct listnodeptr *next;
} *listnodeptr;

and put that in .h file. You may wish to add other things.
 
R

robertwessel2

Keith said:
jacob navia said:
Keith Thompson wrote: [...]
jacob's use of the word "lie" is, as usual, inexcusably rude, but
apart from that he has a valid point.
Well, but then you do not ask WHY Mr McIntyre is doing this?
No.  I'm more interested in why you

Obviously if somebody says that MSVC supports C99
that is not a lie.

No.

It is an honest misunderstanding...
persist in throwing around the
word "lie" or "liar" after you've been told multiple times how
offensive it is.  

So. Mr McIntyre says

MSVC supports C99

and I said that it is a lie. And YOU say that I am "offensive" because
I tell the truth, and get angry with me obviously.

 > You accuse people of deliberately making false
statements with the intent of deceiving others.  

Yes. When somebody says

MSVC supports C99

I answer that it is not true and that the person telling that is
telling lies.


The issue is not that the person making the claim is incorrect or that
the claim is in error (obviously they are), it's the use of the term
"lie," which in English has a definite implication of deliberate
dishonesty. If I accidentally give you incorrect directions to some
place, that's an error. If I deliberately give you incorrect
directions because I'm a jerk and will be amused by the inconvenience
this causes you, that's a lie.

From dictionary.com:

lie - a false statement made with deliberate intent to deceive; an
intentional untruth; a falsehood.
 
C

CBFalconer

George said:
jacob navia wrote:
.... snip ...


I think something like this is needed. Every program seems to
have its own linked lists, or double-linked lists, or hash
tables. They are often poorly implemented too. The list
solution could be resolved, but hash tables I don't think could
adequately be resolved.

Hash tables are too general a problem to solve in C though.
What do I mean by that? Each hash table has a pattern it will
be optimal for with regard to its specific hashing algorithm and
growth factors, but the hash for pointers in not the ideal has
for general strings. Different data requires a slightly different
data structure at times. Do you enlarge the table at some point,
or keep the number of buckets fixed? This will influence the API
from the caller's perspective, and the scalability of the design.
Do you shrink the table when the total number of used buckets
falls, or keep a high water mark? Different data sets require
different behavior for the optimal solution.

I think that, if you take a look, my hashlib meets all of your
objections. It is written in purely standard C, so is portable
anywhere. It can handle arbitrary data objects. The hash
function(s) are set by the user, although a default is provided.
It automatically adjusts its size. It is compact. For complete
source, some applications, and a testing program, see:

<http://cbfalconer.home.att.net/download/hashlib.zip>
 
U

user923005

Not necessarily, the code may not run with any kind of elevated
privileges or only be used internally, in which case there's little to
no benefit to fixing the vulnerability.

I agree that the reward has to be worth as much as the risk/cost.
But the potential cost is extremely high (e.g. destruction of the
corporation -- even destruction of *all* corporations).
The probability may be low, but are you sure that the code will never
be executed by someone with malevolent intent (even someone within the
corporation that is using it?)

The use of gets() is not likely to cause a problem. But when it does
cause a problem it can be the technological equivalent of an atom
bomb. Are we comfortable with atom bombs sitting around that are very
unlikely to go off?

If everyone in the world never had a bad intention, we probably would
not have to worry about gets() at all. After all, accidental buffer
overflow in gets() is likely only to cause a crash but not execution
of malevolent code. It is the deliberate use of gets() with intent of
harm that must be guarded against and I do not think we can know that
all persons with access to code that calls gets() will not have bad
intentions.

It is shocking to me that the ANSI/ISO committee has not removed gets
() from the standard C library.
 
C

CBFalconer

user923005 said:
.... snip ...

It is shocking to me that the ANSI/ISO committee has not removed
gets () from the standard C library.

If you develop a time-machine you might keep it out of C89, K&R II,
and K&R I. :)
 
C

CBFalconer

jacob said:
.... snip ...

Yes. When somebody says

MSVC supports C99

I answer that it is not true and that the person telling that is
telling lies.

And when somebody says: "lcc-win32 supports C99" I answer that it
is not true and that the person telling that is telling lies.
 
B

Bartc

CBFalconer said:
No problem. You may not have noticed that malloc requires a
parameter specifying the size of the object to be created. All the
user has to do is remember that value.

Sure. But the value has already been stored and if there are millions of
malloc pointers to be managed, the programmer now also has the headache of
storing the sizes?

Plus rewriting a few thousand functions that take pointer parameters, to
allow room for the size parameter the caller now has to provide.

You don't think it's a good a idea for the odd function that wants to, to
interrogate the memory system for the end-limit of a pointer that's been
passed to it? This way there is little the rest of the application has to
do, and the application will still work on systems without this extension.

It might even help in extending the life of gets() by making it safer.

Yes. A nuisance, compared to the simplicity of Pascal, but usable.

C's types /are/ getting a little out of hand.
Absolutely. If you want another type, supply the code library to
handle it.

Better to have standardised libraries, and to have proper language support
(with operators and so on) for them.
 
B

Bartc

CBFalconer said:
jacob said:
... snip ...

The operator overloading is only needed to make code like
Str[2] = 'a';
work, instead of forcing the user to write
strasgn(Str,2,'a');

I have rewritten the standard library string functions using
counted strings. Strcat replaces strcat, Strlen replaces
strlen, etc.

This is a marvellous illustration of wasted effort. Note:

#include <stdio.h>
char Str[200] = "nonsense";
...
Str[2] = 'a';
puts(Str);
...

should produce "noasense" on stdout.

I think Str above is of a counted string type, not a C string. So standard C
[] indexing won't work because Str is not an array. The overloading would
allow normal array indexing on such a string type.

Counted strings with dynamic bounds and automatic memory management would
have a huge benefit.

In this case the wasted effort effort is by numbers of C programmers, if
they are using the language at a slightly higher application level than it
they should, continually messing about with low level string and memory
handling.

Or, even if they are using libraries for this, the libraries are going to be
kludgy to use without core language support.
 
K

Keith Thompson

Bartc said:
Sure. But the value has already been stored and if there are millions of
malloc pointers to be managed, the programmer now also has the headache of
storing the sizes?

Plus rewriting a few thousand functions that take pointer parameters, to
allow room for the size parameter the caller now has to provide.

You don't think it's a good a idea for the odd function that wants to, to
interrogate the memory system for the end-limit of a pointer that's been
passed to it? This way there is little the rest of the application has
to do, and the application will still work on systems without this
extension.

It might even help in extending the life of gets() by making it safer.

How would that make gets() safer? Should this new size function work
on pointers that weren't returned by malloc()?

char *p = malloc(42);
/* alloc_size(p) == 42 */

char *q = "Not allocated by malloc";
/* alloc_size(q) == ??? */

I would assume that, if such a function were defined, calling with a
pointer that wasn't returned by malloc and friends would invoke
undefined behavior.

And there are some other questions that would have to be answered.
Does it give you the size you requested (which a current allocator
might not remember), or the size that was actually allocated (which is
likely to be larger than what was requested)?

An implementation has to maintain *some* size information, so
realloc() knows how much to copy. But it's likely that adding an
alloc_size() function would require some implementations to maintain
information that they don't currently store.
 
B

Bartc

Keith Thompson said:
How would that make gets() safer? Should this new size function work
on pointers that weren't returned by malloc()?

char *p = malloc(42);
/* alloc_size(p) == 42 */

char *q = "Not allocated by malloc";
/* alloc_size(q) == ??? */

I would assume that, if such a function were defined, calling with a
pointer that wasn't returned by malloc and friends would invoke
undefined behavior.

Let's say the return from such a function is NULL for a value not part of
any malloc memory, such as addresses of static and frame data.

The gets() implementation which gets a non-NULL value from alloc_size can
then test against the limit (I had in mind the address of the end of the
allocated block), and prevent buffer overflows.

If it gets a NULL value, then it can work as before. So gets() would be safe
only when used with allocated memory.
And there are some other questions that would have to be answered.
Does it give you the size you requested (which a current allocator
might not remember), or the size that was actually allocated (which is
likely to be larger than what was requested)?

An implementation has to maintain *some* size information, so
realloc() knows how much to copy. But it's likely that adding an
alloc_size() function would require some implementations to maintain
information that they don't currently store.

All minor details... Ideally alloc_size or alloc_end would only be used in
libraries that know they are available and give useful results.
 
D

Dik T. Winter

> On Mar 10, 9:51 am, (e-mail address removed) wrote: ....
>
> I would argue that in view of the seriousness of the defect (it is a
> well known exploit) any use of gets() in commercial code *must* be
> fixed or the code vendor is negligent.

And that depends entirely on how gets is used and in what kind of programs.
If gets is *only* used in an interface between two programs I see no
problem in using it. It only becomes a problem when the program using
gets can also be used independent from other programs.

What would be the exploit in a program that reads a log-file, uses gets
to read the lines and displays statistics about the input? I see *no*
way for an exploit in such a program.
 
D

Dik T. Winter

>
> Yes, I think a few do. They don't, so far as I can tell, dispute that
> it should be used only rarely if at all, but they do dispute that it
> should be removed.

Indeed. i do use it quite a lot. But the program I write that use it are
used with known input, they are not otherwise available. If someone would
wish to use those programs where the input does not follow the rules the
output would be gibberish.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top