Thu, 07 Sep 2023 10:06:04 +0200
urlencode resource href in webdav multistatus response
src/server/webdav/multistatus.c | file | annotate | diff | comparison | revisions |
--- a/src/server/webdav/multistatus.c Wed Sep 06 22:48:08 2023 +0200 +++ b/src/server/webdav/multistatus.c Thu Sep 07 10:06:04 2023 +0200 @@ -93,6 +93,9 @@ writer_putc (out, '\"'); } + +// html escape +/* static void send_string_escaped(Writer *out, cxmutstr str) { char *begin = str.ptr; char *end = begin; @@ -102,7 +105,6 @@ char c = str.ptr[i]; end = str.ptr + i; switch(c) { - /* case '"': { escape = """; esclen = 6; @@ -128,17 +130,6 @@ esclen = 4; break; } - */ - case ' ': { - escape = "%20"; - esclen = 3; - break; - } - case '&': { - escape = "%26"; - esclen = 3; - break; - } default: continue; } ptrdiff_t len = end - begin; @@ -154,6 +145,52 @@ begin = end + 1; } } +*/ + +static const char hex_ch[] = "0123456789ABCDEF"; + +static void send_string_escaped(Writer *out, cxmutstr str) { + char *begin = str.ptr; + char *end = begin; + + char escape[4]; + escape[0] = '%'; + + for(size_t i=0;i<str.length;i++) { + unsigned char c = (unsigned char)str.ptr[i]; + end = str.ptr + i; + + // check if the character must be escaped + if( (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c >= '/' && c <= '9') || + (strchr("_.\\-~", c) != NULL)) + { + continue; + } + + // convert char to hex number, escape[0] always contains '%' + escape[1] = hex_ch[(c >> 4) & 0x0F]; + escape[2] = hex_ch[c & 0x0F]; + + // write previous unescaped chars, if available + ptrdiff_t len = end - begin; + if(len > 0) { + writer_put(out, begin, len); + } + + // write escaped char + writer_put(out, escape, 3); + + // begin next chunk + begin = end + 1; + } + ptrdiff_t len = end - begin; + if(len > 0) { + writer_put(out, begin, len + 1); + begin = end + 1; + } +} static int send_property( Multistatus *ms,