Fix encoding functions (use _append for the append version); do not encode characters >= 0x80 for html.
This commit is contained in:
parent
0347a26b37
commit
c2ce9c4f53
|
@ -13,6 +13,7 @@ typedef enum {
|
|||
|
||||
|
||||
/* encodes special characters in a string and returns the new string */
|
||||
GString *string_encode_append(const gchar *str, GString *dest, encoding_t encoding);
|
||||
GString *string_encode(const gchar *str, GString *dest, encoding_t encoding);
|
||||
|
||||
#endif
|
|
@ -38,14 +38,14 @@ static const gchar encode_map_html[] = {
|
|||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50 - 50 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 60 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 70 - 70 DEL */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B0 - BF */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0 - CF */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D0 - DF */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0 - EF */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
|
||||
};
|
||||
|
||||
/* relative URI, everything except: ! ( ) * - . / 0-9 A-Z _ a-z */
|
||||
|
@ -71,7 +71,7 @@ static const gchar encode_map_uri[] = {
|
|||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
|
||||
};
|
||||
|
||||
GString *string_encode(const gchar *str, GString *dest, encoding_t encoding) {
|
||||
GString *string_encode_append(const gchar *str, GString *dest, encoding_t encoding) {
|
||||
GString *result;
|
||||
guchar *c;
|
||||
guchar *pos = NULL;
|
||||
|
@ -105,15 +105,18 @@ GString *string_encode(const gchar *str, GString *dest, encoding_t encoding) {
|
|||
}
|
||||
|
||||
if (dest) {
|
||||
gsize oldlen = dest->len;
|
||||
result = dest;
|
||||
g_string_set_size(result, dest->len + new_len);
|
||||
pos = (guchar*) result->str + oldlen;
|
||||
} else {
|
||||
result = g_string_sized_new(new_len);
|
||||
pos = (guchar*) result->str;
|
||||
}
|
||||
|
||||
switch (encoding) {
|
||||
case ENCODING_HTML:
|
||||
for (c = (guchar*)str, pos = (guchar*)(result->str+dest->len); *c != '\0'; c++) {
|
||||
for (c = (guchar*)str; *c != '\0'; c++) {
|
||||
if (map[*c]) {
|
||||
/* char needs to be encoded */
|
||||
/* &#xHH */
|
||||
|
@ -130,7 +133,7 @@ GString *string_encode(const gchar *str, GString *dest, encoding_t encoding) {
|
|||
}
|
||||
break;
|
||||
case ENCODING_HEX:
|
||||
for (c = (guchar*)str, pos = (guchar*)(result->str+dest->len); *c != '\0'; c++) {
|
||||
for (c = (guchar*)str; *c != '\0'; c++) {
|
||||
if (map[*c]) {
|
||||
/* char needs to be encoded */
|
||||
*pos++ = hex_chars[((*c) >> 4) & 0x0F];
|
||||
|
@ -142,7 +145,7 @@ GString *string_encode(const gchar *str, GString *dest, encoding_t encoding) {
|
|||
}
|
||||
break;
|
||||
case ENCODING_URI:
|
||||
for (c = (guchar*)str, pos = (guchar*)(result->str+dest->len); *c != '\0'; c++) {
|
||||
for (c = (guchar*)str; *c != '\0'; c++) {
|
||||
if (map[*c]) {
|
||||
/* char needs to be encoded */
|
||||
*pos++ = '%';
|
||||
|
@ -159,4 +162,9 @@ GString *string_encode(const gchar *str, GString *dest, encoding_t encoding) {
|
|||
*pos = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
GString *string_encode(const gchar *str, GString *dest, encoding_t encoding) {
|
||||
if (dest) g_string_truncate(dest, 0);
|
||||
return string_encode_append(str, dest, encoding);
|
||||
}
|
||||
|
|
|
@ -114,6 +114,7 @@ struct dirlist_data {
|
|||
gboolean debug;
|
||||
GPtrArray *exclude_suffix;
|
||||
GPtrArray *exclude_prefix;
|
||||
GString *content_type;
|
||||
};
|
||||
typedef struct dirlist_data dirlist_data;
|
||||
|
||||
|
@ -254,7 +255,7 @@ static handler_t dirlist(vrequest *vr, gpointer param, gpointer *context) {
|
|||
if (dd->debug)
|
||||
VR_DEBUG(vr, "dirlist for \"%s\", %u entries", sce->data.path->str, sce->dirlist->len);
|
||||
|
||||
http_header_overwrite(vr->response.headers, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
|
||||
http_header_overwrite(vr->response.headers, CONST_STR_LEN("Content-Type"), GSTR_LEN(dd->content_type));
|
||||
etag_set_header(vr, &sce->data.st, &cachable);
|
||||
if (cachable) {
|
||||
vr->response.http_status = 304;
|
||||
|
@ -430,6 +431,8 @@ static void dirlist_free(server *srv, gpointer param) {
|
|||
g_string_free(g_ptr_array_index(data->exclude_prefix, i), TRUE);
|
||||
g_ptr_array_free(data->exclude_prefix, TRUE);
|
||||
|
||||
g_string_free(data->content_type, TRUE);
|
||||
|
||||
g_slice_free(dirlist_data, data);
|
||||
}
|
||||
|
||||
|
@ -451,6 +454,7 @@ static action* dirlist_create(server *srv, plugin* p, value *val) {
|
|||
data->hide_tildefiles = TRUE;
|
||||
data->exclude_suffix = g_ptr_array_new();
|
||||
data->exclude_prefix = g_ptr_array_new();
|
||||
data->content_type = g_string_new("text/html; charset=utf-8");
|
||||
|
||||
if (val) {
|
||||
for (i = 0; i < val->data.list->len; i++) {
|
||||
|
@ -530,6 +534,13 @@ static action* dirlist_create(server *srv, plugin* p, value *val) {
|
|||
return NULL;
|
||||
}
|
||||
data->debug = v->data.boolean;
|
||||
} else if (g_str_equal(k->str, "content-type")) {
|
||||
if (v->type != VALUE_STRING) {
|
||||
ERROR(srv, "%s", "dirlist: content-type parameter must be a string");
|
||||
dirlist_free(srv, data);
|
||||
return NULL;
|
||||
}
|
||||
g_string_assign(data->content_type, v->data.string->str);
|
||||
} else {
|
||||
ERROR(srv, "dirlist: unknown parameter \"%s\"", k->str);
|
||||
dirlist_free(srv, data);
|
||||
|
|
|
@ -294,7 +294,7 @@ static gboolean rewrite_internal(vrequest *vr, GString *dest_path, GString *dest
|
|||
g_string_append_len(dest, CONST_STR_LEN("http"));
|
||||
} else {
|
||||
if (encoded)
|
||||
string_encode(str->str, dest, ENCODING_URI);
|
||||
string_encode_append(str->str, dest, ENCODING_URI);
|
||||
else
|
||||
g_string_append_len(dest, GSTR_LEN(str));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue