break;
}
c = buf;
- while (c - buf != len) {
+ while (c < buf + len) {
if (ctx->bytes_parsed >= BYTE_COUNT_THRESHOLD) {
apr_bucket *start_bucket;
if (ctx->head_start_index > 0) {
ctx->head_start_index = 0;
ctx->head_start_bucket = tmp_bkt;
+ ctx->parse_pos = 0;
+ ctx->state = PRE_HEAD;
}
return tmp_bkt;
else {
c = buf;
}
- while (c - buf != len) {
+ while (c < buf + len) {
if (ctx->bytes_parsed >= BYTE_COUNT_THRESHOLD) {
+ if (ctx->state == PARSE_DIRECTIVE) {
+ /* gonna start over parsing the directive next time through */
+ ctx->directive_length = 0;
+ ctx->tag_length = 0;
+ }
return dptr;
}
static apr_status_t get_combined_directive (include_ctx_t *ctx,
request_rec *r,
apr_bucket_brigade *bb,
- char *tmp_buf, int tmp_buf_size)
+ char *tmp_buf,
+ apr_size_t tmp_buf_size)
{
- int done = 0;
- apr_bucket *dptr;
+ int done = 0;
+ apr_bucket *dptr;
const char *tmp_from;
apr_size_t tmp_from_len;
}
}
} while ((!done) &&
- ((ctx->curr_tag_pos - ctx->combined_tag) < ctx->tag_length));
+ (ctx->curr_tag_pos < ctx->combined_tag + ctx->tag_length));
ctx->combined_tag[ctx->tag_length] = '\0';
ctx->curr_tag_pos = ctx->combined_tag;
}
}
- *c++ = '\0'; /* Overwrites delimiter (term or WS) with NULL. */
- ctx->curr_tag_pos = c;
+ *(c-shift_val) = '\0'; /* Overwrites delimiter (term or WS) with NULL. */
+ ctx->curr_tag_pos = ++c;
if (dodecode) {
decodehtml(*tag_val);
}
for (p = r; p != NULL && !founddupe; p = p->main) {
request_rec *q;
for (q = p; q != NULL; q = q->prev) {
- if ( (strcmp(q->filename, rr->filename) == 0) ||
- (strcmp(q->uri, rr->uri) == 0) ){
+ if ((q->filename && rr->filename && (strcmp(q->filename, rr->filename) == 0)) ||
+ (strcmp(q->uri, rr->uri) == 0)) {
founddupe = 1;
break;
}
tmp_buck = apr_bucket_heap_create(echo_text, e_len, 1, &e_wrt);
}
else {
- tmp_buck = apr_bucket_immortal_create("(none)", sizeof("none"));
+ tmp_buck = apr_bucket_immortal_create("(none)", sizeof("(none)")-1);
}
APR_BUCKET_INSERT_BEFORE(head_ptr, tmp_buck);
if (*inserted_head == NULL) {
}
}
-#define NEG_SIGN " -"
-#define ZERO_K " 0k"
-#define ONE_K " 1k"
-
-static void generate_size(apr_ssize_t size, char *buff, apr_size_t buff_size)
-{
- /* XXX: this -1 thing is a gross hack */
- if (size == (apr_ssize_t)-1) {
- memcpy (buff, NEG_SIGN, sizeof(NEG_SIGN)+1);
- }
- else if (!size) {
- memcpy (buff, ZERO_K, sizeof(ZERO_K)+1);
- }
- else if (size < 1024) {
- memcpy (buff, ONE_K, sizeof(ONE_K)+1);
- }
- else if (size < 1048576) {
- apr_snprintf(buff, buff_size, "%4" APR_SSIZE_T_FMT "k", (size + 512) / 1024);
- }
- else if (size < 103809024) {
- apr_snprintf(buff, buff_size, "%4.1fM", size / 1048576.0);
- }
- else {
- apr_snprintf(buff, buff_size, "%4" APR_SSIZE_T_FMT "M", (size + 524288) / 1048576);
- }
-}
-
static int handle_fsize(include_ctx_t *ctx, apr_bucket_brigade **bb, request_rec *r,
ap_filter_t *f, apr_bucket *head_ptr, apr_bucket **inserted_head)
{
char buff[50];
if (!(ctx->flags & FLAG_SIZE_IN_BYTES)) {
- generate_size(finfo.size, buff, sizeof(buff));
+ apr_strfsize(finfo.size, buff);
s_len = strlen (buff);
}
else {
/* -------------------------- The main function --------------------------- */
-static void send_parsed_content(apr_bucket_brigade **bb, request_rec *r,
- ap_filter_t *f)
+static apr_status_t send_parsed_content(apr_bucket_brigade **bb,
+ request_rec *r, ap_filter_t *f)
{
include_ctx_t *ctx = f->ctx;
apr_bucket *dptr = APR_BRIGADE_FIRST(*bb);
apr_bucket *tmp_dptr;
apr_bucket_brigade *tag_and_after;
int ret;
+ apr_status_t rv;
if (r->args) { /* add QUERY stuff to env cause it ain't yet */
char *arg_copy = apr_pstrdup(r->pool, r->args);
if ((do_cleanup) && (!APR_BRIGADE_EMPTY(ctx->ssi_tag_brigade))) {
apr_bucket *tmp_bkt;
- tmp_bkt = apr_bucket_immortal_create(STARTING_SEQUENCE, cleanup_bytes);
+ tmp_bkt = apr_bucket_immortal_create(STARTING_SEQUENCE,
+ cleanup_bytes);
APR_BRIGADE_INSERT_HEAD(*bb, tmp_bkt);
-
- while (!APR_BRIGADE_EMPTY(ctx->ssi_tag_brigade)) {
- tmp_bkt = APR_BRIGADE_FIRST(ctx->ssi_tag_brigade);
- apr_bucket_delete(tmp_bkt);
- }
+ apr_brigade_cleanup(ctx->ssi_tag_brigade);
}
/* If I am inside a conditional (if, elif, else) that is false
else if ((tmp_dptr != NULL) && (ctx->bytes_parsed >= BYTE_COUNT_THRESHOLD)) {
/* Send the large chunk of pre-tag bytes... */
tag_and_after = apr_brigade_split(*bb, tmp_dptr);
- ap_pass_brigade(f->next, *bb);
+ rv = ap_pass_brigade(f->next, *bb);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
*bb = tag_and_after;
dptr = tmp_dptr;
ctx->bytes_parsed = 0;
/* DO CLEANUP HERE!!!!! */
tmp_dptr = ctx->head_start_bucket;
if (!APR_BRIGADE_EMPTY(ctx->ssi_tag_brigade)) {
- while (!APR_BRIGADE_EMPTY(ctx->ssi_tag_brigade)) {
- tmp_bkt = APR_BRIGADE_FIRST(ctx->ssi_tag_brigade);
- apr_bucket_delete(tmp_bkt);
- }
+ apr_brigade_cleanup(ctx->ssi_tag_brigade);
}
else {
do {
(tmp_dptr != APR_BRIGADE_SENTINEL(*bb)));
}
- return;
+ return APR_SUCCESS;
}
/* Can't destroy the tag buckets until I'm done processing
ctx->curr_tag_pos = &ctx->combined_tag[ctx->directive_length+1];
handle_func =
- (int (*)(include_ctx_t *, apr_bucket_brigade **, request_rec *,
- ap_filter_t *, apr_bucket *, apr_bucket **))
- apr_hash_get(include_hash, ctx->combined_tag, ctx->directive_length+1);
+ (include_handler_fn_t *)apr_hash_get(include_hash,
+ ctx->combined_tag,
+ ctx->directive_length+1);
if (handle_func != NULL) {
ret = (*handle_func)(ctx, bb, r, f, dptr, &content_head);
}
}
tmp_dptr = ctx->head_start_bucket;
if (!APR_BRIGADE_EMPTY(ctx->ssi_tag_brigade)) {
- while (!APR_BRIGADE_EMPTY(ctx->ssi_tag_brigade)) {
- tmp_bkt = APR_BRIGADE_FIRST(ctx->ssi_tag_brigade);
- apr_bucket_delete(tmp_bkt);
- }
+ apr_brigade_cleanup(ctx->ssi_tag_brigade);
}
else {
do {
ctx->directive_length = 0;
if (!APR_BRIGADE_EMPTY(ctx->ssi_tag_brigade)) {
- while (!APR_BRIGADE_EMPTY(ctx->ssi_tag_brigade)) {
- tmp_bkt = APR_BRIGADE_FIRST(ctx->ssi_tag_brigade);
- apr_bucket_delete(tmp_bkt);
- }
+ apr_brigade_cleanup(ctx->ssi_tag_brigade);
}
ctx->state = PRE_HEAD;
} while (dptr != APR_BRIGADE_SENTINEL(*bb));
}
else { /* Otherwise pass it along... */
- ap_pass_brigade(f->next, *bb); /* No SSI tags in this brigade... */
+ rv = ap_pass_brigade(f->next, *bb); /* No SSI tags in this brigade... */
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
ctx->bytes_parsed = 0;
}
}
}
/* Set aside tag, pass pre-tag... */
tag_and_after = apr_brigade_split(*bb, ctx->head_start_bucket);
- ap_save_brigade(f, &ctx->ssi_tag_brigade, &tag_and_after);
- ap_pass_brigade(f->next, *bb);
+ ap_save_brigade(f, &ctx->ssi_tag_brigade, &tag_and_after, r->pool);
+ rv = ap_pass_brigade(f->next, *bb);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
ctx->bytes_parsed = 0;
}
}
+ return APR_SUCCESS;
}
/*****************************************************************
result->default_time_fmt = DEFAULT_TIME_FORMAT;
result->xbithack = xbh;
return result;
- return result;
}
static const char *set_xbithack(cmd_parms *cmd, void *xbp, const char *arg)
return NULL;
}
-static int includes_filter(ap_filter_t *f, apr_bucket_brigade *b)
+static apr_status_t includes_filter(ap_filter_t *f, apr_bucket_brigade *b)
{
request_rec *r = f->r;
include_ctx_t *ctx = f->ctx;
request_rec *parent;
+ apr_status_t rv;
include_dir_config *conf =
(include_dir_config *)ap_get_module_config(r->per_dir_config,
&include_module);
if (!(ap_allow_options(r) & OPT_INCLUDES)) {
return ap_pass_brigade(f->next, b);
}
- r->allowed |= (1 << M_GET);
+ r->allowed |= (AP_METHOD_BIT << M_GET);
if (r->method_number != M_GET) {
return ap_pass_brigade(f->next, b);
}
ctx->error_length = strlen(ctx->error_str);
}
else {
- ap_pass_brigade(f->next, b);
- return APR_ENOMEM;
+ return ap_pass_brigade(f->next, b);
}
}
else {
*/
apr_table_unset(f->r->headers_out, "Content-Length");
- send_parsed_content(&b, r, f);
+ rv = send_parsed_content(&b, r, f);
if (parent) {
/* signify that the sub request should not be killed */
NESTED_INCLUDE_MAGIC);
}
- return OK;
+ return rv;
}
-static void ap_register_include_handler(char *tag, include_handler func)
+static void ap_register_include_handler(char *tag, include_handler_fn_t *func)
{
apr_hash_set(include_hash, tag, strlen(tag) + 1, (const void *)func);
}
{NULL}
};
+static int xbithack_handler(request_rec *r)
+{
+#if defined(OS2) || defined(WIN32) || defined(NETWARE)
+ /* OS/2 dosen't currently support the xbithack. This is being worked on. */
+ return DECLINED;
+#else
+ enum xbithack *state;
+
+ if (ap_strcmp_match(r->handler, "text/html")) {
+ return DECLINED;
+ }
+ if (!(r->finfo.protection & APR_UEXECUTE)) {
+ return DECLINED;
+ }
+
+ state = (enum xbithack *) ap_get_module_config(r->per_dir_config,
+ &include_module);
+
+ if (*state == xbithack_off) {
+ return DECLINED;
+ }
+ /* We always return declined, because the default handler will actually
+ * serve the file. All we have to do is add the filter.
+ */
+ ap_add_output_filter("INCLUDES", NULL, r, r->connection);
+ return DECLINED;
+#endif
+}
+
static void register_hooks(apr_pool_t *p)
{
APR_REGISTER_OPTIONAL_FN(ap_ssi_get_tag_and_value);
APR_REGISTER_OPTIONAL_FN(ap_ssi_parse_string);
APR_REGISTER_OPTIONAL_FN(ap_register_include_handler);
ap_hook_post_config(include_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
+ ap_hook_handler(xbithack_handler, NULL, NULL, APR_HOOK_MIDDLE);
ap_register_output_filter("INCLUDES", includes_filter, AP_FTYPE_CONTENT);
}