2011-11-19 50 views
1

我必须确保作为参数传递的字符串不会导致溢出。我被用strncpy这样做,但结束“\ 0”,分配的内存适量等等给了我一些麻烦......请确保一个字符串作为参数传递不会导致溢出

我的解决办法是这样的:

l = strlen(argv[optind]); 
if(l<MAX_LENGTH) { 
    msg = malloc((l+1) * sizeof(char)); 
    msg = strcpy(msg, argv[optind]); 
} else { 
    msg = malloc((MAX_LENGTH+1) * sizeof(char)); 
    msg = strncpy(msg, argv[optind], MAX_LENGTH); 
    msg[MAX_LENGTH+1] = '\0'; 
} 

它作品,但我想知道它是否真的正确,如果有更紧凑的解决方案?

+3

我认为这是正确的编码上述方式。但是你也可以直接将argv [optind](通过参数或指针)传递给你的内部例程,而不用担心这种限制。 –

+1

您可能想要考虑一下这样一个事实,即您的平台很可能已经对参数大小进行了限制,因此您可以随时使用“l + 1”。 –

+0

你应该使用strnlen – SoapBox

回答

2

我认为这是最简单的你可以得到:

size_t l; 
char* msg; 
... 
l = strlen(argv[optind]); 
if (l > MAX_LENGTH) l = MAX_LENGTH; 

msg = malloc(l + 1); 
if (msg == NULL) /* handle the error as appropriate*/; 

memcpy(msg, argv[optind], l); 
msg[l] = '\0'; 
+0

GNU函数strnlen(可以轻松地重新实现的扩展)很有趣,可以避免strlen的另一个潜在问题(考虑execX系列函数) – ShinTakezou

1

,也许可以与取代所有这些代码:

msg = strdup(argv[optind]); 

strdup(3)

The strdup() function returns a pointer to a new string which 
    is a duplicate of the string s. Memory for the new string is 
    obtained with malloc(3), and can be freed with free(3). 

    The strndup() function is similar, but only copies at most n 
    characters. If s is longer than n, only n characters are 
    copied, and a terminating null byte ('\0') is added. 

更新

CONFORMING TO 
    strdup() conforms to SVr4, 4.3BSD, POSIX.1-2001. strndup(), 
    strdupa(), and strndupa() are GNU extensions. 
+0

但是,'strdup'不在标准库中...... –

+1

这具有语义上的区别,它不会对结果分配进行限制。 –

+0

@Oli:很好。我很习惯用我的POSIX盲目思考。 :) – sarnold

1
l = strlen(argv[optind]); 
if (l < MAX_LENGTH) { 
    msg = malloc(l+1); 
    if (msg) strcpy(msg, argv[optind]); 
} else { 
    msg = malloc(MAX_LENGTH+1); 
    if (msg) { 
#if 1 
     memcpy(msg, argv[optind], MAX_LENGTH); 
#else 
     strncpy(msg, argv[optind], MAX_LENGTH); 
#endif 
     msg[MAX_LENGTH] = '\0'; 
    } 
} 
+0

这有什么好处?我认为它不会提高可读性,也不会更紧凑。 – mort

+2

区别在最后一行。 OP使用MAX_LENGTH + 1作为索引(这是错误的)。另外,我检查malloc()返回NULL。 – wildplasser

+0

请不要更新您的帖子以隐藏您的错误。这会使未来的观众对这些反应毫无用处。 – wildplasser

相关问题