# HG changeset patch # User Olaf Wintermann # Date 1555408013 -7200 # Node ID f746f601c35cf8f5edf761b5e3e346d792ca6965 # Parent c36eddf167a86a7e9ce89f376f963b12569d41d4 add util_path_normalize diff -r c36eddf167a8 -r f746f601c35c libidav/utils.c --- a/libidav/utils.c Sun Apr 14 20:08:18 2019 +0200 +++ b/libidav/utils.c Tue Apr 16 11:46:53 2019 +0200 @@ -398,6 +398,64 @@ return 0; } +char* util_path_normalize(const char *path) { + size_t len = strlen(path); + UcxBuffer *buf = ucx_buffer_new(NULL, len+1, UCX_BUFFER_AUTOEXTEND); + + if(path[0] == '/') { + ucx_buffer_putc(buf, '/'); + } + + int add_separator = 0; + int seg_start = 0; + for(int i=0;i<=len;i++) { + char c = path[i]; + if(c == '/' || c == '\0') { + const char *seg_ptr = path+seg_start; + int seg_len = i - seg_start; + if(seg_ptr[0] == '/') { + seg_ptr++; + seg_len--; + } + + if(seg_len > 0) { + scstr_t seg = scstrn(seg_ptr, seg_len); + if(!sstrcmp(seg, SC(".."))) { + for(int j=buf->pos;j>=0;j--) { + char t = buf->space[j]; + if(t == '/' || j == 0) { + buf->pos = j; + buf->size = j; + buf->space[j] = 0; + add_separator = t == '/' ? 1 : 0; + break; + } + } + } else if(!sstrcmp(seg, SC("."))) { + // ignore + } else { + if(add_separator) { + ucx_buffer_putc(buf, '/'); + } + ucx_buffer_write(seg_ptr, 1, seg_len, buf); + add_separator = 1; + } + } + + seg_start = i; + } + } + + ucx_buffer_putc(buf, 0); + + + char *space = buf->space; + buf->flags = 0; // disable autofree + ucx_buffer_free(buf); + return space; +} + + void util_capture_header(CURL *handle, UcxMap* map) { if(map) { curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, util_header_callback); diff -r c36eddf167a8 -r f746f601c35c libidav/utils.h --- a/libidav/utils.h Sun Apr 14 20:08:18 2019 +0200 +++ b/libidav/utils.h Tue Apr 16 11:46:53 2019 +0200 @@ -77,6 +77,8 @@ */ int util_path_isrelated(const char *path1, const char *path2); +char* util_path_normalize(const char *path); + void util_capture_header(CURL *handle, UcxMap* map); char* util_path_to_url(DavSession *sn, char *path);