开发者

C: String manipulation adding more characters without causing a buffer overflow

In C I have a path in one of my strings

/home/frankv/

I now want to add the name of files that are contained in this folder - e.g. file1.txt file123.txt etc.

Having declared my variable either like this

char pathToFile[strlen("/home/frankv/")+1]

or

char *pathToFile =开发者_如何学JAVA malloc(strlen("/home/frankv/")+1)

My problem is that I cannot simply add more characters because it would cause a buffer overflow. Also, what do I do in case I do not know how long the filenames will be?

I've really gotten used to PHP lazy $string1.$string2 .. What is the easiest way to do this in C?


If you've allocated a buffer with malloc(), you can use realloc() to expand it:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
    char *buf;
    const char s1[] = "hello";
    const char s2[] = ", world";

    buf = malloc(sizeof s1);
    strcpy(buf, s1);

    buf = realloc(buf, sizeof s1 + sizeof s2 - 1);
    strcat(buf, s2);

    puts(buf);

    return 0;
}

NOTE: I have omitted error checking. You shouldn't. Always check whether malloc() returns a null pointer; if it does, take some corrective action, even if it's just terminating the program. Likewise for realloc(). And if you want to be able to recover from a realloc() failure, store the result in a temporary so you don't clobber your original pointer.


Use std::string, if possible. Else, reallocate another block of memory and use strcpy and strcat.


You have a couple options, but, if you want to do this dynamically using no additional libraries, realloc() is the stdlib function you're looking for:

char *pathToFile = malloc(strlen("/home/frankv/")+1);
char *string_to_add = "filename.txt";

char *p = realloc(pathToFile, strlen(pathToFile) + strlen(string_to_add) + 1);
if (!p) abort();
pathToFile = p;
strcat(p, string_to_add);

Note: you should always assign the result of realloc to a new pointer first, as realloc() returns NULL on failure. If you assign to the original pointer, you are begging for a memory leak.

If you're going to be doing much string manipulation, though, you may want to consider using a string library. Two I've found useful are bstring and ustr.


In case you can use C++, use the std::string. In case you must to use pure C, use what's call doubling - i.e. when out of space in the string - double the memory and copy the string into the new memory. And you'll have to use the second syntax:

char *pathToFile = malloc(strlen("/home/frankv/")+1);


You have chosen the wrong language for manipulating strings!

The easy and conventional way out is to do something like:

#define MAX_PATH 260
char pathToFile[MAX_PATH+1] = "/home/frankv/";

strcat(pathToFile, "wibble/");

Of course, this is error prone - if the resulting string exceeds MAX_PATH characters, anything can happen, and it is this sort of programming which is the route many trojans and worms use to penetrate security (by corrupting memory in a carefully defined way). Hence my deliberate choice of 260 for MAX_PATH, which is what it used to be in Windows - you can still make Windows Explorer do strange things to your files with paths over 260 characters, possibly because of code like this!

strncat may be a small help - you can at least tell it the maximum size of the destination, and it won't copy beyond that.

To do it robustly you need a string library which does variable length strings correctly. But I don't know if there is such a thing for C (C++ is a different matter, of course).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜