Do strong types, in this case char prevent buffer overflow?
char a[100]
char b[100]
strcpy(a,unk开发者_运维技巧nownFunction); // unknownFunction could overflow b
// since its length is unknown
strcpy(b,a); // can b still overflow a with its now,
// potentially overflowed size?
No. strcpy()
just keeps going until it finds a null-terminator ('\0'
). If b[]
doesn't contain one, it will just walk through random memory until it eventually finds one.
C does not have a strong type system.
C++ is somewhat stronger typed, but is not really a true strong type system, since it has reinterpret_cast
.
For a type system to prevent buffer overflow, the type information must either (1) denote an arbitrarily long string or (2) encode the buffer length in the type itself. Further, the type judgment system should ensure buffer-length to be less than or equal to for conversions.
Edit:
With some care, and neglecting the cast-tastic abilities of C++, you can write a "reasonably strong" no-overflow buffer class in C++. However, this is not strongly typed per the general definition of the term, since it is possible to attempt to access the buffer at an invalid point and still have it compile. Someone much better at templates than I might be able to write a truly template-typed SafeBuffer.
Here's my cut at it:
template<int Length>
class SafeBuffer
{
unsigned char[Length];
public:
unsigned char& operator[](int index); //when implemented, throws exception on out-of-range access.
};
SafeBuffer<10> buf, foo;
SafeBuffer<9> bar;
buf = foo; //pass
buf = bar; //compile-time error.
buf[100]; //compiles, but generates error at runtime.
Note that we are leveraging the type judgment system of templates to force the compile error of buf = bar
. That is an example of what a strongly typed system can do (Also note that casts can 100% destroy the typing - in C++).
The type of the arguments of strcopy()
is char *
. This means that once you pass your arrays to strcpy()
, it has no way of knowing that these are fixed size arrays. As far as the function is concerned, they are just pointers, and it will keep copying elements until it finds \0
in b
.
The main point is that once a function takes an argument that is a pointer, it has no way to determine whether it is a pointer to a single object, a pointer to a dynamically allocated buffer, or a fixed size array allocated on the stack.
So the answer is "no".
it can still overflow, strcpy stops
when it finds a NUL
to prevent an overflow, you should use strlcpy
or strncpy
// using strlcpy
strlcpy(a, unknownFunction, 100);
// using strncpy
strncpy(a, unknownFunction, 100);
a[99] = 0; // strncpy doesn't NUL-terminate the result
In general strncpy
is a safer alternative to strcpy
.
精彩评论