Dangerous convertion?

M

mark

Hello Friends ~~

I want to convert CString to LPBYTE like
LPBYTE lpByte = (BYTE*)(LPCTSTR)cstring;
is it very dangerous to do that?

Thanks.
 
N

Nick Keighley

mark said:
[...]
I want to convert CString to LPBYTE like
LPBYTE lpByte = (BYTE*)(LPCTSTR)cstring;
is it very dangerous to do that?

I guess your question is about Microsoft's C++ class library.
1. comp.lang.c++ is probably a better place to ask about that.

nonono!! As you say this is MS stuff. And therefore it is just
as off-topic on comp.lang.c++ asit is on comp.lang.c.

this is good advice. Then try a microsoft newsgroup
 
T

Tom St Denis

mark said:
[...]
I want to convert CString to LPBYTE like
LPBYTE lpByte = (BYTE*)(LPCTSTR)cstring;
is it very dangerous to do that?

I guess your question is about Microsoft's C++ class library.
1. comp.lang.c++ is probably a better place to ask about that.
2. If all else fails, read the manual.

http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx

The recommended method on the page is all that's wrong with msft...

CString aCString = "A string";
char myString[256];
strcpy(myString, (LPCTSTR)aString);

Can the kids spot the problem with this code?

Tom
 
J

James Kuyper

mark said:

According to my news server, the first response to your original message
was sent 8 minutes before you sent this one; but I suppose it might not
have propagated to your news server yet.

Usenet is not a chat room. Don't expect an immediate response. The best
response to your question might come from someone who might be asleep at
the time you sent it. As a general rule, wait at least 24 hours before
assuming that you've been ignored.
 
E

Eric Sosman

Tom said:
mark said:
[...]
I want to convert CString to LPBYTE like
LPBYTE lpByte = (BYTE*)(LPCTSTR)cstring;
is it very dangerous to do that?
I guess your question is about Microsoft's C++ class library.
1. comp.lang.c++ is probably a better place to ask about that.
2. If all else fails, read the manual.

http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx

The recommended method on the page is all that's wrong with msft...

CString aCString = "A string";
char myString[256];
strcpy(myString, (LPCTSTR)aString);

Can the kids spot the problem with this code?

Three undeclared identifiers and an executable statement
not inside a function block.
 
T

Tom St Denis

Tom said:
mark wrote:
[...]
I want to convert CString to LPBYTE like
LPBYTE lpByte = (BYTE*)(LPCTSTR)cstring;
is it very dangerous to do that?
I guess your question is about Microsoft's C++ class library.
1. comp.lang.c++ is probably a better place to ask about that.
2. If all else fails, read the manual.
http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx
The recommended method on the page is all that's wrong with msft...
CString aCString = "A string";
char myString[256];
strcpy(myString, (LPCTSTR)aString);
Can the kids spot the problem with this code?

     Three undeclared identifiers and an executable statement
not inside a function block.

Well letting aside it's not a complete program [I wouldn't fault msft
for that], it has the potential for a buffer overflow. But given you
didn't point that out I guess you didn't see that either...

I know this is clc and all, but come on, if you didn't see that...
 
B

Ben Bacarisse

Tom St Denis said:
Tom said:
On Aug 9, 7:16 am, Alexander Bartolich <[email protected]>
wrote:
mark wrote:
[...]
I want to convert CString to LPBYTE like
LPBYTE lpByte = (BYTE*)(LPCTSTR)cstring;
is it very dangerous to do that?
I guess your question is about Microsoft's C++ class library.
1. comp.lang.c++ is probably a better place to ask about that.
2. If all else fails, read the manual.

The recommended method on the page is all that's wrong with msft...
CString aCString = "A string";
char myString[256];
strcpy(myString, (LPCTSTR)aString);
Can the kids spot the problem with this code?

     Three undeclared identifiers and an executable statement
not inside a function block.

Well letting aside it's not a complete program [I wouldn't fault msft
for that], it has the potential for a buffer overflow.

But the buffer overflow possibility comes from what Eric pointed out.
if the example had been correct there would be no buffer overflow,
surely?
But given you
didn't point that out I guess you didn't see that either...

Did you spot the error that Eric pointed out by saying three (rather
than two) undeclared identifiers? If you did it seems odd to call the
problem "potential buffer overflow" though, of course, depending on
what aString is that is indeed a possibility.
I know this is clc and all, but come on, if you didn't see that...

I think he did.
 
E

Eric Sosman

Tom said:
Tom said:
On Aug 9, 7:16 am, Alexander Bartolich <[email protected]>
wrote:
mark wrote:
[...]
I want to convert CString to LPBYTE like
LPBYTE lpByte = (BYTE*)(LPCTSTR)cstring;
is it very dangerous to do that?
I guess your question is about Microsoft's C++ class library.
1. comp.lang.c++ is probably a better place to ask about that.
2. If all else fails, read the manual.
http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx
The recommended method on the page is all that's wrong with msft...
CString aCString = "A string";
char myString[256];
strcpy(myString, (LPCTSTR)aString);
Can the kids spot the problem with this code?
Three undeclared identifiers and an executable statement
not inside a function block.

Well letting aside it's not a complete program [I wouldn't fault msft
for that], it has the potential for a buffer overflow. But given you
didn't point that out I guess you didn't see that either...

I know this is clc and all, but come on, if you didn't see that...

Actually, what I failed to see was a *fourth* undeclared
identifier.

More seriously, I really, truly, have nothing but guesses
about what a `CString' may be, and no notion at all about the
meaning of `LPCTSTR'. I imagine they're C++-isms, but I know
nothing of C++; for whatever rational or irrational reason I
have succeeded in avoiding it just as I've avoided COBOL. If
I were interested in C++ (as many perfectly decent people are),
I'd be reading a C++ forum.
 
T

Tom St Denis

     More seriously, I really, truly, have nothing but guesses
about what a `CString' may be, and no notion at all about the
meaning of `LPCTSTR'.  I imagine they're C++-isms, but I know
nothing of C++; for whatever rational or irrational reason I
have succeeded in avoiding it just as I've avoided COBOL.  If
I were interested in C++ (as many perfectly decent people are),
I'd be reading a C++ forum.

Look, I'll break it down for you.

You should never use strcpy. Ever. It's a bad habit to get in.

Specially in a generic example showing how to copy from some type to
another because you know people will copy/paste it into their
applications.

My point was that leaving aside it's an incomplete program because
it's just a snippet, it shows that MSFT can't even write a damn string
copy example without doing it wrong.

BTW, the fact that it's a snippet and not a complete program is fine
IMHO. They're just showing how to use the API to perform an
operation, not how to write an entire program that does the
operation. So the fact that you're harping has motivations that elude
me.

Tom
 
E

Eric Sosman

Tom said:
You should never use strcpy. Ever. It's a bad habit to get in.

"Nonsense," "nonsense," and "too late."

My principal objection to strcpy() has nothing to do with
safety -- it's perfectly safe when "used as directed" -- but
the same objection I have to all forms of copying: Making a
copy of something you already know does not increase what is
known. It doesn't "advance the state of the computation," it
doesn't move the program closer to a goal or solution. When
I'm considering making a copy of something, I ponder whether
it's avoidable, whether the reason for copying is a good one.
Then if the reason is in fact good, I go ahead and make the
copy. Using strcpy(), if the thing being copied is a string,
because it's the right tool for the job. In responsible hands,
anyhow.
 
T

Tom St Denis

     "Nonsense," "nonsense," and "too late."

     My principal objection to strcpy() has nothing to do with
safety -- it's perfectly safe when "used as directed" -- but
the same objection I have to all forms of copying: Making a
copy of something you already know does not increase what is
known.  It doesn't "advance the state of the computation," it
doesn't move the program closer to a goal or solution.  When
I'm considering making a copy of something, I ponder whether
it's avoidable, whether the reason for copying is a good one.
Then if the reason is in fact good, I go ahead and make the
copy.  Using strcpy(), if the thing being copied is a string,
because it's the right tool for the job.  In responsible hands,
anyhow.

While I agree blanket "never use X" statements are nonsense, for
example, there are plenty of good uses for goto, strcpy is one that
just should be avoided.

It's the sort of bad habits that lead to other things like

- not checking parameters for validity
- not checking returns of malloc/calloc
- Not checking boundaries

How often does "malloc" really fail? So I guess checking the return
is just paranoia, etc. Sometimes not being lazy up front saves having
to go back and fix things later when it costs more to re-open the
code.

As for never having a use for making a copy, sometimes you're
transferring it from one structure to another and you're not at a
point to know where the pointers came from [stack, heap, auto, ???] so
you can't just copy the pointer.

Tom
 
T

Tom St Denis

Tom St Denis said:



Why not? And what would you recommend in its place?

strncpy and/or write your own that checks bounds.

Sure you *can* safely use strcpy, but it's a better habit to use
functions or write code that honour boundaries instead.

Tom
 
E

Eric Sosman

Tom said:
While I agree blanket "never use X" statements are nonsense, for
example, there are plenty of good uses for goto, strcpy is one that
just should be avoided.

It's the sort of bad habits that lead to other things like

- not checking parameters for validity
- not checking returns of malloc/calloc
- Not checking boundaries

Using strcpy() is the cause of these bad habits? Can you
quote any research to support this claim, or is it just one of
those "Stop, or you'll go blind" things?

The act of calling strcpy(), or even the intent thereof,
does not prompt me to swallow untrusted values from untrusted
sources. Nor does it influence me to omit tests for malloc()
failure. I *do* omit boundary checking, because there's no
need: I allocate sufficient space before copying, and once
the space is known to suffice there's no reason to check it.
How often does "malloc" really fail? So I guess checking the return
is just paranoia, etc. Sometimes not being lazy up front saves having
to go back and fix things later when it costs more to re-open the
code.

If this has anything at all to do with strcpy(), I am
unable to discern the connection.
As for never having a use for making a copy, sometimes you're
transferring it from one structure to another and you're not at a
point to know where the pointers came from [stack, heap, auto, ???] so
you can't just copy the pointer.

Yes, I know -- and I *did* say that copying is sometimes
necessary. Often you want a copy as an "initializer" for an
object you will then proceed to modify, but you'd like the
original to remain intact. Sometimes the original is itself
in jeopardy, sitting in a soon-to-vanish auto array or in a
soon-to-be-overwritten I/O buffer. And sometimes the point
of copying isn't to create redundant data but to rearrange,
as in sorting an array.

... and when a string is the thing you want to copy,
strcpy() is just the ticket.
 
K

Keith Thompson

Malcolm McLean said:
That's the wrong way of looking at it.

I think it's exactly the right way of looking at it.
As we all know by now, banks can fail. Say you've got an account at
the high street bank Boorcloys (fictitious name to avoid libel
charges). You withdraw a hundred pounds. What's the chance that your
transaction will fail because the bank has run out of money at that
point?
Millions of transactions a day are putting money into and out of the
bank, but eventually if withdrawls exceed deposits the bank will run
out of money. However this is highly embarrassing for the
government, so action is taken when banks start to fail too often -
more liquidity is injected. You can't have a situation where the
bank is failing every few days, because no-one would tolerate it.

Computers are not banks. The analagous statement that you can't
have a situation where the computer is failing every few days,
because no-one would tolerate it, is inconsistent with reality;
many computers *do* fail every few days, and people *do* tolerate it.

Failing to check malloc isn't like making a small withdrawal from
the bank, it's like the bank not bothering to check whether your
withdrawal is for more money than the bank has and ignoring the
consequences.

Adding code to check the result of malloc() is easier than computing
the probability that you can get away without checking it.
 
J

James Kuyper

Malcolm said:
That's the wrong way of looking at it.

As we all know by now, banks can fail. Say you've got an account at the high
street bank Boorcloys (fictitious name to avoid libel charges). You withdraw
a hundred pounds. What's the chance that your transaction will fail because
the bank has run out of money at that point?

The chance of your transaction failing can be estimated by methods
similar to those given above, if you decided to make your withdrawal at
the same time and for the same reason as a lot of other people. This is
called a "run on the bank". They used to be quite common, and the fact
that they're less common nowadays is because a great deal of effort has
been expended to set up a legal and regulatory system to prevent them
from happening. It's a primarily psychological issue that has no analog
in memory allocation.

On the other hand, banking is a bad analogy for a different reason. A
depositor has no right to remove any more money from a bank than the
current account balance, and interest rates give depositors an incentive
to take out no more than they actually need. In memory allocation,
here's no corresponding limit, and no corresponding incentive, to
restrain memory allocation requests. Therefore, the chance that a given
request might make the system will run out of memory can, to a rough
first approximation, be estimated by methods similar to those given above.
 
B

bartc

Keith Thompson said:
I think it's exactly the right way of looking at it.
Computers are not banks. The analagous statement that you can't
have a situation where the computer is failing every few days,
because no-one would tolerate it, is inconsistent with reality;
many computers *do* fail every few days, and people *do* tolerate it.

Failing to check malloc isn't like making a small withdrawal from
the bank, it's like the bank not bothering to check whether your
withdrawal is for more money than the bank has and ignoring the
consequences.

A better analogy is when you give the OS your own reserves of memory on
'deposit'. The OS then lends this memory to other, 'sub-prime' processes
which don't give it back (eg. badly written C applications). Then when you
want to make use of your own, personal memory, it's not available.
 
P

Phil Carmody

Tom St Denis said:
strncpy and/or write your own that checks bounds.

I view strncpy as a bigger threat to sanity than strcpy. It has
the illusion of taking a few extra things into account, but it
less efficient and invites pointers later in program execution
to wander off into UB-land. strlcpy is what strncpy should have
been.

Phil
 
E

Eric Sosman

Richard said:
[...]
As with any function, before calling it, one should ensure that it is
safe to call.

There's the crux, I think. memcpy() is unsafe if either
the source or destination is smaller than the count. longjmp()
is unsafe if the caller of setjmp() has already returned. Even
printf("Hello, %s!\n", placeName) is unsafe if there's no '\0'
within the memory pointed to by `placeName'.

"Safe when used as directed" (not intended as a plug for
"Ubik," but I can't see the phrase without recalling the book)
is the watchword. Ignoring the directions is what makes the
trouble: It's not aspirin's fault if you swallow an entire bottle
of the stuff. One could even argue, rather speciously, that
gets() is "safe when used as directed," but that the directions
("First, foretell the future") are not easy to follow.

As a defense against thoughtless programmers, the strlcpy()
and strlcat() functions (not part of the Standard library) show
promise, I think. They're not inherently safer than strcpy()
and strcat() -- it is *always* possible to pass an incorrect
output area size -- but at least it forces the T.P. to think
about that size, if only for a moment. Not enough in and of
itself, but a moment's thought is better than none.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top