Browse Source

Fix encoding functions (use _append for the append version); do not encode characters >= 0x80 for html.

personal/stbuehler/wip
Stefan Bühler 13 years ago
parent
commit
c2ce9c4f53
  1. 1
      include/lighttpd/encoding.h
  2. 34
      src/encoding.c
  3. 13
      src/modules/mod_dirlist.c
  4. 2
      src/modules/mod_rewrite.c

1
include/lighttpd/encoding.h

@ -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

34
src/encoding.c

@ -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);
}

13
src/modules/mod_dirlist.c

@ -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);

2
src/modules/mod_rewrite.c

@ -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…
Cancel
Save