Hi all,
I've been wondering whether this code would cause problems (as in a
potential crash). I've tested it on certain compilers and it did not
cause problems, but I'm still dubious. Note that I'm deliberately not
terminating source. Therefore strncpy will read into memory
unintentionally. This is not the way I write code - just pure
curiosity.
char from[10] = "";
strncpy( from, "0123456789", sizeof(source) );
char to[50] = "";
strncpy( to, from, sizeof(to) ); //Is this bad...?
//or
memcpy( to, from, sizeof(to) ); //Bad?
I can accept that overwriting memory should cause problems. Is
overreading just as bad.
Looking forward to your replies...
Werner
|
|
0
|
|
|
|
Reply
|
w_erasm (159)
|
8/22/2005 5:08:50 PM |
|
Werner wrote:
> I've been wondering whether this code would cause problems (as in a
> potential crash). I've tested it on certain compilers and it did not
> cause problems, but I'm still dubious. Note that I'm deliberately not
> terminating source. Therefore strncpy will read into memory
> unintentionally. This is not the way I write code - just pure
> curiosity.
>
> char from[10] = "";
> strncpy( from, "0123456789", sizeof(source) );
What is 'source'? Did you mean 'sizeof(from)'?
> char to[50] = "";
>
> strncpy( to, from, sizeof(to) ); //Is this bad...?
This is bad. You're accessing memory that doesn't necessarily exist
by reading beyond 'sizeof(from)'.
> //or
> memcpy( to, from, sizeof(to) ); //Bad?
Same difference.
> I can accept that overwriting memory should cause problems. Is
> overreading just as bad.
Yes.
V
|
|
0
|
|
|
|
Reply
|
v.Abazarov (13255)
|
8/22/2005 6:22:36 PM
|
|
application will crash (OS exception generated) when trying to access
not mapped pages. win32/intel platform have 4096 bytes page, how they
are allocated by heap manager - depends. it is low probability to hit
guarded page overeading few bytes on brain new heap.
try to overread few megabytes :).
anyway even tiny probabilities summed together makes code unstable.
|
|
0
|
|
|
|
Reply
|
forester (8)
|
8/22/2005 9:31:56 PM
|
|
Victor Bazarov wrote:
> Werner wrote:
> > I've been wondering whether this code would cause problems (as in a
> > potential crash). I've tested it on certain compilers and it did not
> > cause problems, but I'm still dubious. Note that I'm deliberately not
> > terminating source. Therefore strncpy will read into memory
> > unintentionally. This is not the way I write code - just pure
> > curiosity.
> >
> > char from[10] = "";
> > strncpy( from, "0123456789", sizeof(source) );
>
> What is 'source'? Did you mean 'sizeof(from)'?
>
> > char to[50] = "";
> >
> > strncpy( to, from, sizeof(to) ); //Is this bad...?
>
> This is bad. You're accessing memory that doesn't necessarily exist
> by reading beyond 'sizeof(from)'.
Since the contents of the from array is a null-terminated string, the
strncpy call in this example is OK. strncpy stops copying characters
when it reaches the terminating zero-valued character in from. To
handle the case when the characters in from are not null-terminated, I
would suggest replacing sizeof(to) with sizeof(from) as long as
sizeof(from) continues to be equal or less than sizeof(to).
But given that this is a C++ newsgroup, I would just replace the whole
program with one that uses std::strings and be free of these concerns.
>
> > //or
> > memcpy( to, from, sizeof(to) ); //Bad?
>
> Same difference.
This statement is worse than the previous statement, because unlike the
previous statement, this one is unsafe. Replacing strncpy with memcpy
removes the check on the number of bytes read from "from" and therefore
accesses unallocated memory addresses.
Greg
|
|
0
|
|
|
|
Reply
|
greghe (676)
|
8/23/2005 1:48:21 AM
|
|
Greg wrote:
> Victor Bazarov wrote:
>> Werner wrote:
>>> I've been wondering whether this code would cause problems (as in a
>>> potential crash). I've tested it on certain compilers and it did
>>> not cause problems, but I'm still dubious. Note that I'm
>>> deliberately not terminating source. Therefore strncpy will read
>>> into memory unintentionally. This is not the way I write code -
>>> just pure curiosity.
>>>
>>> char from[10] = "";
>>> strncpy( from, "0123456789", sizeof(source) );
>>
>> What is 'source'? Did you mean 'sizeof(from)'?
>>
>>> char to[50] = "";
>>>
>>> strncpy( to, from, sizeof(to) ); //Is this bad...?
>>
>> This is bad. You're accessing memory that doesn't necessarily exist
>> by reading beyond 'sizeof(from)'.
>
> Since the contents of the from array is a null-terminated string,
Uh... What? Come again? Where is the null terminator written there?
> [...]
>
>>
>>> //or
>>> memcpy( to, from, sizeof(to) ); //Bad?
>>
>> Same difference.
>
> This statement is worse than the previous statement, because unlike
> the previous statement, this one is unsafe. [..]
Both have undefined behaviour.
V
|
|
0
|
|
|
|
Reply
|
v.Abazarov (13255)
|
8/23/2005 2:24:41 AM
|
|
Greg wrote:
> Victor Bazarov wrote:
>> Werner wrote:
>>> I've been wondering whether this code would cause problems
>>> char from[10] = "";
>>> strncpy( from, "0123456789", sizeof(source) );
>>
>> What is 'source'? Did you mean 'sizeof(from)'?
>>
>>> char to[50] = "";
>>>
>>> strncpy( to, from, sizeof(to) ); //Is this bad...?
>>
>> This is bad. You're accessing memory that doesn't necessarily
>> exist by reading beyond 'sizeof(from)'.
>
> Since the contents of the from array is a null-terminated
> string,
But it isn't. The first strncpy cause 'from' to be filled
with 10 bytes, none of which is a null terminator.
|
|
0
|
|
|
|
Reply
|
oldwolf (2278)
|
8/23/2005 2:33:23 AM
|
|
Victor Bazarov wrote:
> Werner wrote:
> > I've been wondering whether this code would cause problems (as in a
> > potential crash). I've tested it on certain compilers and it did not
> > cause problems, but I'm still dubious. Note that I'm deliberately not
> > terminating source. Therefore strncpy will read into memory
> > unintentionally. This is not the way I write code - just pure
> > curiosity.
> >
> > char from[10] = "";
> > strncpy( from, "0123456789", sizeof(source) );
>
> What is 'source'? Did you mean 'sizeof(from)'?
Yes, sorry about that. I used to be called source...
>
> > char to[50] = "";
> >
> > strncpy( to, from, sizeof(to) ); //Is this bad...?
>
> This is bad. You're accessing memory that doesn't necessarily exist
> by reading beyond 'sizeof(from)'.
>
> > //or
> > memcpy( to, from, sizeof(to) ); //Bad?
>
> Same difference.
>
> > I can accept that overwriting memory should cause problems. Is
> > overreading just as bad.
>
> Yes.
>
> V
|
|
0
|
|
|
|
Reply
|
w_erasm (159)
|
8/23/2005 5:02:53 AM
|
|
forester wrote:
> application will crash (OS exception generated) when trying to access
> not mapped pages. win32/intel platform have 4096 bytes page, how they
> are allocated by heap manager - depends. it is low probability to hit
> guarded page overeading few bytes on brain new heap.
> try to overread few megabytes :).
>
> anyway even tiny probabilities summed together makes code unstable.
Thank you, question answered. Therefore read violations may cause
instabilities too - accessing unmapped memory. Furthermore when using
strncpy (or even more important, memcpy), care is to be taken to not
overread (that confirms my fears).
Kind regards,
Werner
|
|
0
|
|
|
|
Reply
|
w_erasm (159)
|
8/23/2005 5:22:53 AM
|
|
Greg wrote:
> Victor Bazarov wrote:
> > Werner wrote:
> > > I've been wondering whether this code would cause problems (as in a
> > > potential crash). I've tested it on certain compilers and it did not
> > > cause problems, but I'm still dubious. Note that I'm deliberately not
> > > terminating source. Therefore strncpy will read into memory
> > > unintentionally. This is not the way I write code - just pure
> > > curiosity.
> > >
> > > char from[10] = "";
> > > strncpy( from, "0123456789", sizeof(source) );
> >
> > What is 'source'? Did you mean 'sizeof(from)'?
> >
> > > char to[50] = "";
> > >
> > > strncpy( to, from, sizeof(to) ); //Is this bad...?
> >
> > This is bad. You're accessing memory that doesn't necessarily exist
> > by reading beyond 'sizeof(from)'.
>
> Since the contents of the from array is a null-terminated string,
NOT! I explicitly state that - see (NOTE).
> the
> strncpy call in this example is OK. strncpy stops copying characters
> when it reaches the terminating zero-valued character in from. To
> handle the case when the characters in from are not null-terminated, I
> would suggest replacing sizeof(to) with sizeof(from) as long as
> sizeof(from) continues to be equal or less than sizeof(to).
>
> But given that this is a C++ newsgroup, I would just replace the whole
> program with one that uses std::strings and be free of these concerns.
I assume then, that initialising std::string with a (const char*) with
the likes of <from> mentioned here above is OK? (NOT) Furthermore,
std::string cannot be used over processor/hardware/communication
boundaries. On the other hand, bytes are used over these boundaries.
This makes this question relevant on a C++ newsgroup. When performing
string manipulations with normal strings, I do use std::string.
Unfortunately not all strings are necessarily normal.
>
> >
> > > //or
> > > memcpy( to, from, sizeof(to) ); //Bad?
> >
> > Same difference.
>
> This statement is worse than the previous statement, because unlike the
> previous statement, this one is unsafe. Replacing strncpy with memcpy
> removes the check on the number of bytes read from "from" and therefore
> accesses unallocated memory addresses.
>
> Greg
Werner
|
|
0
|
|
|
|
Reply
|
w_erasm (159)
|
8/23/2005 5:35:11 AM
|
|
|
8 Replies
26 Views
(page loaded in 0.704 seconds)
|