⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_include.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 5 页
字号:
            *p = *s;            continue;        }        /* find end of entity */        for (i = 1; s[i] != ';' && s[i] != '\0'; i++) {            continue;        }        if (s[i] == '\0') {     /* treat as normal data */            *p = *s;            continue;        }        /* is it numeric ? */        if (s[1] == '#') {            for (j = 2, val = 0; j < i && apr_isdigit(s[j]); j++) {                val = val * 10 + s[j] - '0';            }            s += i;            if (j < i || val <= 8 || (val >= 11 && val <= 31) ||                (val >= 127 && val <= 160) || val >= 256) {                p--;            /* no data to output */            }            else {                *p = RAW_ASCII_CHAR(val);            }        }        else {            j = i - 1;            if (j > MAXENTLEN || entlist[j] == NULL) {                /* wrong length */                *p = '&';                continue;       /* skip it */            }            for (ents = entlist[j]; *ents != '\0'; ents += i) {                if (strncmp(s + 1, ents, j) == 0) {                    break;                }            }            if (*ents == '\0') {                *p = '&';       /* unknown */            }            else {                *p = RAW_ASCII_CHAR(((const unsigned char *) ents)[j]);                s += i;            }        }    }    *p = '\0';}/* * Extract the next tag name and value. * If there are no more tags, set the tag name to NULL. * The tag value is html decoded if dodecode is non-zero. * The tag value may be NULL if there is no tag value.. *    format: *        [WS]<Tag>[WS]=[WS]['|"|`]<Value>[['|"|`|]|WS] */#define SKIP_TAG_WHITESPACE(ptr) while ((*ptr != '\0') && (apr_isspace (*ptr))) ptr++static void ap_ssi_get_tag_and_value(include_ctx_t *ctx, char **tag,                                     char **tag_val, int dodecode){    *tag_val = NULL;    if (ctx->curr_tag_pos >= ctx->combined_tag + ctx->tag_length) {        *tag = NULL;        return;    }    *tag = ctx->curr_tag_pos;    if (!**tag) {        *tag = NULL;        /* finitio */        ctx->curr_tag_pos = ctx->combined_tag + ctx->tag_length;        return;    }    *tag_val = ap_strchr(*tag, '=');    if (!*tag_val) {        ctx->curr_tag_pos = ctx->combined_tag + ctx->tag_length;        return;    }    /* if it starts with '=' there was no tag name, just a value */    if (*tag_val == *tag) {        *tag = NULL;    }    *(*tag_val)++ = '\0';    ctx->curr_tag_pos = *tag_val + strlen(*tag_val) + 1; /* skip \0 byte */    if (dodecode) {        decodehtml(*tag_val);    }    return;}/* initial buffer size for power-of-two allocator in ap_ssi_parse_string */#define PARSE_STRING_INITIAL_SIZE 64/* * Do variable substitution on strings * (Note: If out==NULL, this function allocs a buffer for the resulting * string from r->pool.  The return value is the parsed string) */static char *ap_ssi_parse_string(request_rec *r, include_ctx_t *ctx,                                  const char *in, char *out,                                 apr_size_t length, int leave_name){    char ch;    char *next;    char *end_out;    apr_size_t out_size;    /* allocate an output buffer if needed */    if (!out) {        out_size = PARSE_STRING_INITIAL_SIZE;        if (out_size > length) {            out_size = length;        }        out = apr_palloc(r->pool, out_size);    }    else {        out_size = length;    }    /* leave room for nul terminator */    end_out = out + out_size - 1;    next = out;    while ((ch = *in++) != '\0') {        switch (ch) {        case '\\':            if (next == end_out) {                if (out_size < length) {                    /* double the buffer size */                    apr_size_t new_out_size = out_size * 2;                    apr_size_t current_length = next - out;                    char *new_out;                    if (new_out_size > length) {                        new_out_size = length;                    }                    new_out = apr_palloc(r->pool, new_out_size);                    memcpy(new_out, out, current_length);                    out = new_out;                    out_size = new_out_size;                    end_out = out + out_size - 1;                    next = out + current_length;                }                else {                    /* truncated */                    *next = '\0';                    return out;                }            }            if (*in == '$') {                *next++ = *in++;            }            else {                *next++ = ch;            }            break;        case '$':            {                const char *start_of_var_name;                char *end_of_var_name;        /* end of var name + 1 */                const char *expansion, *temp_end, *val;                char        tmp_store;                apr_size_t l;                /* guess that the expansion won't happen */                expansion = in - 1;                if (*in == '{') {                    ++in;                    start_of_var_name = in;                    in = ap_strchr_c(in, '}');                    if (in == NULL) {                        ap_log_rerror(APLOG_MARK, APLOG_ERR,                                      0, r, "Missing '}' on variable \"%s\"",                                      expansion);                        *next = '\0';                        return out;                    }                    temp_end = in;                    end_of_var_name = (char *)temp_end;                    ++in;                }                else {                    start_of_var_name = in;                    while (apr_isalnum(*in) || *in == '_') {                        ++in;                    }                    temp_end = in;                    end_of_var_name = (char *)temp_end;                }                /* what a pain, too bad there's no table_getn where you can                 * pass a non-nul terminated string */                l = end_of_var_name - start_of_var_name;                if (l != 0) {                    tmp_store        = *end_of_var_name;                    *end_of_var_name = '\0';                    val = get_include_var(r, ctx, start_of_var_name);                    *end_of_var_name = tmp_store;                    if (val) {                        expansion = val;                        l = strlen(expansion);                    }                    else if (leave_name) {                        l = in - expansion;                    }                    else {                        /* no expansion to be done */                        break;                    }                }                else {                    /* zero-length variable name causes just the $ to be                      * copied */                    l = 1;                }                if ((next + l > end_out) && (out_size < length)) {                    /* increase the buffer size to accommodate l more chars */                    apr_size_t new_out_size = out_size;                    apr_size_t current_length = next - out;                    char *new_out;                    do {                        new_out_size *= 2;                    } while (new_out_size < current_length + l + 1); /* +1 for NUL */                    if (new_out_size > length) {                        new_out_size = length;                    }                    new_out = apr_palloc(r->pool, new_out_size);                    memcpy(new_out, out, current_length);                    out = new_out;                    out_size = new_out_size;                    end_out = out + out_size - 1;                    next = out + current_length;                }                l = ((int)l > end_out - next) ? (end_out - next) : l;                memcpy(next, expansion, l);                next += l;                break;            }        default:            if (next == end_out) {                if (out_size < length) {                    /* double the buffer size */                    apr_size_t new_out_size = out_size * 2;                    apr_size_t current_length = next - out;                    char *new_out;                    if (new_out_size > length) {                        new_out_size = length;                    }                    new_out = apr_palloc(r->pool, new_out_size);                    memcpy(new_out, out, current_length);                    out = new_out;                    out_size = new_out_size;                    end_out = out + out_size - 1;                    next = out + current_length;                }                else {                    /* truncated */                    *next = '\0';                    return out;                }            }            *next++ = ch;            break;        }    }    *next = '\0';    return out;}/* --------------------------- Action handlers ---------------------------- *//* ensure that path is relative, and does not contain ".." elements * ensentially ensure that it does not match the regex: * (^/|(^|/)\.\.(/|$)) * XXX: Simply replace with apr_filepath_merge                     */static int is_only_below(const char *path){#ifdef HAVE_DRIVE_LETTERS    if (path[1] == ':')         return 0;#endif#ifdef NETWARE    if (ap_strchr_c(path, ':'))        return 0;#endif    if (path[0] == '/') {        return 0;    }    while (*path) {        int dots = 0;        while (path[dots] == '.')            ++dots;#if defined(WIN32)         /* If the name is canonical this is redundant         * but in security, redundancy is worthwhile.         * Does OS2 belong here (accepts ... for ..)?         */        if (dots > 1 && (!path[dots] || path[dots] == '/'))            return 0;#else        if (dots == 2 && (!path[dots] || path[dots] == '/'))            return 0;#endif        path += dots;        /* Advance to either the null byte at the end of the         * string or the character right after the next slash,         * whichever comes first         */        while (*path && (*path++ != '/')) {            continue;        }    }    return 1;}static int handle_include(include_ctx_t *ctx, apr_bucket_brigade **bb,                          request_rec *r, ap_filter_t *f, apr_bucket *head_ptr,                          apr_bucket **inserted_head){    char *tag     = NULL;    char *tag_val = NULL;    apr_bucket  *tmp_buck;    char *parsed_string;    int loglevel = APLOG_ERR;    *inserted_head = NULL;    if (ctx->flags & FLAG_PRINTING) {        while (1) {            ap_ssi_get_tag_and_value(ctx, &tag, &tag_val, 1);            if (tag_val == NULL) {                if (tag == NULL) {                    return (0);                }                else {                    return (1);                }            }            if (!strcmp(tag, "virtual") || !strcmp(tag, "file")) {                request_rec *rr = NULL;                char *error_fmt = NULL;                apr_status_t rc = APR_SUCCESS;                SPLIT_AND_PASS_PRETAG_BUCKETS(*bb, ctx, f->next, rc);                if (rc != APR_SUCCESS) {                    return rc;                }                 parsed_string = ap_ssi_parse_string(r, ctx, tag_val, NULL,                                                     MAX_STRING_LEN, 0);                if (tag[0] == 'f') {                    /* XXX: Port to apr_filepath_merge                     * be safe; only files in this directory or below allowed                      */                    if (!is_only_below(parsed_string)) {                        error_fmt = "unable to include file \"%s\" "                                    "in parsed file %s";                    }                    else {                        rr = ap_sub_req_lookup_uri(parsed_string, r, f->next);                    }                }                else {                    rr = ap_sub_req_lookup_uri(parsed_string, r, f->next);                }                if (!error_fmt && rr->status != HTTP_OK) {                    error_fmt = "unable to include \"%s\" in parsed file %s";                }                if (!error_fmt && (ctx->flags & FLAG_NO_EXEC) &&                     rr->content_type &&                     (strncmp(rr->content_type, "text/", 5))) {                    error_fmt = "unable to include potential exec \"%s\" "                        "in parsed file %s";

⌨️ 快捷键说明

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