test/ctestfile.c

Tue, 21 Apr 2015 09:47:52 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 21 Apr 2015 09:47:52 +0200
changeset 25
f82aa7afe872
child 31
50ae611a785c
permissions
-rw-r--r--

more and better test cases + fixed memory leak introduced by changeset e43dee5892f4

universe@25 1 /*
universe@25 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@25 3 *
universe@25 4 * Copyright 2015 Olaf Wintermann. All rights reserved.
universe@25 5 *
universe@25 6 * Redistribution and use in source and binary forms, with or without
universe@25 7 * modification, are permitted provided that the following conditions are met:
universe@25 8 *
universe@25 9 * 1. Redistributions of source code must retain the above copyright
universe@25 10 * notice, this list of conditions and the following disclaimer.
universe@25 11 *
universe@25 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@25 13 * notice, this list of conditions and the following disclaimer in the
universe@25 14 * documentation and/or other materials provided with the distribution.
universe@25 15 *
universe@25 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@25 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@25 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@25 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@25 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@25 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@25 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@25 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@25 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@25 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@25 26 * POSSIBILITY OF SUCH DAMAGE.
universe@25 27 */
universe@25 28
universe@25 29 #include <time.h>
universe@25 30 #include <stdio.h>
universe@25 31 #include <stdlib.h>
universe@25 32 #include <string.h>
universe@25 33 #include <ucx/string.h>
universe@25 34 #include <ucx/buffer.h>
universe@25 35 #include <ucx/utils.h>
universe@25 36 #include <libxml/tree.h>
universe@25 37 #include <curl/curl.h>
universe@25 38
universe@25 39 #include <openssl/sha.h>
universe@25 40 #include <openssl/hmac.h>
universe@25 41 #include <openssl/evp.h>
universe@25 42 #include <openssl/bio.h>
universe@25 43 #include <openssl/buffer.h>
universe@25 44 #include <openssl/rand.h>
universe@25 45
universe@25 46 #include "utils.h"
universe@25 47 #include "crypto.h"
universe@25 48 #include "webdav.h"
universe@25 49
universe@25 50
universe@25 51 time_t util_parse_creationdate(char *str) {
universe@25 52 // example: 2012-11-29T21:35:35Z
universe@25 53 if(!str) {
universe@25 54 return 0;
universe@25 55 }
universe@25 56 // TODO
universe@25 57 return 0;
universe@25 58 }
universe@25 59
universe@25 60 time_t util_parse_lastmodified(char *str) {
universe@25 61 // example: Thu, 29 Nov 2012 21:35:35 GMT
universe@25 62 if(!str) {
universe@25 63 return 0;
universe@25 64 } else {
universe@25 65 return curl_getdate(str, NULL);
universe@25 66 }
universe@25 67 }
universe@25 68
universe@25 69 int util_getboolean(char *v) {
universe@25 70 if(v[0] == 'T' || v[0] == 't') {
universe@25 71 return 1;
universe@25 72 }
universe@25 73 return 0;
universe@25 74 }
universe@25 75
universe@25 76 int util_strtoint(char *str, int64_t *value) {
universe@25 77 char *end;
universe@25 78 int64_t val = strtoll(str, &end, 0);
universe@25 79 if(strlen(end) == 0) {
universe@25 80 *value = val;
universe@25 81 return 1;
universe@25 82 } else {
universe@25 83 return 0;
universe@25 84 }
universe@25 85 }
universe@25 86
universe@25 87 char* util_url_path(char *url) {
universe@25 88 char *path = NULL;
universe@25 89 size_t len = strlen(url);
universe@25 90 int slashcount = 0;
universe@25 91 int slmax;
universe@25 92 if(len > 7 && !strncasecmp(url, "http://", 7)) {
universe@25 93 slmax = 3;
universe@25 94 } else if(len > 8 && !strncasecmp(url, "https://", 8)) {
universe@25 95 slmax = 3;
universe@25 96 } else {
universe@25 97 slmax = 1;
universe@25 98 }
universe@25 99 char c;
universe@25 100 for(int i=0;i<len;i++) {
universe@25 101 c = url[i];
universe@25 102 if(c == '/') {
universe@25 103 slashcount++;
universe@25 104 if(slashcount == slmax) {
universe@25 105 path = url + i;
universe@25 106 break;
universe@25 107 }
universe@25 108 }
universe@25 109 }
universe@25 110 return path;
universe@25 111 }
universe@25 112
universe@25 113 char* util_url_decode(DavSession *sn, char *url) {
universe@25 114 char *unesc = curl_easy_unescape(sn->handle, url, strlen(url), NULL);
universe@25 115 char *ret = strdup(unesc);
universe@25 116 curl_free(unesc);
universe@25 117 return ret;
universe@25 118 }
universe@25 119
universe@25 120 char* util_resource_name(char *url) {
universe@25 121 int si = 0;
universe@25 122 int osi = 0;
universe@25 123 int i = 0;
universe@25 124 int p = 0;
universe@25 125 char c;
universe@25 126 while((c = url[i]) != 0) {
universe@25 127 if(c == '/') {
universe@25 128 osi = si;
universe@25 129 si = i;
universe@25 130 p = 1;
universe@25 131 }
universe@25 132 i++;
universe@25 133 }
universe@25 134
universe@25 135 char *name = url + si + p;
universe@25 136 if(name[0] == 0) {
universe@25 137 name = url + osi + p;
universe@25 138 if(name[0] == 0) {
universe@25 139 return url;
universe@25 140 }
universe@25 141 }
universe@25 142
universe@25 143 return name;
universe@25 144 }
universe@25 145
universe@25 146 int util_mkdir(char *path, mode_t mode) {
universe@25 147 #ifdef _WIN32
universe@25 148 return mkdir(path);
universe@25 149 #else
universe@25 150 return mkdir(path, mode);
universe@25 151 #endif
universe@25 152 }
universe@25 153
universe@25 154 char* util_concat_path(char *url_base, char *p) {
universe@25 155 sstr_t base = sstr(url_base);
universe@25 156 sstr_t path;
universe@25 157 if(p) {
universe@25 158 path = sstr(p);
universe@25 159 } else {
universe@25 160 path = sstrn("", 0);
universe@25 161 }
universe@25 162
universe@25 163 int add_separator = 0;
universe@25 164 if(base.ptr[base.length-1] == '/') {
universe@25 165 if(path.ptr[0] == '/') {
universe@25 166 base.length--;
universe@25 167 }
universe@25 168 } else {
universe@25 169 if(path.length == 0 || path.ptr[0] != '/') {
universe@25 170 add_separator = 1;
universe@25 171 }
universe@25 172 }
universe@25 173
universe@25 174 sstr_t url;
universe@25 175 if(add_separator) {
universe@25 176 url = sstrcat(3, base, sstr("/"), path);
universe@25 177 } else {
universe@25 178 url = sstrcat(2, base, path);
universe@25 179 }
universe@25 180
universe@25 181 return url.ptr;
universe@25 182 }
universe@25 183
universe@25 184 void util_set_url(DavSession *sn, char *href) {
universe@25 185 sstr_t base = sstr(sn->base_url);
universe@25 186 sstr_t href_str = sstr(href);
universe@25 187
universe@25 188 char *base_path = util_url_path(sn->base_url);
universe@25 189 base.length -= strlen(base_path);
universe@25 190
universe@25 191 sstr_t url = sstrcat(2, base, href_str);
universe@25 192
universe@25 193 curl_easy_setopt(sn->handle, CURLOPT_URL, url.ptr);
universe@25 194 free(url.ptr);
universe@25 195 }
universe@25 196
universe@25 197 char* util_path_to_url(DavSession *sn, char *path) {
universe@25 198 char *space = malloc(256);
universe@25 199 UcxBuffer *url = ucx_buffer_new(space, 256, UCX_BUFFER_AUTOEXTEND);
universe@25 200
universe@25 201 // add base url
universe@25 202 ucx_buffer_write(sn->base_url, 1, strlen(sn->base_url), url);
universe@25 203 // remove trailing slash
universe@25 204 ucx_buffer_seek(url, -1, SEEK_CUR);
universe@25 205
universe@25 206 sstr_t p = sstr(path);
universe@25 207 ssize_t ntk = 0;
universe@25 208 sstr_t *tks = sstrsplit(p, S("/"), &ntk);
universe@25 209
universe@25 210 for(int i=0;i<ntk;i++) {
universe@25 211 sstr_t node = tks[i];
universe@25 212 if(node.length > 0) {
universe@25 213 char *esc = curl_easy_escape(sn->handle, node.ptr, node.length);
universe@25 214 ucx_buffer_putc(url, '/');
universe@25 215 ucx_buffer_write(esc, 1, strlen(esc), url);
universe@25 216 curl_free(esc);
universe@25 217 }
universe@25 218 free(node.ptr);
universe@25 219 }
universe@25 220 free(tks);
universe@25 221 if(path[p.length-1] == '/') {
universe@25 222 ucx_buffer_putc(url, '/');
universe@25 223 }
universe@25 224 ucx_buffer_putc(url, 0);
universe@25 225
universe@25 226 space = url->space;
universe@25 227 ucx_buffer_free(url);
universe@25 228
universe@25 229 return space;
universe@25 230 }
universe@25 231
universe@25 232 char* util_parent_path(char *path) {
universe@25 233 char *name = util_resource_name(path);
universe@25 234 size_t namelen = strlen(name);
universe@25 235 size_t pathlen = strlen(path);
universe@25 236 size_t parentlen = pathlen - namelen;
universe@25 237 char *parent = malloc(parentlen + 1);
universe@25 238 memcpy(parent, path, parentlen);
universe@25 239 parent[parentlen] = '\0';
universe@25 240 return parent;
universe@25 241 }
universe@25 242
universe@25 243
universe@25 244 char* util_xml_get_text(xmlNode *elm) {
universe@25 245 xmlNode *node = elm->children;
universe@25 246 while(node) {
universe@25 247 if(node->type == XML_TEXT_NODE) {
universe@25 248 return (char*)node->content;
universe@25 249 }
universe@25 250 node = node->next;
universe@25 251 }
universe@25 252 return NULL;
universe@25 253 }
universe@25 254
universe@25 255
universe@25 256 char* util_base64decode(char *in) {
universe@25 257 int len = 0;
universe@25 258 return util_base64decode_len(in, &len);
universe@25 259 }
universe@25 260
universe@25 261 char* util_base64decode_len(char* in, int *outlen) {
universe@25 262 size_t len = strlen(in);
universe@25 263 char *out = calloc(1, len);
universe@25 264
universe@25 265 BIO* b = BIO_new_mem_buf(in, len);
universe@25 266 BIO *d = BIO_new(BIO_f_base64());
universe@25 267 BIO_set_flags(d, BIO_FLAGS_BASE64_NO_NL);
universe@25 268 b = BIO_push(d, b);
universe@25 269
universe@25 270 *outlen = BIO_read(b, out, len);
universe@25 271 BIO_free_all(b);
universe@25 272
universe@25 273 return out;
universe@25 274 }
universe@25 275
universe@25 276 char* util_base64encode(char *in, size_t len) {
universe@25 277 BIO *b;
universe@25 278 BIO *e;
universe@25 279 BUF_MEM *mem;
universe@25 280
universe@25 281 e = BIO_new(BIO_f_base64());
universe@25 282 b = BIO_new(BIO_s_mem());
universe@25 283
universe@25 284 e = BIO_push(e, b);
universe@25 285 BIO_write(e, in, len);
universe@25 286 BIO_flush(e);
universe@25 287
universe@25 288 BIO_get_mem_ptr(e, &mem);
universe@25 289 char *out = malloc(mem->length);
universe@25 290 memcpy(out, mem->data, mem->length -1);
universe@25 291 out[mem->length - 1] = '\0';
universe@25 292
universe@25 293 BIO_free_all(e);
universe@25 294
universe@25 295 return out;
universe@25 296 }
universe@25 297
universe@25 298 char* util_encrypt_str(DavSession *sn, char *str, char *key) {
universe@25 299 DavKey *k = dav_context_get_key(sn->context, key);
universe@25 300 if(!k) {
universe@25 301 // TODO: session error
universe@25 302 return NULL;
universe@25 303 }
universe@25 304
universe@25 305 char *enc_str = aes_encrypt(str, k);
universe@25 306 char *ret_str = dav_session_strdup(sn, enc_str);
universe@25 307 free(enc_str);
universe@25 308 return ret_str;
universe@25 309 }
universe@25 310
universe@25 311 char* util_decrypt_str(DavSession *sn, char *str, char *key) {
universe@25 312 DavKey *k = dav_context_get_key(sn->context, key);
universe@25 313 if(!k) {
universe@25 314 // TODO: session error
universe@25 315 return NULL;
universe@25 316 }
universe@25 317
universe@25 318 char *dec_str = aes_decrypt(str, k);
universe@25 319 char *ret_str = dav_session_strdup(sn, dec_str);
universe@25 320 free(dec_str);
universe@25 321 return ret_str;
universe@25 322 }
universe@25 323
universe@25 324 char* util_random_str() {
universe@25 325 unsigned char *str = malloc(25);
universe@25 326 str[24] = '\0';
universe@25 327
universe@25 328 sstr_t t = S(
universe@25 329 "01234567890"
universe@25 330 "abcdefghijklmnopqrstuvwxyz"
universe@25 331 "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
universe@25 332 const unsigned char *table = (const unsigned char*)t.ptr;
universe@25 333
universe@25 334 RAND_pseudo_bytes(str, 24);
universe@25 335 for(int i=0;i<24;i++) {
universe@25 336 int c = str[i] % t.length;
universe@25 337 str[i] = table[c];
universe@25 338 }
universe@25 339
universe@25 340 return (char*)str;
universe@25 341 }
universe@25 342
universe@25 343 /*
universe@25 344 * gets a substring from 0 to the appearance of the token
universe@25 345 * tokens are separated by space
universe@25 346 * sets sub to the substring and returns the remaining string
universe@25 347 */
universe@25 348 sstr_t util_getsubstr_until_token(sstr_t str, sstr_t token, sstr_t *sub) {
universe@25 349 int i;
universe@25 350 int token_start = -1;
universe@25 351 int token_end = -1;
universe@25 352 for(i=0;i<=str.length;i++) {
universe@25 353 int c;
universe@25 354 if(i == str.length) {
universe@25 355 c = ' ';
universe@25 356 } else {
universe@25 357 c = str.ptr[i];
universe@25 358 }
universe@25 359 if(c < 33) {
universe@25 360 if(token_start != -1) {
universe@25 361 token_end = i;
universe@25 362 size_t len = token_end - token_start;
universe@25 363 sstr_t tk = sstrsubsl(str, token_start, len);
universe@25 364 //printf("token: {%.*s}\n", token.length, token.ptr);
universe@25 365 if(!sstrcmp(tk, token)) {
universe@25 366 *sub = sstrtrim(sstrsubsl(str, 0, token_start));
universe@25 367 break;
universe@25 368 }
universe@25 369 token_start = -1;
universe@25 370 token_end = -1;
universe@25 371 }
universe@25 372 } else {
universe@25 373 if(token_start == -1) {
universe@25 374 token_start = i;
universe@25 375 }
universe@25 376 }
universe@25 377 }
universe@25 378
universe@25 379 if(i < str.length) {
universe@25 380 return sstrtrim(sstrsubs(str, i));
universe@25 381 } else {
universe@25 382 str.ptr = NULL;
universe@25 383 str.length = 0;
universe@25 384 return str;
universe@25 385 }
universe@25 386 }

mercurial