【发布时间】:2021-01-28 00:07:40
【问题描述】:
我正在编写一个 c 编译器。 Flex 识别出我的字符串标记并将其发送到函数以将其存储在包含有关它的信息的 struct{} 中,但首先该字符串需要删除转义字符,即“”。这是我的代码:
char* removeEscapeChars(char* svalue)
{
char* processedString; //will be the string with escape characters removed
int svalLen = strlen(svalue);
printf("svalLen (size of string passed in): %d\n", svalLen);
printf("svalue (string passed in): %s\n", svalue);
int foundEscapedChars = 0;
for (int i = 0; i < svalLen;)
{
if (svalue[i] == '\\') {
//Found escaped character
if (svalue[i+1] == 'n') {
//Found newline character
svalue[i] = int('\n');
}
else if (svalue[i+1] == '0') {
//Found null character
svalue[i] = int('\0');
}
else {
//Any other character
svalue[i] = svalue[i+1];
}
i++;
foundEscapedChars++;
for (int j = i; j < svalLen + 1; j++) {
svalue[j] = svalue[j+1];
}
}
else {
i++;
}
}
int newSize = svalLen - foundEscapedChars;
processedString = (char*) malloc(newSize * sizeof(char));
memcpy(processedString, svalue, newSize * sizeof(char));
printf("newSize: %d\n", newSize);
printf("processedString: %s\n", processedString);
printf("processedString Size: %d\n", strlen(processedString));
free(svalue);
return processedString;
}
它在 99% 的时间都可以工作,但是当它在这个特定的字符串(或类似的 40 个字符的字符串)“-//W3C//DTD XHTML 1.0 Transitional//EN”上进行测试时,malloc() 似乎是为 2 个字节的字符串分配内存太大。输出如下。请注意,我在调用 malloc() 时使用了 int newSize,它说它的值是 40,然后 strlen() 返回 42。 sizeof(char) 也是 == 1。主要问题是它在字符串末尾插入垃圾字符。什么给了?
"-//W3C//DTD XHTML 1.0 Transitional//EN"
svalLen (size of string passed in): 40
svalue (string passed in) "-//W3C//DTD XHTML 1.0 Transitional//EN"
newSize: 40
processedString: "-//W3C//DTD XHTML 1.0 Transitional//EN"Z
processedString Size: 42
Line 47 Token: STRINGCONST Value: "-//W3C//DTD XHTML 1.0 Transitional//EN"Z Len: 40 Input: "-//W3C//DTD XHTML 1.0 Transitional//EN"
【问题讨论】:
-
我不能完全遵循所有逻辑,但我不认为您的
memcpy正在复制终止的空字符。结果,如您所见,在processedString上调用strlen可能会超出它。 (当您修复此问题时,请确保调整malloc以允许该空字符也有空间。) -
如果您扫描转义字符,计算您需要的数量,分配和转储偏移量,这将相当更有效。现在,每次找到转义字符时,您都会痛苦地将字符串重新洗牌。您拥有的转义字符越多,速度就越慢。
-
我认为它只是从外部分配的随机内存......基本上你没有复制\0......这就是缓冲区溢出攻击的来源
-
简而言之:“为什么 malloc() 分配的字节数比预期的多 2 个字节?”这不是 - 您 访问的字节数(至少)比您分配的多 2 个字节。
-
free()给你的论点也是非常粗鲁的。你不拥有那个。你不能假设你甚至可以free()它。removeEscapeChars("test")爆炸。如有必要,让调用者处理清理工作。 不要自以为比来电者更了解。
标签: c parsing compiler-construction flex-lexer