下面是phpbbs_file.c中的一个函数。问题是没有附件的帖子能打开。有附件不能显示
附件链接,而是把附件直接显示了。。。
偶然发现声明一个无用的变量i(下面红色的i)按说函数的行为应该没有改变,但是
函数行为变成了有附件的帖子能打开,完全正常。没有附件的帖子不能打开,进一步
跟踪发现函数在while(1)里面死循环了。下面黄色的语句if (ptrlen <= 0) break;
没有执行,我在这个语句前面后面加了语句输出ptrlen的值,结果都是 0 ..括号里面
的条件应该成立,执行break语句,而事实上根本就没执行。
弄了好几天了,还是找不到头绪,第一次见这么诡异的bug。
各位大佬帮忙看看吧。如果需要可以提供机器的ssh端口。
/*
* refer Ecma-262
* '\033' -> \r (not exactly the same thing, but borrow...)
* '\n' -> \n
* '\\' -> \\
* '\'' -> \'
* '\"' -> \"
* '\0' -> possible start of attachment
* 0 <= char < 32 -> ignore
* others -> passthrough
*/
PHP_FUNCTION(bbs2_readfile)
{
char *filename;
int filename_len;
char *output_buffer;
int output_buffer_len, output_buffer_size, j, i;
char c;
char *ptr, *cur_ptr;
off_t ptrlen, mmap_ptrlen;
int in_chinese = false;
int chunk_size = 51200;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
WRONG_PARAM_COUNT;
}
if (safe_mmapfile(filename, O_RDONLY, PROT_READ, MAP_SHARED, &ptr, &mmap_ptrlen, NULL) == 0)
RETURN_LONG(-1);
j = ptrlen = mmap_ptrlen;
if (j > chunk_size) j = chunk_size;
output_buffer_size = 2 * j + 16;
output_buffer = (char* )emalloc(output_buffer_size);
output_buffer_len = 0;
cur_ptr = ptr;
strcpy(output_buffer + output_buffer_len, "prints('");
output_buffer_len += 8;
while (1) {
for (; j > 0 ; j--) {
c = *cur_ptr;
if (c == '\0') { //assume ATTACHMENT_PAD[0] is '\0'
if (ptrlen >= ATTACHMENT_SIZE + sizeof(int) + 2) {
if (!memcmp(cur_ptr, ATTACHMENT_PAD, ATTACHMENT_SIZE)) {
ptrlen = -ptrlen;
break;
}
}
ptrlen--; cur_ptr++;
continue;
}
if (c < 0) {
in_chinese = !in_chinese;
output_buffer[output_buffer_len++] = c;
} else {
do {
if (c == '\n') c = 'n';
else if (c == '\033') c = 'r';
else if (c != '\\' && c != '\'' && c != '\"'
&& c != '/' /* to prevent things like </script> */
) {
if (c >= 32) {
output_buffer[output_buffer_len++] = c;
}
break;
}
if (in_chinese && c == 'n') {
output_buffer[output_buffer_len++] = ' ';
}
output_buffer[output_buffer_len++] = '\\';
output_buffer[output_buffer_len++] = c;
} while(0);
in_chinese = false;
}
ptrlen--; cur_ptr++;
}
if (ptrlen <= 0) break;
j = ptrlen;
if (j > chunk_size) j = chunk_size;
output_buffer_size += 2 * j;
output_buffer = (char*)erealloc(output_buffer, output_buffer_size);
if (output_buffer == NULL) RETURN_LONG(3);
}
if (in_chinese) {
output_buffer[output_buffer_len++] = ' ';
}
strcpy(output_buffer + output_buffer_len, "');");
output_buffer_len += 3;
if (ptrlen < 0) { //attachment
char *attachfilename, *attachptr;
char buf[1024];
char *startbufptr, *bufptr;
long attach_len, attach_pos, newlen;
int l;
ptrlen = -ptrlen;
strcpy(buf, "attach('");
startbufptr = buf + strlen(buf);
while(ptrlen > 0) {
if (((attachfilename = checkattach(cur_ptr, ptrlen,
&attach_len, &attachptr)) == NULL)) {
break;
}
attach_pos = attachfilename - ptr;
newlen = attachptr - cur_ptr + attach_len;
cur_ptr += newlen;
ptrlen -= newlen;
if (ptrlen < 0) break;
bufptr = startbufptr;
while(*attachfilename != '\0') {
switch(*attachfilename) {
case '\'':
case '\"':
case '\\':
*bufptr++ = '\\'; /* TODO: boundary check */
/* break is missing *intentionally* */
default:
*bufptr++ = *attachfilename++; /* TODO: boundary check */
}
}
sprintf(bufptr, "', %ld, %ld);", attach_len, attach_pos); /* TODO: boundary check */
l = strlen(buf);
if (output_buffer_len + l > output_buffer_size) {
output_buffer_size = output_buffer_size + sizeof(buf) * 10;
output_buffer = (char*)erealloc(output_buffer, output_buffer_size);
if (output_buffer == NULL) RETURN_LONG(3);
}
strcpy(output_buffer + output_buffer_len, buf);
output_buffer_len += l;
}
}
end_mmapfile(ptr, mmap_ptrlen, -1);
RETVAL_STRINGL(output_buffer, output_buffer_len, 0);
}
--
修改:spadger FROM 211.99.222.*
FROM 211.99.222.*