473,396 Members | 1,891 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Bug/Gross InEfficiency in HeathField's fgetline program

The function below is from Richard HeathField's fgetline program. For
some reason, it makes three passes through the string (a strlen(), a
strcpy() then another pass to change dots) when two would clearly be
sufficient. This could lead to unnecessarily bad performance on very
long strings. It is also written in a hard-to-read and clunky style.

char *dot_to_underscore(const char *s)
{
char *t = malloc(strlen(s) + 1);
if(t != NULL)
{
char *u;
strcpy(t, s);
u = t;
while(*u)
{
if(*u == '.')
{
*u = '_';
}
++u;
}
}
return
t;
}

Proposed solution:

char *dot_to_underscore(const char *s)
{
char *t, *u;
if(t=u=malloc(strlen(s)+1))
while(*u++=(*s=='.' ? s++, '_' : *s++));
return t;
}

Oct 7 '07
334 11240
"Richard" <rg****@gmail.comschrieb im Newsbeitrag
news:65************@news.individual.net...
"Joachim Schmitz" <no************@hp.comwrites:
>"¬a\/b" <al@f.gschrieb im Newsbeitrag
news:4j********************************@4ax.com.. .
>>In data Mon, 8 Oct 2007 00:16:07 +0200 (CEST), Antoninus Twink
scrisse:

The function below is from Richard HeathField's fgetline program. For
some reason, it makes three passes through the string (a strlen(), a
strcpy() then another pass to change dots) when two would clearly be
sufficient. This could lead to unnecessarily bad performance on very
long strings. It is also written in a hard-to-read and clunky style.

char *dot_to_underscore(const char *s)
{
char *t = malloc(strlen(s) + 1);
if(t != NULL)
{
char *u;
strcpy(t, s);
u = t;
while(*u)
{
if(*u == '.')
{
*u = '_';
}
++u;
}
}
return
t;
}

this is a big waste of vertical spaces
Scratch the 'big' and I agree. Saving 6 lines:

char *dot_to_underscore(const char *s)
{
char *t = malloc(strlen(s) + 1);
if(t != NULL){
char *u;
strcpy(t, s);
u = t;
while(*u){
if(*u == '.') *u = '_';

failed.

you cant easily see in a debugger if the assignment is done.
Well, OK, I saved one line too much then here. Make it a 2-liner and save
that line by char *u = t;

Bye, Jojo
Oct 9 '07 #101
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Ian Collins <ia******@hotmail.comwrote:
>Antoninus Twink wrote:
On 7 Oct 2007 at 22:55, Richard Heathfield wrote:
Antoninus Twink said:
It is also written in a hard-to-read and clunky style.
A matter of opinion. Which bit did you find hard to read?

The function is a completely trivial one, yet I can't see it all at once
in my editor without scrolling! Whitespace can help readability, but
excessive whitespace can reduce it, and at the same time give too much
weight to things that aren't important.
You must have a very small screen.

I don't think it's his _screen_ that's very small.

Richard
It is perfectly normal in many cases to debug on smaller displays over
remote lines or to debug in a small window or gdb buffer. The point
remains - smaller footprint is easier to read and follow.

3 clear lines is better than 20 clear lines any day of the week. Long
winded overly whitespaced code is bad.
Oct 9 '07 #102
Richard wrote:
....
I am astonished that people claiming to be professional programmers
could be in any way "confused" or "unsure" about your concise
replacement for Heathfield's version.

,----
| while(*u++=(*s=='.' ? '_' : *s))
| s++;
`----

I simply can not see the complication or the need to "analyse" this. Yes
if we were training in lesson 2 we might expand it out a little. but
only to the extent of removing the ?: usage to an if then else.
I have interviewed several dozen people for C programming positions
over the past 15 years. I've given every single one of them a simple
program to understand and explain and suggest improvements for. The
heart of that program was the following loop:

while(*p++ = *q++);

Only about half of them could even tell me correctly what that loop
does; not a single one has ever correctly explained how it does it.
The only person I've found who ever passed this test wasn't an
applicant but a co-worker, and she required a lot of hints before she
figured it out. The stumbling block for most of them is explaining how
the loop terminates. I've had to hire people who couldn't answer that
question, because better candidates weren't available. One of the most
recent applicants had 15 years(!) of recent C programming experience.
He didn't get the position, but not because of his lack of programming
skills, but only because he lacked several of the other important
qualifications for the position.

You may have had the privilege of working with more competent C
programmers than I have; but I would recommend not overestimating the
competence of the average C programmer. The code you cite has every
feature that made my test difficult for applicants, and adds to that a
use of the ?: operator.

While I can understand your code, even for a use-once-and-throw-away
program, I consider it excessively terse. For improved debugging, I'd
have used an if() statement rather than a ?: operator, so the if-
clause and the else-clause would occur on different lines that could
be selected by the debugger. Any decent compiler should produce the
same code, whether using if() or ?:. Yes, I do write my even use-once
programs anticipating that they may need to be debugged; they tend to
be written in a hurry without review, which means they're much more
likely to be buggy than my longer-lived code.

Oct 9 '07 #103
kuyper wrote:
Richard wrote:
...
>I am astonished that people claiming to be professional programmers
could be in any way "confused" or "unsure" about your concise
replacement for Heathfield's version.

,----
| while(*u++=(*s=='.' ? '_' : *s))
| s++;
`----

I simply can not see the complication or the need to "analyse" this.
Yes if we were training in lesson 2 we might expand it out a little.
but only to the extent of removing the ?: usage to an if then else.

I have interviewed several dozen people for C programming positions
over the past 15 years. I've given every single one of them a simple
program to understand and explain and suggest improvements for. The
heart of that program was the following loop:

while(*p++ = *q++);

Only about half of them could even tell me correctly what that loop
does; not a single one has ever correctly explained how it does it.
The only person I've found who ever passed this test wasn't an
applicant but a co-worker, and she required a lot of hints before she
figured it out. The stumbling block for most of them is explaining how
the loop terminates. I've had to hire people who couldn't answer that
question, because better candidates weren't available.
This is incredible!

<snip>
You may have had the privilege of working with more competent C
programmers than I have; but I would recommend not overestimating the
competence of the average C programmer. The code you cite has every
feature that made my test difficult for applicants, and adds to that a
use of the ?: operator.
I agree here. All other factors being equal clearer code is always
better. The issue though is, what's clear to one is obfuscation to
another.

<snip>

Oct 9 '07 #104
santosh said:
kuyper wrote:
<snip>
>>
[classic K&R strcpy loop snipped]
The stumbling block for most of them is explaining how
the loop terminates. I've had to hire people who couldn't answer that
question, because better candidates weren't available.

This is incredible!
No, he's right. Most C programmers are very, very bad at C. That's why it's
so important to write clear, simple code. Or at least, as clear and simple
as possible. No clearer, no simpler. :-)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 9 '07 #105
In article <q8******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>santosh said:
>kuyper wrote:
<snip>
>>>
[classic K&R strcpy loop snipped]
The stumbling block for most of them is explaining how
the loop terminates. I've had to hire people who couldn't answer that
question, because better candidates weren't available.

This is incredible!

No, he's right. Most C programmers are very, very bad at C. That's why it's
so important to write clear, simple code. Or at least, as clear and simple
as possible. No clearer, no simpler. :-)
I think Sturgeon's law applies here (as it does everywhere).

Oct 9 '07 #106
Malcolm McLean wrote:
"kuyper" <ku****@wizard.netwrote in message
The heart of that program was the following loop:

while(*p++ = *q++);

Only about half of them could even tell me correctly what that loop
does; not a single one has ever correctly explained how it does it.
It's what I call compileable gibberish. That's the sort of thing that gives
C a bad name.
I agree that it's an obscure idiom, but I wouldn't go so far as to
call it gibberish.

When I first used this test on an applicant, I expected that anyone
adequately qualified for an entry-level full-time C programming
position would be able to figure out how that idiom works, if given a
reasonable amount of time to do so. Furthermore, since the idiom is
explained in full detail in K&R, I expected that many of them would
actually recognize it. My expectations have lowered since then. I
still think that entry-level programmers should be able to figure this
out, even though I no longer expect them to be able to do so.

....
slightly more intuitive syntax to do it. Whilst you've got to assume that
the reader knows C, don't assume that he uses the language more than
occasionally.
The code I'm responsible for is intended to be read and modified only
by full-time professional C programmers. While the code is publicly
available, making it easily modifiable by people who aren't very
familiar with C is not a priority. It's not just a low priority; it's
completely missing from our list of priorities.

Making it easily modifiable by people who are very familiar with C is
one of our priorities. The depressing thing is how low a limit that
places on the complexity of the code.

Oct 9 '07 #107
Richard wrote:

[...]
The shorter more concise version would have got through any code review
long before the long winded one on any project I have worked on.
OP's version, would *never* have passed through a code review by me at
least. If I locate such *student code* in safety-critical and/or
security sensitive SW, the subcontractor has received their last
contract from "us", unless the junior programmer is taken off the
project and his code is rewritten.

In one funny case, the sub-contractor hired me to do their re-write, I
did pass it on code review thereafter! :)
--
Tor <torust [at] online [dot] no>

C-FAQ: http://c-faq.com/
Oct 10 '07 #108
On Tue, 09 Oct 2007 09:25:42 -0400, Richard <rg****@gmail.comwrote:
Mark McIntyre <ma**********@spamcop.netwrites:
>On Tue, 9 Oct 2007 14:20:41 +0200 (CEST), in comp.lang.c , Antoninus
Twink <no****@nospam.comwrote:
>>On 9 Oct 2007 at 9:34, Richard Heathfield wrote:
Antoninus Twink said:
If making the code harder to read in exchange for a small increasein
speed is bad,

Whether it is bad depends on the relative merits of performance and
clarity. I have already shown how I would have to use the program
24/7 for
almost half a century before your suggested change could save me so
much
as a nanosecond (once the time cost of making that change is factored
in),
and quite frankly I have better things to do with my life. So in this
case, the performance increase is meaningless, whereas the loss of
clarity
is significant.

But exactly the opposite is true - clarity is lost in *your* version,

You're wrong, but I don't expect you to believe me since you're
apparently a troll.

He most certainly is not.
I don't know how long you've been writing C, but I've been doing it for 20
years now.

If I were looking at that code with an eye to making it run as fast as
possible, I'd probably benchmark it written a couple of different ways.
I've done embedded systems for most of that 20 years, and have had
occasion to lock sections of code down in cache so that I could meet
performance metrics. I have no idea what your level of expertise is, but
from your arguments and the comments you make, I suspect it's not HPC.
>
The shorter more concise version would have got through any code review
long before the long winded one on any project I have worked on.
Not the case on any project I've been on. The use of the comma operator,
for one, would be seen as unwise, as well as assignment from the result of
the trinary operator.

You like terse code? Great. Use it. Then give it to a co-op or intern
or new grad and see how well he can read it. Odds are, they won't
understand that. I know I wouldn't hire you if I saw samples of your code
that looked like this everywhere.

From memory, I think the loop you posted was something like:
while (*u++ = (*s == '.' ? '_' : *s))
s++;

While it's short, it has at least 8 pieces of semantic information all
stuffed together. It's simply too much for the average C programmer to
take in at a glance.

On the other hand, the original code that the twink posted which he
claimed was from Heathfield, was easy to read because the meaning wasn't
all stuffed together.

Code the way you want, but please stop making these asinine assertions
about how idiomatic conciseness is the only way to write good code.
>>
>>And if you make simple things over-complicated, we might not
unreasonably suspect that you might make complicated things into a
complete mess.

Only if he changes his name to Antoninus Twink.

This is getting ridiculous.
You and twink pushed WAY past ridiculous a great number of posts in the
past.

Oct 10 '07 #109
On Mon, 08 Oct 2007 18:09:01 -0400, Richard Heathfield
<rj*@see.sig.invalidwrote:
John Bode said:

<snip>
>FWIW, after four runs on a 200 MB input string, RH's code is on
average 4% faster than AT's code.

I couldn't possibly comment. :-)
Your refusal to comment is a comment.
Oct 10 '07 #110
kuyper wrote:
Richard wrote:
...
>I am astonished that people claiming to be professional programmers
could be in any way "confused" or "unsure" about your concise
replacement for Heathfield's version.

,----
| while(*u++=(*s=='.' ? '_' : *s))
| s++;
`----

I simply can not see the complication or the need to "analyse" this. Yes
if we were training in lesson 2 we might expand it out a little. but
only to the extent of removing the ?: usage to an if then else.

I have interviewed several dozen people for C programming positions
over the past 15 years. I've given every single one of them a simple
program to understand and explain and suggest improvements for. The
heart of that program was the following loop:

while(*p++ = *q++);

Only about half of them could even tell me correctly what that loop
does; not a single one has ever correctly explained how it does it.
Recently I was involved in hiring a security officer with C programming
skills. Those who passed the initial screening, had at least a master
degree, but their experience varied a lot.

I ended up recommending the only one, with 0 work experience, who
admitted he didn't knew C well. The seniors, failed big time
implementing strncpy() on the blackboard. Very embarrassing.
--
Tor <torust [at] online [dot] no>

C-FAQ: http://c-faq.com/
Oct 10 '07 #111
Tor Rustad said:

<snip>
I ended up recommending the only one, with 0 work experience, who
admitted he didn't knew C well. The seniors, failed big time
implementing strncpy() on the blackboard. Very embarrassing.

Well, I'm game. Is this a blackboard? Why, yes, it is (although it's
actually white, but never mind).

Okay, it's an interview, so I'm not allowed to look stuff up. So, off the
top of my head, strncpy copies no more than n characters from s to t,
stopping at a null terminator if present, and zero-padding t. It then
returns t. I can't actually remember whether n is size_t or int. (It ought
to be size_t, of course, but then so ought the n in fgets.) So I'll risk
embarrassment by plumping for size_t.

#include <stddef.h>

char *strncpy(char *t, const char *s, size_t n)
{
char *u = t;
while(n 0 && *s != '\0')
{
*t++ = *s++;
--n;
}
while(n-- 0)
{
*t++ = '\0';
}
return u;
}

How did I do? Should I start blushing yet?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 10 '07 #112
In data Tue, 09 Oct 2007 14:17:59 +0530, santosh scrisse:
>¬a\/b wrote:
>In data Tue, 09 Oct 2007 10:06:04 +0200, ¬a\/b scrisse:

>>>#.2
.0: B*i='_'; #.1;
.1: ++i,j; .2: al=*j; al=='.'#.0; *i=al; al#.1

there is jmp more

#.2
.0: B*i='_'
.1: ++i,j; .2: al=*j; al=='.'#.0; *i=al; al#.1
#.2
..e: a=0; jmp exit /* here exit erron
..0: B*i='_'
..1: ++i; jz .e; ++j; jz .e; .2: al=*j; al=='.'#.0; *i=al; al#.1
>Your programs would be more readable if you decided to use either one of
l33t or brainf?uk.
i think that a routine has to deal with every input possible and
impossible: so have to detect all, and report its result

so no one have detect if the array is not a string

and so the 'brainfuk' language version is better that all your ones
all togheter :)
>To get you started:
<http://esoteric.voxelperfect.net/wiki/Brainf?ck>
<http://www.geocities.com/electrodruiduk/l33t.htm>
Oct 10 '07 #113

"Antoninus Twink" <no****@nospam.comwrote in message
news:sl*******************@nospam.com...
On 9 Oct 2007 at 20:40, Malcolm McLean wrote:
>It's what I call compileable gibberish. That's the sort of thing that
gives
C a bad name.

It's the sort of thing that attracted me to C in the first place. I
suspect I'm not alone.
To know the secret codes is a powerful motive. But it is the attiude of a
hacker, not a software engineer.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 10 '07 #114
Richard Heathfield wrote:
Tor Rustad said:

<snip>
>I ended up recommending the only one, with 0 work experience, who
admitted he didn't knew C well. The seniors, failed big time
implementing strncpy() on the blackboard. Very embarrassing.


Well, I'm game. Is this a blackboard? Why, yes, it is (although it's
actually white, but never mind).
The actual one, was white too. :)
Okay, it's an interview, so I'm not allowed to look stuff up. So, off the
top of my head, strncpy copies no more than n characters from s to t,
stopping at a null terminator if present, and zero-padding t. It then
returns t. I can't actually remember whether n is size_t or int. (It ought
to be size_t, of course, but then so ought the n in fgets.) So I'll risk
embarrassment by plumping for size_t.
First task indeed, would be to explain how this standard function works.
Knowing about the zero-padding, would give you a plus, but more
important would be if the candidate said something about the security
related usage pitfalls.

#include <stddef.h>

char *strncpy(char *t, const char *s, size_t n)
{
char *u = t;
while(n 0 && *s != '\0')
{
*t++ = *s++;
--n;
}
while(n-- 0)
{
*t++ = '\0';
}
return u;
}

How did I do? Should I start blushing yet?
Well done! :-) Obviously dealing with a senior C programmer here. I
would myself, rather have written aka

char *strncpy(char *dest, const char *src, size_t n)
{
char *d = dest;

[...]

return dest;

to make the code more readable, but by the first sight, I can't spot any
mistake in your code.

OTOH, you didn't provide pre/post-conditions via e.g. assert for the UB
cases. My follow-up question, would be to see some assert's checks for UB.

However, your C skills are sufficient, so we would rapidly move over to
other technical and relevant topics. :)

--
Tor <torust [at] online [dot] no>

C-FAQ: http://c-faq.com/
Oct 10 '07 #115
Tor Rustad said:

<snip>
Knowing about the zero-padding, would give you a plus, but more
important would be if the candidate said something about the security
related usage pitfalls.
There aren't any - strncpy is perfectly secure if used properly. If we're
allowed to use strncpy improperly, I'll get my coat.

<snip>
>char *strncpy(char *t, const char *s, size_t n)
<snip>
[...] I would myself, rather have written aka

char *strncpy(char *dest, const char *src, size_t n)
/nod - fair enough, although the convention of t = target, s = source is
relatively well-established. [Checks K&R2.] Except in K&R2. [Checks
Standard.] And except in the Standard. [Checks H&S4.] And except in H&S4.
[Checks D&D5.] And except in D&D5. In fact, it doesn't seem to be even
remotely well-established in the literature. Odd. I've seen it around
quite a lot. Maybe it's just me that uses that convention - but in *my*
code it's very we... hmmm... [Checks own code.] Er, no, in fact it's not
even all that common in my own code. But I do use it sometimes. Like, er,
for example, er, er... here!

<snip>
OTOH, you didn't provide pre/post-conditions via e.g. assert for the UB
cases. My follow-up question, would be to see some assert's checks for
UB.
Fair comment again. Clearly both pointers can be checked to ensure that
they are not null pointers. Whether n should be asserted to be 0 is
arguable.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 10 '07 #116
Richard Heathfield <r...@see.sig.invalidwrote:
[snip strncpy discussion]
OTOH, you didn't provide pre/post-conditions via e.g. assert
for the UB cases. My follow-up question, would be to see some
assert's checks for UB.

Fair comment again. Clearly both pointers can be checked to
ensure that they are not null pointers.
You could even test for overlapping buffers by testing each
destination byte prior to writing, but I personally wouldn't
bother with any assert, let alone that one.
Whether n should be asserted to be 0 is arguable.
Not really, since n == 0 is explicitly allowed.

--
Peter

Oct 11 '07 #117
Richard Heathfield <r...@see.sig.invalidwrote:
Tor Rustad said:
Knowing about the zero-padding, would give you a plus,
but more important would be if the candidate said
something about the security related usage pitfalls.

There aren't any -
That alone would be enough to put most people out of the
running in my book.
strncpy is perfectly secure if used properly.
This wouldn't help.

Risk assessment is about what might go wrong. More important
is how you mitigate identified risks. But you're not in a
good position to do that if you can't even identify them!

My next questions would be: "Can you think of any ways it
might be used improperly? What steps would you take to avoid
using it improperly?" My tone and body language would no doubt
give away that the previous response had placed the interviewee
on a precipice, assuming I hand't already thanked them for
their time. ;)

--
Peter

Oct 11 '07 #118
Peter Nilsson said:
Richard Heathfield <r...@see.sig.invalidwrote:
>Tor Rustad said:
Knowing about the zero-padding, would give you a plus,
but more important would be if the candidate said
something about the security related usage pitfalls.

There aren't any -

That alone would be enough to put most people out of the
running in my book.
That's why I made the remark about my coat.
>
>strncpy is perfectly secure if used properly.

This wouldn't help.
Despite being true. Truth often goes down badly at interviews. I once blew
an interview because I corrected the question (which was in the form of a
written program, in which they had voided main - had that been what they'd
wanted me to spot, I'd have been fine, but it turns out they thought main
really did return void).
Risk assessment is about what might go wrong. More important
is how you mitigate identified risks. But you're not in a
good position to do that if you can't even identify them!
The risk is not in strncpy. The risk is in picking the wrong programmer for
the job. If you pick someone who thinks otherwise, well, that's a risk
too.
My next questions would be: "Can you think of any ways it
might be used improperly?
And I'd answer "Yes, of course. I can think of a way a child's toy brick
can be used improperly, too. I don't think we're on the same page here."
What steps would you take to avoid using it improperly?"
My reply to this one would be "I wouldn't. Instead, I'd take steps to use
it properly, which means (a) never using it at all unless it really is the
right function for the job, which does happen but is vanishingly rare; and
(b) ensuring that there is sufficient storage to receive *all* the data I
intend to copy." I would not bother to mention anything about strings,
since I don't particularly think of strncpy as being a string function.
My tone and body language would no doubt
give away that the previous response had placed the interviewee
on a precipice,
My tone and body language would perhaps indicate that I was on the point of
setting off for home...
assuming I hand't already thanked them for their time. ;)
....and crossing the company off my list for wasting my time. :-)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 11 '07 #119
On Tue, 09 Oct 2007 20:22:08 -0400, in comp.lang.c , dbtid
<db****@nospam.gmail.comwrote:
>On Mon, 08 Oct 2007 18:09:01 -0400, Richard Heathfield
<rj*@see.sig.invalidwrote:
>John Bode said:

<snip>
>>FWIW, after four runs on a 200 MB input string, RH's code is on
average 4% faster than AT's code.

I couldn't possibly comment. :-)

Your refusal to comment is a comment.
"You might well think that; I couldn't possibly comment"

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Oct 11 '07 #120
Mark McIntyre said:

<snip>
Personally I consider it the height of arrogance to believe
unequivocally that you cannot possibly be wrong.
Strawman. I haven't claimed that either that I cannot possibly be wrong or
that I *believe* I cannot possibly be wrong (and in fact I don't think
either of these statements is true). If you want to debate with me, fine,
but why bother to argue against something I haven't actually said?
>
>>The point is that my mind is *my* mind,
not *your* mind. If you want to hire it, fine. But *changing* it is my
prerogative, just as changing your mind is your prerogative.

Ok, if you prefer - I prefer to train a smart junior who's not afraid
to admit he has stuff to learn,
That is your prerogative, obviously...
than to try to persuade a senior, who
thinks he knows it all, to accept that he doesn't. .
....but this is just a continuation of your strawman argument.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 12 '07 #121
Malcolm McLean said:

<snip>
We've got a buffer of 32 bytes, and we want to jam in a Christian name
and a surname.
The correct algorithm is

/* assume database field with no necessary nul */
strcnpy(buff, christian, 32);
strncpy(buff + strlen(christian), surname, 32 - strlen(christian));
Correct? Um, no, I don't think so.

Consider a system with 32-bit size_t, and a 40-byte Christian name. The
expression 32 - strlen(christian), on my system (which is fairly typical
of modern desktop sytems), evaluates to 4294967288, and you pass this
result to strncpy as a buffer limit, even though your buffer is only 32
bytes in size. That's one mother of a buffer overrun you have there.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 13 '07 #122
On Fri, 12 Oct 2007 21:11:36 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>Mark McIntyre said:

<snip>
>Personally I consider it the height of arrogance to believe
unequivocally that you cannot possibly be wrong.

Strawman.
Disingenuous attempt to divert attention from your error.

However this is entirely offtopic, and your responses are sadly
typical of your posts these days (ie happy to criticise others, but
instantly hyperdefensive when you're criticised, in fact everything
you complain about JN being) so I'm no sense continuing the debate.
>than to try to persuade a senior, who
thinks he knows it all, to accept that he doesn't. .

...but this is just a continuation of your strawman argument.
.... but your comment is merely a continuation of your arrogance.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Oct 13 '07 #123
Mark McIntyre said:
On Fri, 12 Oct 2007 21:11:36 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>>Mark McIntyre said:

<snip>
>>Personally I consider it the height of arrogance to believe
unequivocally that you cannot possibly be wrong.

Strawman.

Disingenuous attempt to divert attention from your error.
No, Mark, it really really isn't. But now I remember why I plonked you.
Time for me to re-enable that filter, I think.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 13 '07 #124
On Fri, 12 Oct 2007 14:19:16 -0700, in comp.lang.c , Keith Thompson
<ks***@mib.orgwrote:
>I think you're misunderstanding what Richard said.
I understand it perfectly in fact. He's saying that in a literal
sense, only he can change his mind, since there's no known
(nonphysical) mechanism to alter the stored memory patterns in
someone's btain.

However this quite clearly wasn't what the original comment related
to, and RJH knew that perfectly too. His response was in my opinion an
example of the sort of 'smug cleverness' that some people complain the
regulars here exhibit too much of.

I tire of seeing such smart-arse posts here, especially when the
poster, when called on it, attempts to actually justify the sort of
behaviour that would, IRL, get them disciplined, sacked or socked.
>As for strncpy() the function itself is not fundamentally unsafe. Its
semantics are precisely defined by the standard, including the
specification of cases where its behavior is undefined. In contrast
to gets(), it *can* be used safely in well-written code.
I agree.
>I strongly suspect that most uses of strncpy() in production code are
incorrect.
Well, 'most' is probably a bit strong - I'd go with 'many'.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Oct 13 '07 #125
On Sat, 13 Oct 2007 09:48:00 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>Mark McIntyre said:
>On Fri, 12 Oct 2007 21:11:36 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>>>Mark McIntyre said:

<snip>

Personally I consider it the height of arrogance to believe
unequivocally that you cannot possibly be wrong.

Strawman.

Disingenuous attempt to divert attention from your error.

No, Mark, it really really isn't. But now I remember why I plonked you.
*sigh*
>Time for me to re-enable that filter, I think.
Thats up to you. Perhaps if you stopped being so pompous and posting
such clever-clever smug posts, you'd be able to avoid that.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Oct 13 '07 #126
On Sat, 13 Oct 2007 09:48:00 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>No, Mark, it really really isn't. But now I remember why I plonked you.
Time for me to re-enable that filter, I think.
You might want to consider that my initial posts in this thread were
in your favour, and I've only commented adversely once you started
being a pompous twit.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Oct 13 '07 #127
¬a\/b wrote:
In data Sat, 13 Oct 2007 00:59:07 +0200, Tor Rustad scrisse:
>Richard Heathfield wrote:
[...]
>>I'm not entirely sure this can be done in standard C, at least not the
obvious way, although I'd be glad to be proved wrong.
Hmm.. haven't written it before, my first try would be:

/* pre-condition: checking for overlapped objects */
N = strlen(s);
for (i=0; i<N; i++) {
for (j=0; j<N; j++)
assert(t + i != s + j);
}

in the little i know overlap is not a problem in a x86 cpu
because the C instruction of assignament is done trhu a register or
trhu push pop; so where is the problem?
Assuming, you want the job, I say provide good answers to the questions
you get.

--
Tor <torust [at] online [dot] no>
Oct 14 '07 #128
Tor Rustad said:
Richard Heathfield wrote:
>Tor Rustad said:
>>[...] would you consider the OpenSSL maintainers sloppy and clueless?

If they've misused strncpy, I would consider them to be people capable
of misusing strncpy.

You did not answer the question.
It was a loaded question, so I engaged the safety catch.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 14 '07 #129
Richard Heathfield wrote:
Tor Rustad said:
[...]
>You did not answer the question.

It was a loaded question, so I engaged the safety catch.
I won this on a bluff then, they didn't misuse strncpy. :)

--
Tor <torust [at] online [dot] no>

C-FAQ: http://c-faq.com/
Oct 14 '07 #130
Tor Rustad said:
Richard Heathfield wrote:
>Tor Rustad said:

[...]
>>You did not answer the question.

It was a loaded question, so I engaged the safety catch.

I won this on a bluff then, they didn't misuse strncpy. :)
My answer was: "If they've misused strncpy, I would consider them to be
people capable of misusing strncpy." This is a statement of the form "if A
is true, then B is true", which doesn't enable us to deduce anything about
the state of B if A is false, so I don't quite see how you claim to have
"won" anything. Still, if *you* think you've won, that's fine by me.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 14 '07 #131
Joachim Schmitz said:
"¬a\/b" schrieb...
>Antoninus Twink scrisse:
<snip>
>>>
char *dot_to_underscore(const char *s)
{
char *t = malloc(strlen(s) + 1);

this goes in seg fault here if s==0
garbage in, garbage out.
This function is not even *called* unless s is non-null, so the situation
simply doesn't arise.

<snip>
However: I hope that RH free()s the malloc()ed memory later in his code,
I do indeed. And no, I didn't retrofit the free() as a result of your
query. It was already there. But your query did at least cause me to
check...
(as he claims not doing so to be sloppy style in another thread.)
....because we're all capable of being sloppy occasionally, aren't we? So it
was a worthwhile question to raise. Had I been sloppy, this paragraph
would have been an apology and an announcement of a URL to the fix. But I
hadn't, so it isn't.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 14 '07 #132
On Wed, 10 Oct 2007 21:34:35 +0100, Malcolm McLean wrote:
"Antoninus Twink" <no****@nospam.comwrote in message
news:sl*******************@nospam.com...
>On 9 Oct 2007 at 20:40, Malcolm McLean wrote:
>>It's what I call compileable gibberish. That's the sort of thing that
gives
C a bad name.

It's the sort of thing that attracted me to C in the first place. I
suspect I'm not alone.
To know the secret codes is a powerful motive. But it is the attiude of a
hacker, not a software engineer.
Context: while(*p++ = *q++);

Terseness - to a point - is a good thing. Some languages require
constructs such as var1 = var1 + 1, where C allows var1++, some require
var1 = var1 + var2 where C allows var1 += var2.

It doesn't take long, particularly when working with descriptive
identifiers, to learn how the terseness benefits coding; it doesn't take
long after that to learn terseness as a habit.

Sure, there are "more clear" ways to write the loop above; but that "more
clear" is largely dependent upon the relative skill of the coder. An
experienced C slinger will see the code as a gestalt and know exactly what
it does, the newbie may not - but the newbie isn't expected to grok a lot
of things, they're still learning.

It's a case of which is the more desirable goal - making things which
newbies have to learn, or making things easier and more efficient for
skilled coders?
Oct 14 '07 #133
[snips]

On Sat, 13 Oct 2007 19:32:09 +0200, ¬a\\/b wrote:
>>/* pre-condition: checking for overlapped objects */
N = strlen(s);
for (i=0; i<N; i++) {
for (j=0; j<N; j++)
assert(t + i != s + j);
}

in the little i know overlap is not a problem in a x86 cpu
because the C instruction of assignament is done trhu a register or
trhu push pop; so where is the problem?
Assuming that the code will execute only on x86 processors?
Oct 14 '07 #134

"Richard Heathfield" <rj*@see.sig.invalidwrote in message
...because we're all capable of being sloppy occasionally, aren't we? So
it
was a worthwhile question to raise. Had I been sloppy, this paragraph
would have been an apology and an announcement of a URL to the fix. But I
hadn't, so it isn't.
It is rather lackadaisical, Friday afternoon type code. Not for the reason
the OP claimed, but because it hardcodes the characters / strings to be
replaced, when they should be passed in by parameters.
However the job is only to replace one character with another in a string,
very much bread and butter programming, whilst the real interest of the
program is elsewhere. So the fuss is absurd.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 14 '07 #135
Peter Nilsson wrote:
Richard Heathfield <r...@see.sig.invalidwrote:
>>Tor Rustad said:
>>>Knowing about the zero-padding, would give you a plus,
but more important would be if the candidate said
something about the security related usage pitfalls.

There aren't any -

That alone would be enough to put most people out of the
running in my book.
>>strncpy is perfectly secure if used properly.

This wouldn't help.
[Interview]er: "Here is a wooden box to keep apples in.
What security flaws can you find in it?"
[Interview]ee (after a careful examination):
"There aren't any."
er: "You failed the interview. You didn't consider the risk
of someone breaking someone's skull with it."
ee: "That's not a proper use of the box! The box is
perfectly safe if used properly."
er: "That wouldn't help."
Oct 14 '07 #136
Peter Pichler <us****@pichler.co.ukwrites:
Peter Nilsson wrote:
>Richard Heathfield <r...@see.sig.invalidwrote:
>>>Tor Rustad said:

Knowing about the zero-padding, would give you a plus,
but more important would be if the candidate said
something about the security related usage pitfalls.

There aren't any -

That alone would be enough to put most people out of the
running in my book.
>>>strncpy is perfectly secure if used properly.

This wouldn't help.

[Interview]er: "Here is a wooden box to keep apples in.
What security flaws can you find in it?"
[Interview]ee (after a careful examination):
"There aren't any."
er: "You failed the interview. You didn't consider the risk
of someone breaking someone's skull with it."
ee: "That's not a proper use of the box! The box is
perfectly safe if used properly."
er: "That wouldn't help."
Analogies are slippery things. I could have gone this way:

er: "You failed the interview. You didn't consider the risk
of staking them too high and someone being hurt if they
fall over."
ee: "That's not a proper use of the box! The box is
perfectly safe if used properly. On page 206 of the manual
for these boxes it clearly says stack no more than 5 high."
er: "That wouldn't help."

I post this because I don't like analogies, not because it illustrates
my point of view! To come clean, I am probably somewhere in the
middle with a leaning towards the view that errors result from sloppy
programming (in general) as much as from misuse of specific "risky"
functions.

--
Ben.
Oct 15 '07 #137
Peter Pichler <us****@pichler.co.ukwrote:
Peter Nilsson wrote:
Richard Heathfield <r...@see.sig.invalidwrote:
>Tor Rustad said:

Knowing about the zero-padding, would give you a plus,
but more important would be if the candidate said
something about the security related usage pitfalls.

There aren't any -
That alone would be enough to put most people out of the
running in my book.
>strncpy is perfectly secure if used properly.
This wouldn't help.

[Interview]er: "Here is a wooden box to keep apples in.
What security flaws can you find in it?"
[Interview]ee (after a careful examination):
"There aren't any."
er: "You failed the interview. You didn't consider the risk
of someone breaking someone's skull with it."
ee: "That's not a proper use of the box! The box is
perfectly safe if used properly."
er: "That wouldn't help."
That's not a valid analogy. It is very unlikely that an apple crate will
be used for craniofractural purposes, but as we've seen often enough in
comp.lang.c, strncpy() _will_ be used the wrong way.

Richard
Oct 15 '07 #138
On Oct 13, 6:32 pm, "¬a\\/b" <a...@f.gwrote:
In data Sat, 13 Oct 2007 00:59:07 +0200, Tor Rustad scrisse:
[in conversation with Richard Heathfield]
>What about the non-trivial case, where buffers overlap?
I'm not entirely sure this can be done in standard C, at least not the
obvious way, although I'd be glad to be proved wrong.
Hmm.. haven't written it before, my first try would be:
/* pre-condition: checking for overlapped objects */
N = strlen(s);
for (i=0; i<N; i++) {
for (j=0; j<N; j++)
assert(t + i != s + j);
}

in the little i know overlap is not a problem in a x86 cpu
because the C instruction of assignament is done trhu a register or
trhu push pop; so where is the problem?
Perhaps in the fact that the code is required to run on a Frooble m57
processor? Where did x86 come in to this?

Oct 15 '07 #139
Peter Pichler wrote:
Peter Nilsson wrote:
>Richard Heathfield <r...@see.sig.invalidwrote:
>>Tor Rustad said:

Knowing about the zero-padding, would give you a plus,
but more important would be if the candidate said
something about the security related usage pitfalls.

There aren't any -
[...]
[Interview]er: "Here is a wooden box to keep apples in.
What security flaws can you find in it?"
[Interview]ee (after a careful examination):
"There aren't any."
er: "You failed the interview. You didn't consider the risk
of someone breaking someone's skull with it."

What has assets of national importance, in common with *apples*???

I be very surprised, if UK or US security professionals these days,
will hire people with such a complete lack of understanding of basic
security principles.

--
Tor <torust [at] online [dot] no>
Oct 15 '07 #140
[my final post here - promise!]

Richard Heathfield wrote:
Tor Rustad said:
>Richard Heathfield wrote:
>>Tor Rustad said:
[...]
>>>You did not answer the question.
It was a loaded question, so I engaged the safety catch.
I won this on a bluff then, they didn't misuse strncpy. :)

My answer was: "If they've misused strncpy, I would consider them to be
people capable of misusing strncpy." This is a statement of the form "if A
is true, then B is true", which doesn't enable us to deduce anything about
the state of B if A is false, so I don't quite see how you claim to have
"won" anything. Still, if *you* think you've won, that's fine by me.
If there was nothing to be afraid of, why did you take such extreme
safety measures then? In mathematical terms, I viewed your behavior as
"reductio ad absurdum". :)

In science, making statements that cannot be falsified, has *no value*.
So, how can your "no usage pitfalls with strncpy", be falsified by
measurement exactly?

Did you refer to your own C skill-level only?

By not making a stand, you lost.

--
Tor <torust [at] online [dot] no>
Oct 15 '07 #141
Tor Rustad <tor_rus...@hotmail.comwrote:
Richard Heathfield wrote:
What about the non-trivial case, where buffers overlap?
I'm not entirely sure this can be done in standard C, at
least not the obvious way, although I'd be glad to be proved
wrong.

Hmm.. haven't written it before, my first try would be:

/* pre-condition: checking for overlapped objects */
N = strlen(s);
for (i=0; i<N; i++) {
for (j=0; j<N; j++)
assert(t + i != s + j);

}
Slightly less Grossly InEfficient ;) ...

/* test: if n bytes starting at s
// overlaps n bytes starting at t
*/
int mem_overlap(const void *s, const void *t, size_t n)
{
const char *u, *v;
size_t m = n;
if (n == 0) return (s == t);
for (u = t; m--; u++) if (u == s) return 1;
for (v = s; n--; v++) if (v == t) return 1;
return 0;
}
/* test: if destination s
// overlaps source string t
*/
int str_overlap(const char *s, const char *t)
{
const char *u = t;
do { if (u == s) return 1; } while (*u++);
while (--u != t) if (++s == t) return 1;
return 0;
}

--
Peter

Oct 16 '07 #142
Tor Rustad said:
Peter Pichler wrote:
>Peter Nilsson wrote:
>>Richard Heathfield <r...@see.sig.invalidwrote:
Tor Rustad said:

Knowing about the zero-padding, would give you a plus,
but more important would be if the candidate said
something about the security related usage pitfalls.

There aren't any -

[...]
>[Interview]er: "Here is a wooden box to keep apples in.
What security flaws can you find in it?"
[Interview]ee (after a careful examination):
"There aren't any."
er: "You failed the interview. You didn't consider the risk
of someone breaking someone's skull with it."


What has assets of national importance, in common with *apples*???
Okay, let's try something oh so very different.

Interviewer: Here is St Edward's Crown, in which Queen Elizabeth II was
crowned in 1953. It is well over 400 years old, it is one of the UK's
crown jewels, and not only is it unquestionably an asset of national
importance in its own right, but also, when the Queen is wearing it, it
can be considered as a container for another asset of national importance
- i.e. the monarch's head. What security flaws can you find in it?
Interviewee (after a careful examination): There aren't any.
Interviewer: You failed the interview. You didn't consider the risk of
someone breaking someone's skull with it.

Better? (FCOL)
I be very surprised, if UK or US security professionals these days,
will hire people with such a complete lack of understanding of basic
security principles.
You have not demonstrated such a lack in your correspondents. I'm not quite
sure what you /have/ demonstrated (other than, perhaps, your own lack of
understanding of analogies).

The strncpy function does a simple task reasonably well. Yes, we all know
it has a lousy name, but apart from that it's a simple function, easy to
use properly. Yes, it's easy to use improperly too, but then so are lots
of C functions. All of them, really. And of course C operators are pretty
easy to misuse, as well. Er, so what? The mark of an anathematical
function is not that it can be used improperly, but that it cannot be used
properly.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 16 '07 #143
In data 15 Oct 2007 11:54:09 -0700, J. J. Farrell scrisse:
>On Oct 13, 6:32 pm, "¬a\\/b" <a...@f.gwrote:
>In data Sat, 13 Oct 2007 00:59:07 +0200, Tor Rustad scrisse:
[in conversation with Richard Heathfield]
>>What about the non-trivial case, where buffers overlap?
>I'm not entirely sure this can be done in standard C, at least not the
obvious way, although I'd be glad to be proved wrong.
>Hmm.. haven't written it before, my first try would be:
>/* pre-condition: checking for overlapped objects */
N = strlen(s);
for (i=0; i<N; i++) {
for (j=0; j<N; j++)
assert(t + i != s + j);
}
and if for some i t+i==0 ?
and if for some j s+j==0 ?

yes this goes in segfault for strlen() in the "s" case

why the string "t" has len == N? (like string "s" and if len of "t" is
many time less of N the above have zero sense because can detect a
overlap where there are no one)
>in the little i know overlap is not a problem in a x86 cpu
because the C instruction of assignament is done trhu a register or
trhu push pop; so where is the problem?

Perhaps in the fact that the code is required to run on a Frooble m57
processor? Where did x86 come in to this?
it is just an example. for me the problem could be implementig
somethig like below in your favorite cpu language (where in "b" and in
"k" there are the 2 arrays) a=1 all is ok, a=0 there is something
wrong

a=b: a==0#.e; #.1;
..0: ++a; jz .e;
..1: B*a#.0
c=a; c-=b;
r=k; r==0#.e; r+=c; jc .e; c=a; a=k; #.2;
/* jc means string not can be 0 anywhere
..e: a=0; #.3;
..2: a==b#.e; ++a; a<r#.2
++b; a=k; b<c#.2
a=1;
..3:

don't know if it has some meaning ....
i'm just a pirate :)
Oct 16 '07 #144
¬a\/b wrote:
In data 15 Oct 2007 11:54:09 -0700, J. J. Farrell scrisse:
>On Oct 13, 6:32 pm, "¬a\\/b" <a...@f.gwrote:
>>In data Sat, 13 Oct 2007 00:59:07 +0200, Tor Rustad scrisse:
[in conversation with Richard Heathfield]
[Re: implementing an equivalent of strncpy(t,s,n)]
....
>>>>>What about the non-trivial case, where buffers overlap?
I'm not entirely sure this can be done in standard C, at least not the
obvious way, although I'd be glad to be proved wrong.
Hmm.. haven't written it before, my first try would be:
/* pre-condition: checking for overlapped objects */
N = strlen(s);
This function doesn't require that the source be a null terminated
string. It could legally be a pointer to a character array of at least n
characters, that contains no null characters. If so, the strlen() call
will not terminate at the end of the array, so this code would have
undefined behavior. What is really needed can be written as follows:

for(N=0; N<n && s[N]; N++);

Alternatively,

void *end = memchar(s, '\0', n);
N = (end ? (char*)end - s : n);

which might be faster, depending about how poorly my loop is optimized,
and how well memchar() is optimized.
>>>for (i=0; i<N; i++) {
for (j=0; j<N; j++)
assert(t + i != s + j);
}

and if for some i t+i==0 ?
and if for some j s+j==0 ?
What is the problem that you see in that case? Null pointer values can
be compared for equality other pointer values, with well-defined
behavior. The problem that you could worry about is that t+i or s+j
might go more than one past the end of the array that they point into.

However, the implementor might as well assume that both t and s point
into sufficiently large arrays, since as far as I know there's no way to
test against the possibility that they don't.
yes this goes in segfault for strlen() in the "s" case
There's no guarantee in the C standard that it goes into segfault.
That's platform-dependent.
why the string "t" has len == N?
It doesn't matter to this function whether or not t points at a string,
much less what the length of that string is. All that matters is that t
must point at a position where you can write at least n characters with
defined behavior.
Oct 17 '07 #145
Mark McIntyre scribbled:
Personally I consider it the height of arrogance to believe
unequivocally that you cannot possibly be wrong.
Are you thoroughly confident that someone that believes unequivocally
that they cannot possibly be wrong has reached the height of arrogance?

Regards,
Orlando B. Salazar


Oct 17 '07 #146
In data Mon, 15 Oct 2007 18:23:54 -0700, Peter Nilsson scrisse:
>Tor Rustad <tor_rus...@hotmail.comwrote:
>Richard Heathfield wrote:
What about the non-trivial case, where buffers overlap?

I'm not entirely sure this can be done in standard C, at
least not the obvious way, although I'd be glad to be proved
wrong.

Hmm.. haven't written it before, my first try would be:

/* pre-condition: checking for overlapped objects */
N = strlen(s);
for (i=0; i<N; i++) {
for (j=0; j<N; j++)
assert(t + i != s + j);

}

Slightly less Grossly InEfficient ;) ...

/* test: if n bytes starting at s
// overlaps n bytes starting at t
*/
int mem_overlap(const void *s, const void *t, size_t n)
{
const char *u, *v;
size_t m = n;
if (n == 0) return (s == t);
for (u = t; m--; u++) if (u == s) return 1;
for (v = s; n--; v++) if (v == t) return 1;
return 0;
}

/* test: if n bytes starting at s
// overlaps n bytes starting at t
*/
/* assume a pointer has the same size of an int and one unsigned */
/* return 1 if error or overlap 0 otherwise */
int mem_overlap123(char* s, int n, char* t, int m)
{if(s==0|| t==0 || n<0 || m<0) return 0;

/* no array can have the address 0
if( ((int)s)>=0 &&((int)(s+n-1))<= 0) return 1;
if( ((int)t)>=0 &&((int)(t+n-1))<= 0) return 1;

if( ((int)s)<=0 &&((int)(s+n-1))>= 0) return 1;
if( ((int)t)<=0 &&((int)(t+n-1))>= 0) return 1;

/* s----- t------ || t----- s------*/
if( (unsigned)(s+n-1) < (unsigned) t) return 0;
if( (unsigned)(t+m-1) < (unsigned) s) return 0;
return 1;
}

not tested
how many errors do you see?
>
/* test: if destination s
// overlaps source string t
*/
int str_overlap(const char *s, const char *t)
{
const char *u = t;
do { if (u == s) return 1; } while (*u++);
while (--u != t) if (++s == t) return 1;
return 0;
}
Oct 17 '07 #147
"Tor Rustad" <to********@hotmail.comwrote in message
In science, making statements that cannot be falsified, has *no value*.
So, how can your "no usage pitfalls with strncpy", be falsified by
measurement exactly?
A hypothesis which is empirical in nature is stronger if it survives an
attempt at falsification. That's not the same thing as saying that every
statement in science must be falsifiable, or it has no value. A theorem, as
opposed to theory, cannot be falsified by experiment, for example, but
theorems are very useful to scientists.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
Oct 17 '07 #148

"Ben Bacarisse" <be********@bsb.me.ukwrote in message
>[Interview]er: "Here is a wooden box to keep apples in.
What security flaws can you find in it?"
[Interview]ee (after a careful examination):
"There aren't any."
er: "You failed the interview. You didn't consider the risk
of someone breaking someone's skull with it."
ee: "That's not a proper use of the box! The box is
perfectly safe if used properly."
er: "That wouldn't help."

Analogies are slippery things. I could have gone this way:

er: "You failed the interview. You didn't consider the risk
of staking them too high and someone being hurt if they
fall over."
ee: "That's not a proper use of the box! The box is
perfectly safe if used properly. On page 206 of the manual
for these boxes it clearly says stack no more than 5 high."
er: "That wouldn't help."

I post this because I don't like analogies, not because it illustrates
my point of view! To come clean, I am probably somewhere in the
middle with a leaning towards the view that errors result from sloppy
programming (in general) as much as from misuse of specific "risky"
functions.
You've got to have a degree of knowledge about the fruit industry before you
can say whether the box is dangerous.
For instance if the boxes look exactly like orgage boxes, which are
typically stacked ten high, then the fact that they will topple over if
stacked more than five is an obvious danger.
However if established practise in fruit warehouses is to stack boxes no
more than three high, and there is nothing about the apple boxes to suggest
that they are unusual, then it is not a safety risk. In fact we create a
safety risk by sticking a "stack no more than five high" label on it,
because it gets people out of the habit of observing notices.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 17 '07 #149
Malcolm McLean said:
"Tor Rustad" <to********@hotmail.comwrote in message
>In science, making statements that cannot be falsified, has *no value*.
So, how can your "no usage pitfalls with strncpy", be falsified by
measurement exactly?
A hypothesis which is empirical in nature is stronger if it survives an
attempt at falsification. That's not the same thing as saying that every
statement in science must be falsifiable, or it has no value. A theorem,
as opposed to theory, cannot be falsified by experiment, for example, but
theorems are very useful to scientists.
Theorems certainly /can/ be falsified (at which point they instantly stop
being theorems, because theorems are supposed to be true statements). For
example, Pythagoras's Theorem (which is a statement about Euclidean
geometry) is a theorem that can easily be falsified (if it is not true).
All you have to do is find a right triangle lying flat on the Euclidean
plane, such that the square of its hypotenuse is not equal to the sum of
the squares of the other two sides.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 17 '07 #150

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.