phpbbs.file.c

来自「linux/unix环境下的建站系统」· C语言 代码 · 共 736 行 · 第 1/2 页

C
736
字号
#include "php_kbs_bbs.h"  #include "SAPI.h"#include "md5.h"/* * 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;    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);}PHP_FUNCTION(bbs2_readfile_text){    char *filename;    int filename_len;    long maxchar;    long escape_flag; /* 0(default) - escape <>&, 1 - double escape <>&, 2 - escape <>& and space */    char *output_buffer;    int output_buffer_len, output_buffer_size, last_return = 0;    char c;    char *ptr, *cur_ptr;    off_t ptrlen, mmap_ptrlen;    int in_escape = false, is_last_space = false;    int i;    char escape_seq[4][16], escape_seq_len[4];    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll", &filename, &filename_len, &maxchar, &escape_flag) == FAILURE) {        WRONG_PARAM_COUNT;    }    if (safe_mmapfile(filename, O_RDONLY, PROT_READ, MAP_SHARED, &ptr, &mmap_ptrlen, NULL) == 0)        RETURN_LONG(-1);    ptrlen = mmap_ptrlen;        if (!maxchar) {        maxchar = ptrlen;    } else if (ptrlen > maxchar) {        ptrlen = maxchar;    }    output_buffer_size = 2 * maxchar;    output_buffer = (char* )emalloc(output_buffer_size);    output_buffer_len = 0;    cur_ptr = ptr;    if (escape_flag == 1) {        strcpy(escape_seq[0], "&amp;amp;");        strcpy(escape_seq[1], "&amp;lt;");        strcpy(escape_seq[2], "&amp;gt;");        strcpy(escape_seq[3], "&lt;br/&gt;");    } else {        strcpy(escape_seq[0], "&amp;");        strcpy(escape_seq[1], "&lt;");        strcpy(escape_seq[2], "&gt;");        strcpy(escape_seq[3], "<br/>");    }    for (i=0;i<4;i++) escape_seq_len[i] = strlen(escape_seq[i]);    while (ptrlen > 0) {        c = *cur_ptr;        if (c == '\0') { //assume ATTACHMENT_PAD[0] is '\0'            break;        } else if (c == '\033') {            in_escape = true;        } else if (!in_escape) {            if (output_buffer_len + 16 > output_buffer_size) {                output_buffer = (char*)erealloc(output_buffer, output_buffer_size += 128);            }            if (escape_flag == 2 && c == ' ') {                if (!is_last_space) {                    output_buffer[output_buffer_len++] = ' ';                } else {                    strcpy(output_buffer + output_buffer_len, "&nbsp;");                    output_buffer_len += 6;                }                is_last_space = !is_last_space;            } else {                is_last_space = false;                switch(c) {                    case '&':                        strcpy(output_buffer + output_buffer_len, escape_seq[0]);                        output_buffer_len += escape_seq_len[0];                        break;                    case '<':                        strcpy(output_buffer + output_buffer_len, escape_seq[1]);                        output_buffer_len += escape_seq_len[1];                        break;                    case '>':                        strcpy(output_buffer + output_buffer_len, escape_seq[2]);                        output_buffer_len += escape_seq_len[2];                        break;                    case '\n':                        strcpy(output_buffer + output_buffer_len, escape_seq[3]);                        output_buffer_len += escape_seq_len[3];                        last_return = output_buffer_len;                        is_last_space = true;                        break;                    default:                        if (c < 0 || c >= 32)                            output_buffer[output_buffer_len++] = c;                        break;                }            }        } else if (isalpha(c)) {            in_escape = false;        }        ptrlen--; cur_ptr++;    }    end_mmapfile(ptr, mmap_ptrlen, -1);    RETVAL_STRINGL(output_buffer, last_return, 0);}PHP_FUNCTION(bbs_file_output_attachment){    char *filename;    int filename_len;    char *attachname = NULL;    int attachname_len = 0;    long attachpos;    char *ptr;    char *sendptr = NULL;    int sendlen;    off_t ptrlen, mmap_ptrlen;    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|s", &filename, &filename_len, &attachpos, &attachname, &attachname_len) == FAILURE) {        WRONG_PARAM_COUNT;    }        if (attachpos == 0 && attachname == NULL) {        RETURN_LONG(-2);    }    if (safe_mmapfile(filename, O_RDONLY, PROT_READ, MAP_SHARED, &ptr, &mmap_ptrlen, NULL) == 0)        RETURN_LONG(-1);    ptrlen = mmap_ptrlen;    if (attachpos == 0) {        sendptr = ptr;        sendlen = ptrlen;    } else if (attachpos >= 0 && attachpos < ptrlen) {        char *p, *pend = ptr + ptrlen;        p = attachname = ptr + attachpos;        while(*p && p < pend) {            p++;        }        p++;        if (p <= pend - 4) {            memcpy(&sendlen, p, 4);            sendlen = ntohl(sendlen);            if (sendlen >= 0 && pend - 4 - p >= sendlen) {                sendptr = p + 4;            }        }    }    if (sendptr) {        sapi_header_line ctr = {0};        char buf[256];        ctr.line = buf;        snprintf(buf, 256, "Content-Type: %s", get_mime_type(attachname));        ctr.line_len = strlen(buf);        sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);        snprintf(buf, 256, "Accept-Ranges: bytes");        ctr.line_len = strlen(buf);        sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);        snprintf(buf, 256, "Content-Length: %d", sendlen);        ctr.line_len = strlen(buf);        sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);        snprintf(buf, 256, "Content-Disposition: inline;filename=%s", attachname);        ctr.line_len = strlen(buf);        sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);                ZEND_WRITE(sendptr, sendlen);    }    end_mmapfile(ptr, mmap_ptrlen, -1);    RETURN_LONG(0);}static char* output_buffer=NULL;static int output_buffer_len=0;static int output_buffer_size=0;void reset_output_buffer() {    output_buffer=NULL;    output_buffer_size=0;    output_buffer_len=0;}static void output_printf(const char* buf, uint len){	int bufLen;	int n,newsize;	char * newbuf;	if (output_buffer==NULL) {		output_buffer=(char* )emalloc(51200); //first 50k		if (output_buffer==NULL) {			return;		}		output_buffer_size=51200;	}	bufLen=strlen(buf);	if (bufLen>len) {		bufLen=len;	}	n=1+output_buffer_len+bufLen-output_buffer_size;	if (n>=0) {		newsize=output_buffer_size+((n/102400)+1)*102400; //n*100k every time		newbuf=(char*)erealloc(output_buffer,newsize);		if (newbuf==NULL){			return;		}		output_buffer=newbuf;		output_buffer_size=newsize;	}	memcpy(output_buffer+output_buffer_len,buf,bufLen);	output_buffer_len+=bufLen;}static char* get_output_buffer(){	return output_buffer;}static int get_output_buffer_len(){	int len=output_buffer_len;	output_buffer_len=0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?