--- mod_webdav.c.orig 2005-11-05 22:04:24.000000000 +0800 +++ mod_webdav.c 2005-11-05 23:21:06.000000000 +0800 @@ -970,6 +970,93 @@ static int webdav_parse_chunkqueue(serve } #endif +static const char hex_chars[] = "0123456789abcdef"; +static int buffer_append_string_uri_encoded(buffer *b, const char *s, size_t s_len) { + unsigned char *ds, *d; + size_t d_len; + + if (!s || !b) return -1; + + if (b->ptr[b->used - 1] != '\0') { + SEGFAULT(); + } + + if (s_len == 0) return 0; + + /* count to-be-encoded-characters */ + for (ds = (unsigned char *)s, d_len = 0; *ds; ds++) { + if (*ds < 32 || *ds > 126) { + d_len += 3; + } else { + switch (*ds) { + case '$': + case '&': + case '+': + case ',': + case ':': + case ';': + case '=': + case '?': + case '@': + case ' ': + case '#': + case '%': + case '<': + case '>': + case '"': + case '\'': + d_len += 3; + break; + default: + d_len ++; + break; + } + } + } + + buffer_prepare_append(b, d_len); + + for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0; *ds; ds++) { + if (*ds < 32 || *ds > 126) { + d[d_len++] = '%'; + d[d_len++] = hex_chars[((*ds) >> 4) & 0x0F]; + d[d_len++] = hex_chars[(*ds) & 0x0F]; + } else { + switch (*ds) { + case '$': + case '&': + case '+': + case ',': + case ':': + case ';': + case '=': + case '?': + case '@': + case ' ': + case '#': + case '%': + case '<': + case '>': + case '"': + case '\'': + d[d_len++] = '%'; + d[d_len++] = hex_chars[((*ds) >> 4) & 0x0F]; + d[d_len++] = hex_chars[(*ds) & 0x0F]; + break; + default: + d[d_len++] = *ds; + break; + } + } + } + + b->ptr[b->used + d_len - 1] = '\0'; + + b->used += d_len; + + return 0; +} + URIHANDLER_FUNC(mod_webdav_subrequest_handler) { plugin_data *p = p_d; buffer *b; @@ -1111,7 +1198,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_ha buffer_append_string_buffer(b, con->uri.scheme); buffer_append_string(b,"://"); buffer_append_string_buffer(b, con->uri.authority); - buffer_append_string_buffer(b, con->uri.path); + buffer_append_string_uri_encoded(b, CONST_BUF_LEN(con->uri.path)); buffer_append_string(b,"\n"); if (!buffer_is_empty(prop_200)) { @@ -1176,7 +1263,8 @@ URIHANDLER_FUNC(mod_webdav_subrequest_ha buffer_append_string_buffer(b, con->uri.scheme); buffer_append_string(b,"://"); buffer_append_string_buffer(b, con->uri.authority); - buffer_append_string_buffer(b, d.rel_path); + buffer_append_string_uri_encoded(b, + CONST_BUF_LEN(d.rel_path)); buffer_append_string(b,"\n"); if (!buffer_is_empty(prop_200)) {