我正在用C编写一个简单的程序:
int main(int argc, char** argv) {
unsigned char* line = (unsigned char* ) malloc(0xFFFF);
while (gets(line) > 0) {
if (line[0] == 'l') {
if (line[2]=='.' && line[3] == '.') {
printf("forbidden path");
}
unsigned char* res = (unsigned char* ) malloc(0xFFFF);
unsigned char* cmd = (unsigned char* ) malloc(strlen(line) +
1 + strlen(" | grep -v xml") + strlen("/home/files/"));
strcpy(cmd, "ls ");
strcpy(cmd + 3, "/home/boris/0servfiles/");
strcpy(cmd + 3 + strlen("/home/files/"), line + 2);
strcpy(cmd + 3 + strlen("/home/files/") + strlen(line + 2), " | grep -v xml");
execwthr(cmd, res);
printf("%s\n%s", cmd, res);
free(cmd);
free(res);
} else if (line[0] == 'm') {
if (line[2]=='.' && line[3] == '.') {
printf("forbidden path");
}
unsigned char res = (unsigned char* ) malloc(0xFFFF);
unsigned char* cmd = (unsigned char* ) malloc(strlen(line) +
1 + strlen("/home/files/"));
strcpy(cmd, "mkdir ");
strcpy(cmd + 6, "/home/files/");
strcpy(cmd + 6 + strlen("/home/files/"), line + 2);
execwthr(cmd, res);
printf("%s\n%s", cmd, res);
free(cmd);
free(res);
}
}
return (EXIT_SUCCESS);
}
有一个小问题。当我尝试创建名为“h”的文件夹时,我得到以下内容:
m l
mkdir /home/files)l
怎么了?提前谢谢!
答案 0 :(得分:2)
您似乎没有意识到strcat()
功能。使用它将大大简化您的代码。
另外,为什么要编写C代码来完成一个可以通过简单的shell(或Perl)脚本轻松完成的工作?例如,我相信您的脚本在Perl中看起来像这样:
#!/usr/bin/perl
use strict;
while (my $line = <STDIN>) {
chomp $line;
my $cmd;
if (my ($arg) = $line =~ m{^l (.*)$}) {
$cmd = "ls /home/files/$arg | grep -v xml";
} elsif (my ($arg) = $line =~ m{^m (.*)$}) {
$cmd = "mkdir /home/files/$arg";
}
my $res = `$cmd`;
print "$cmd\n$res\n";
}
请注意,此代码未经测试,并且(仍然)不安全。但是,它比您的代码更短更容易阅读。这表明C是此任务的错误语言。 :)
答案 1 :(得分:2)
这里有很多问题。我将列出一些,解决它们可能会让其他人更明显。
当意外路径显示为输入时,您打印出“禁止路径”。但是,您继续使用该无效路径执行该功能。当发生这种情况时,您可能希望完全错误地退出程序。
malloc()
功能可能会失败。当它这样做时,它返回一个NULL指针。您永远不会检查malloc
返回的值,这意味着您的字符串操作代码可能使用了无效指针。
您不应该使用strcpy()
之类的函数,因为它们无法防止缓冲区溢出。请改用“安全”版本(例如strncpy
)。
函数gets()
非常不安全,不推荐使用。请改用其他标准库I / O函数。
此代码:
strcpy(cmd, "ls ");
strcpy(cmd + 3, "/home/boris/0servfiles/");
strcpy(cmd + 3 + strlen("/home/files/"), line + 2);
可能没有做你想做的事。第二行向缓冲区添加一个长字符串,但第三行只向前跳过足够远以容纳更短的字符串。这意味着您的第三个strcpy
将部分覆盖第二个strcpy
写入的字符串。
这样的代码:
strcpy(cmd, "mkdir ");
strcpy(cmd + 6, "/home/files/");
strcpy(cmd + 6 + strlen("/home/files/"), line + 2);
容易出错并且充满魔力数字。如果我正在解释你正在做的事情,你可以将它组合成一个更有意义的电话:sprintf(cmd, "mkdir /home/files/%s", line + 2);
。
正如其他人所提到的,您似乎正在重新实施标准strncat()
功能。您最好使用标准版本。如果你正在处理像这样的硬编码字符串,我甚至建议使用snprintf()
。
以下行错误:
unsigned char res = (unsigned char* ) malloc(0xFFFF);
你正在指定一个指向char
的指针,这几乎肯定不是你想要的。
您为line
动态分配内存,但永远不会释放它。
答案 2 :(得分:1)
这段代码非常糟糕。请参阅strcat()功能。
我也看到了许多其他问题。例如,如果代码确定了一条&#34;禁止路径&#34;进入后,它继续执行任务!
您将从学习如何使用调试器逐步完成此代码并了解其实际功能中获益。这也可以让你能够回答你原来的问题。
答案 3 :(得分:0)
基本上所有丑陋的代码都可以用一个带有正确参数的snprintf
调用来代替。不要费心学习strcat
;而正如其他人所说,它比你正在做的更容易,它也使编写易受攻击的代码变得容易。只需使用snprintf
来满足您的所有字符串生成需求,您的代码将变得干净,简单,甚至可能无错误。