summaryrefslogtreecommitdiffstats
path: root/modules/filters/mod_xml2enc.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/filters/mod_xml2enc.c')
-rw-r--r--modules/filters/mod_xml2enc.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/modules/filters/mod_xml2enc.c b/modules/filters/mod_xml2enc.c
index 76046b4..eb05c18 100644
--- a/modules/filters/mod_xml2enc.c
+++ b/modules/filters/mod_xml2enc.c
@@ -206,11 +206,11 @@ static void sniff_encoding(request_rec* r, xml2ctx* ctx)
}
}
}
-
+
/* to sniff, first we look for BOM */
if (ctx->xml2enc == XML_CHAR_ENCODING_NONE) {
- ctx->xml2enc = xmlDetectCharEncoding((const xmlChar*)ctx->buf,
- ctx->bytes);
+ ctx->xml2enc = xmlDetectCharEncoding((const unsigned char*)ctx->buf,
+ ctx->bytes);
if (HAVE_ENCODING(ctx->xml2enc)) {
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01432)
"Got charset from XML rules.") ;
@@ -323,7 +323,7 @@ static apr_status_t xml2enc_ffunc(ap_filter_t* f, apr_bucket_brigade* bb)
apr_bucket* bstart;
apr_size_t insz = 0;
int pending_meta = 0;
- char *ctype;
+ char *mtype;
char *p;
if (!ctx || !f->r->content_type) {
@@ -332,13 +332,17 @@ static apr_status_t xml2enc_ffunc(ap_filter_t* f, apr_bucket_brigade* bb)
return ap_pass_brigade(f->next, bb) ;
}
- ctype = apr_pstrdup(f->r->pool, f->r->content_type);
- for (p = ctype; *p; ++p)
- if (isupper(*p))
- *p = tolower(*p);
-
- /* only act if starts-with "text/" or contains "xml" */
- if (strncmp(ctype, "text/", 5) && !strstr(ctype, "xml")) {
+ /* Extract the media type, ignoring parameters in content-type. */
+ mtype = apr_pstrdup(f->r->pool, f->r->content_type);
+ if ((p = ap_strchr(mtype, ';')) != NULL) *p = '\0';
+ ap_str_tolower(mtype);
+
+ /* Accept text/ types, plus any XML media type per RFC 7303. */
+ if (!(strncmp(mtype, "text/", 5) == 0
+ || strcmp(mtype, "application/xml") == 0
+ || (strlen(mtype) > 7 /* minimum 'a/b+xml' length */
+ && (p = strstr(mtype, "+xml")) != NULL
+ && strlen(p) == 4 /* ensures +xml is a suffix */))) {
ap_remove_output_filter(f);
return ap_pass_brigade(f->next, bb) ;
}