ucl_util.c (262975) | ucl_util.c (263648) |
---|---|
1/* Copyright (c) 2013, Vsevolod Stakhov 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright --- 11 unchanged lines hidden (view full) --- 20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 */ 23 24#include "ucl.h" 25#include "ucl_internal.h" 26#include "ucl_chartable.h" 27 | 1/* Copyright (c) 2013, Vsevolod Stakhov 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright --- 11 unchanged lines hidden (view full) --- 20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 */ 23 24#include "ucl.h" 25#include "ucl_internal.h" 26#include "ucl_chartable.h" 27 |
28#ifdef HAVE_LIBGEN_H |
|
28#include <libgen.h> /* For dirname */ | 29#include <libgen.h> /* For dirname */ |
30#endif |
|
29 30#ifdef HAVE_OPENSSL 31#include <openssl/err.h> 32#include <openssl/sha.h> 33#include <openssl/rsa.h> 34#include <openssl/ssl.h> 35#include <openssl/evp.h> 36#endif 37 | 31 32#ifdef HAVE_OPENSSL 33#include <openssl/err.h> 34#include <openssl/sha.h> 35#include <openssl/rsa.h> 36#include <openssl/ssl.h> 37#include <openssl/evp.h> 38#endif 39 |
40#ifdef CURL_FOUND 41#include <curl/curl.h> 42#endif 43#ifdef HAVE_FETCH_H 44#include <fetch.h> 45#endif 46 |
|
38#ifdef _WIN32 39#include <windows.h> 40 | 47#ifdef _WIN32 48#include <windows.h> 49 |
50#ifndef PROT_READ |
|
41#define PROT_READ 1 | 51#define PROT_READ 1 |
52#endif 53#ifndef PROT_WRITE |
|
42#define PROT_WRITE 2 | 54#define PROT_WRITE 2 |
55#endif 56#ifndef PROT_READWRITE |
|
43#define PROT_READWRITE 3 | 57#define PROT_READWRITE 3 |
58#endif 59#ifndef MAP_SHARED |
|
44#define MAP_SHARED 1 | 60#define MAP_SHARED 1 |
61#endif 62#ifndef MAP_PRIVATE |
|
45#define MAP_PRIVATE 2 | 63#define MAP_PRIVATE 2 |
64#endif 65#ifndef MAP_FAILED |
|
46#define MAP_FAILED ((void *) -1) | 66#define MAP_FAILED ((void *) -1) |
67#endif |
|
47 | 68 |
48static void *mmap(char *addr, size_t length, int prot, int access, int fd, off_t offset) | 69static void *ucl_mmap(char *addr, size_t length, int prot, int access, int fd, off_t offset) |
49{ 50 void *map = NULL; 51 HANDLE handle = INVALID_HANDLE_VALUE; 52 53 switch (prot) { 54 default: 55 case PROT_READ: 56 { --- 21 unchanged lines hidden (view full) --- 78 } 79 } 80 if (map == (void *) NULL) { 81 return (void *) MAP_FAILED; 82 } 83 return (void *) ((char *) map + offset); 84} 85 | 70{ 71 void *map = NULL; 72 HANDLE handle = INVALID_HANDLE_VALUE; 73 74 switch (prot) { 75 default: 76 case PROT_READ: 77 { --- 21 unchanged lines hidden (view full) --- 99 } 100 } 101 if (map == (void *) NULL) { 102 return (void *) MAP_FAILED; 103 } 104 return (void *) ((char *) map + offset); 105} 106 |
86static int munmap(void *map,size_t length) | 107static int ucl_munmap(void *map,size_t length) |
87{ 88 if (!UnmapViewOfFile(map)) { 89 return(-1); 90 } 91 return(0); 92} 93 | 108{ 109 if (!UnmapViewOfFile(map)) { 110 return(-1); 111 } 112 return(0); 113} 114 |
94static char* realpath(const char *path, char *resolved_path) { | 115static char* ucl_realpath(const char *path, char *resolved_path) { |
95 char *p; 96 char tmp[MAX_PATH + 1]; 97 strncpy(tmp, path, sizeof(tmp)-1); 98 p = tmp; 99 while(*p) { 100 if (*p == '/') *p = '\\'; 101 p++; 102 } 103 return _fullpath(resolved_path, tmp, MAX_PATH); 104} | 116 char *p; 117 char tmp[MAX_PATH + 1]; 118 strncpy(tmp, path, sizeof(tmp)-1); 119 p = tmp; 120 while(*p) { 121 if (*p == '/') *p = '\\'; 122 p++; 123 } 124 return _fullpath(resolved_path, tmp, MAX_PATH); 125} |
126#else 127#define ucl_mmap mmap 128#define ucl_munmap munmap 129#define ucl_realpath realpath |
|
105#endif 106 107/** 108 * @file rcl_util.c 109 * Utilities for rcl parsing 110 */ 111 112 --- 40 unchanged lines hidden (view full) --- 153} 154 155size_t 156ucl_unescape_json_string (char *str, size_t len) 157{ 158 char *t = str, *h = str; 159 int i, uval; 160 | 130#endif 131 132/** 133 * @file rcl_util.c 134 * Utilities for rcl parsing 135 */ 136 137 --- 40 unchanged lines hidden (view full) --- 178} 179 180size_t 181ucl_unescape_json_string (char *str, size_t len) 182{ 183 char *t = str, *h = str; 184 int i, uval; 185 |
186 if (len <= 1) { 187 return len; 188 } |
|
161 /* t is target (tortoise), h is source (hare) */ 162 163 while (len) { 164 if (*h == '\\') { 165 h ++; 166 switch (*h) { 167 case 'n': 168 *t++ = '\n'; --- 14 unchanged lines hidden (view full) --- 183 *t++ = '\\'; 184 break; 185 case '"': 186 *t++ = '"'; 187 break; 188 case 'u': 189 /* Unicode escape */ 190 uval = 0; | 189 /* t is target (tortoise), h is source (hare) */ 190 191 while (len) { 192 if (*h == '\\') { 193 h ++; 194 switch (*h) { 195 case 'n': 196 *t++ = '\n'; --- 14 unchanged lines hidden (view full) --- 211 *t++ = '\\'; 212 break; 213 case '"': 214 *t++ = '"'; 215 break; 216 case 'u': 217 /* Unicode escape */ 218 uval = 0; |
191 for (i = 0; i < 4; i++) { 192 uval <<= 4; 193 if (isdigit (h[i])) { 194 uval += h[i] - '0'; | 219 if (len > 3) { 220 for (i = 0; i < 4; i++) { 221 uval <<= 4; 222 if (isdigit (h[i])) { 223 uval += h[i] - '0'; 224 } 225 else if (h[i] >= 'a' && h[i] <= 'f') { 226 uval += h[i] - 'a' + 10; 227 } 228 else if (h[i] >= 'A' && h[i] <= 'F') { 229 uval += h[i] - 'A' + 10; 230 } 231 else { 232 break; 233 } |
195 } | 234 } |
196 else if (h[i] >= 'a' && h[i] <= 'f') { 197 uval += h[i] - 'a' + 10; | 235 h += 3; 236 len -= 3; 237 /* Encode */ 238 if(uval < 0x80) { 239 t[0] = (char)uval; 240 t ++; |
198 } | 241 } |
199 else if (h[i] >= 'A' && h[i] <= 'F') { 200 uval += h[i] - 'A' + 10; | 242 else if(uval < 0x800) { 243 t[0] = 0xC0 + ((uval & 0x7C0) >> 6); 244 t[1] = 0x80 + ((uval & 0x03F)); 245 t += 2; |
201 } | 246 } |
247 else if(uval < 0x10000) { 248 t[0] = 0xE0 + ((uval & 0xF000) >> 12); 249 t[1] = 0x80 + ((uval & 0x0FC0) >> 6); 250 t[2] = 0x80 + ((uval & 0x003F)); 251 t += 3; 252 } 253 else if(uval <= 0x10FFFF) { 254 t[0] = 0xF0 + ((uval & 0x1C0000) >> 18); 255 t[1] = 0x80 + ((uval & 0x03F000) >> 12); 256 t[2] = 0x80 + ((uval & 0x000FC0) >> 6); 257 t[3] = 0x80 + ((uval & 0x00003F)); 258 t += 4; 259 } 260 else { 261 *t++ = '?'; 262 } |
|
202 } | 263 } |
203 h += 3; 204 len -= 3; 205 /* Encode */ 206 if(uval < 0x80) { 207 t[0] = (char)uval; 208 t ++; 209 } 210 else if(uval < 0x800) { 211 t[0] = 0xC0 + ((uval & 0x7C0) >> 6); 212 t[1] = 0x80 + ((uval & 0x03F)); 213 t += 2; 214 } 215 else if(uval < 0x10000) { 216 t[0] = 0xE0 + ((uval & 0xF000) >> 12); 217 t[1] = 0x80 + ((uval & 0x0FC0) >> 6); 218 t[2] = 0x80 + ((uval & 0x003F)); 219 t += 3; 220 } 221 else if(uval <= 0x10FFFF) { 222 t[0] = 0xF0 + ((uval & 0x1C0000) >> 18); 223 t[1] = 0x80 + ((uval & 0x03F000) >> 12); 224 t[2] = 0x80 + ((uval & 0x000FC0) >> 6); 225 t[3] = 0x80 + ((uval & 0x00003F)); 226 t += 4; 227 } | |
228 else { | 264 else { |
229 *t++ = '?'; | 265 *t++ = 'u'; |
230 } 231 break; 232 default: 233 *t++ = *h; 234 break; 235 } 236 h ++; 237 len --; --- 6 unchanged lines hidden (view full) --- 244 *t = '\0'; 245 246 return (t - str); 247} 248 249UCL_EXTERN char * 250ucl_copy_key_trash (ucl_object_t *obj) 251{ | 266 } 267 break; 268 default: 269 *t++ = *h; 270 break; 271 } 272 h ++; 273 len --; --- 6 unchanged lines hidden (view full) --- 280 *t = '\0'; 281 282 return (t - str); 283} 284 285UCL_EXTERN char * 286ucl_copy_key_trash (ucl_object_t *obj) 287{ |
288 if (obj == NULL) { 289 return NULL; 290 } |
|
252 if (obj->trash_stack[UCL_TRASH_KEY] == NULL && obj->key != NULL) { 253 obj->trash_stack[UCL_TRASH_KEY] = malloc (obj->keylen + 1); 254 if (obj->trash_stack[UCL_TRASH_KEY] != NULL) { 255 memcpy (obj->trash_stack[UCL_TRASH_KEY], obj->key, obj->keylen); 256 obj->trash_stack[UCL_TRASH_KEY][obj->keylen] = '\0'; 257 } 258 obj->key = obj->trash_stack[UCL_TRASH_KEY]; 259 obj->flags |= UCL_OBJECT_ALLOCATED_KEY; 260 } 261 262 return obj->trash_stack[UCL_TRASH_KEY]; 263} 264 265UCL_EXTERN char * 266ucl_copy_value_trash (ucl_object_t *obj) 267{ | 291 if (obj->trash_stack[UCL_TRASH_KEY] == NULL && obj->key != NULL) { 292 obj->trash_stack[UCL_TRASH_KEY] = malloc (obj->keylen + 1); 293 if (obj->trash_stack[UCL_TRASH_KEY] != NULL) { 294 memcpy (obj->trash_stack[UCL_TRASH_KEY], obj->key, obj->keylen); 295 obj->trash_stack[UCL_TRASH_KEY][obj->keylen] = '\0'; 296 } 297 obj->key = obj->trash_stack[UCL_TRASH_KEY]; 298 obj->flags |= UCL_OBJECT_ALLOCATED_KEY; 299 } 300 301 return obj->trash_stack[UCL_TRASH_KEY]; 302} 303 304UCL_EXTERN char * 305ucl_copy_value_trash (ucl_object_t *obj) 306{ |
307 if (obj == NULL) { 308 return NULL; 309 } |
|
268 if (obj->trash_stack[UCL_TRASH_VALUE] == NULL) { 269 if (obj->type == UCL_STRING) { 270 /* Special case for strings */ 271 obj->trash_stack[UCL_TRASH_VALUE] = malloc (obj->len + 1); 272 if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) { 273 memcpy (obj->trash_stack[UCL_TRASH_VALUE], obj->value.sv, obj->len); 274 obj->trash_stack[UCL_TRASH_VALUE][obj->len] = '\0'; 275 obj->value.sv = obj->trash_stack[UCL_TRASH_VALUE]; --- 23 unchanged lines hidden (view full) --- 299ucl_parser_free (struct ucl_parser *parser) 300{ 301 struct ucl_stack *stack, *stmp; 302 struct ucl_macro *macro, *mtmp; 303 struct ucl_chunk *chunk, *ctmp; 304 struct ucl_pubkey *key, *ktmp; 305 struct ucl_variable *var, *vtmp; 306 | 310 if (obj->trash_stack[UCL_TRASH_VALUE] == NULL) { 311 if (obj->type == UCL_STRING) { 312 /* Special case for strings */ 313 obj->trash_stack[UCL_TRASH_VALUE] = malloc (obj->len + 1); 314 if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) { 315 memcpy (obj->trash_stack[UCL_TRASH_VALUE], obj->value.sv, obj->len); 316 obj->trash_stack[UCL_TRASH_VALUE][obj->len] = '\0'; 317 obj->value.sv = obj->trash_stack[UCL_TRASH_VALUE]; --- 23 unchanged lines hidden (view full) --- 341ucl_parser_free (struct ucl_parser *parser) 342{ 343 struct ucl_stack *stack, *stmp; 344 struct ucl_macro *macro, *mtmp; 345 struct ucl_chunk *chunk, *ctmp; 346 struct ucl_pubkey *key, *ktmp; 347 struct ucl_variable *var, *vtmp; 348 |
349 if (parser == NULL) { 350 return; 351 } 352 |
|
307 if (parser->top_obj != NULL) { 308 ucl_object_unref (parser->top_obj); 309 } 310 311 LL_FOREACH_SAFE (parser->stack, stack, stmp) { 312 free (stack); 313 } 314 HASH_ITER (hh, parser->macroes, macro, mtmp) { --- 18 unchanged lines hidden (view full) --- 333 } 334 335 UCL_FREE (sizeof (struct ucl_parser), parser); 336} 337 338UCL_EXTERN const char * 339ucl_parser_get_error(struct ucl_parser *parser) 340{ | 353 if (parser->top_obj != NULL) { 354 ucl_object_unref (parser->top_obj); 355 } 356 357 LL_FOREACH_SAFE (parser->stack, stack, stmp) { 358 free (stack); 359 } 360 HASH_ITER (hh, parser->macroes, macro, mtmp) { --- 18 unchanged lines hidden (view full) --- 379 } 380 381 UCL_FREE (sizeof (struct ucl_parser), parser); 382} 383 384UCL_EXTERN const char * 385ucl_parser_get_error(struct ucl_parser *parser) 386{ |
387 if (parser == NULL) { 388 return NULL; 389 } 390 |
|
341 if (parser->err == NULL) 342 return NULL; 343 344 return utstring_body(parser->err); 345} 346 347UCL_EXTERN bool 348ucl_pubkey_add (struct ucl_parser *parser, const unsigned char *key, size_t len) --- 6 unchanged lines hidden (view full) --- 355 ucl_create_err (&parser->err, "cannot check signatures, openssl version is unsupported"); 356 return EXIT_FAILURE; 357# else 358 struct ucl_pubkey *nkey; 359 BIO *mem; 360 361 mem = BIO_new_mem_buf ((void *)key, len); 362 nkey = UCL_ALLOC (sizeof (struct ucl_pubkey)); | 391 if (parser->err == NULL) 392 return NULL; 393 394 return utstring_body(parser->err); 395} 396 397UCL_EXTERN bool 398ucl_pubkey_add (struct ucl_parser *parser, const unsigned char *key, size_t len) --- 6 unchanged lines hidden (view full) --- 405 ucl_create_err (&parser->err, "cannot check signatures, openssl version is unsupported"); 406 return EXIT_FAILURE; 407# else 408 struct ucl_pubkey *nkey; 409 BIO *mem; 410 411 mem = BIO_new_mem_buf ((void *)key, len); 412 nkey = UCL_ALLOC (sizeof (struct ucl_pubkey)); |
413 if (nkey == NULL) { 414 ucl_create_err (&parser->err, "cannot allocate memory for key"); 415 return false; 416 } |
|
363 nkey->key = PEM_read_bio_PUBKEY (mem, &nkey->key, NULL, NULL); 364 BIO_free (mem); 365 if (nkey->key == NULL) { 366 UCL_FREE (sizeof (struct ucl_pubkey), nkey); 367 ucl_create_err (&parser->err, "%s", 368 ERR_error_string (ERR_get_error (), NULL)); 369 return false; 370 } --- 151 unchanged lines hidden (view full) --- 522 *buflen = 0; 523 } 524 else { 525 if ((fd = open (filename, O_RDONLY)) == -1) { 526 ucl_create_err (err, "cannot open file %s: %s", 527 filename, strerror (errno)); 528 return false; 529 } | 417 nkey->key = PEM_read_bio_PUBKEY (mem, &nkey->key, NULL, NULL); 418 BIO_free (mem); 419 if (nkey->key == NULL) { 420 UCL_FREE (sizeof (struct ucl_pubkey), nkey); 421 ucl_create_err (&parser->err, "%s", 422 ERR_error_string (ERR_get_error (), NULL)); 423 return false; 424 } --- 151 unchanged lines hidden (view full) --- 576 *buflen = 0; 577 } 578 else { 579 if ((fd = open (filename, O_RDONLY)) == -1) { 580 ucl_create_err (err, "cannot open file %s: %s", 581 filename, strerror (errno)); 582 return false; 583 } |
530 if ((*buf = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { | 584 if ((*buf = ucl_mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { |
531 close (fd); 532 ucl_create_err (err, "cannot mmap file %s: %s", 533 filename, strerror (errno)); 534 return false; 535 } 536 *buflen = st.st_size; 537 close (fd); 538 } --- 85 unchanged lines hidden (view full) --- 624 if (!ucl_fetch_url (urlbuf, &sigbuf, &siglen, &parser->err, true)) { 625 return false; 626 } 627 if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) { 628 ucl_create_err (&parser->err, "cannot verify url %s: %s", 629 urlbuf, 630 ERR_error_string (ERR_get_error (), NULL)); 631 if (siglen > 0) { | 585 close (fd); 586 ucl_create_err (err, "cannot mmap file %s: %s", 587 filename, strerror (errno)); 588 return false; 589 } 590 *buflen = st.st_size; 591 close (fd); 592 } --- 85 unchanged lines hidden (view full) --- 678 if (!ucl_fetch_url (urlbuf, &sigbuf, &siglen, &parser->err, true)) { 679 return false; 680 } 681 if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) { 682 ucl_create_err (&parser->err, "cannot verify url %s: %s", 683 urlbuf, 684 ERR_error_string (ERR_get_error (), NULL)); 685 if (siglen > 0) { |
632 munmap (sigbuf, siglen); | 686 ucl_munmap (sigbuf, siglen); |
633 } 634 return false; 635 } 636 if (siglen > 0) { | 687 } 688 return false; 689 } 690 if (siglen > 0) { |
637 munmap (sigbuf, siglen); | 691 ucl_munmap (sigbuf, siglen); |
638 } 639#endif 640 } 641 642 prev_state = parser->state; 643 parser->state = UCL_STATE_INIT; 644 645 res = ucl_parser_add_chunk (parser, buf, buflen); --- 27 unchanged lines hidden (view full) --- 673 bool res; 674 struct ucl_chunk *chunk; 675 unsigned char *buf = NULL; 676 size_t buflen; 677 char filebuf[PATH_MAX], realbuf[PATH_MAX]; 678 int prev_state; 679 680 snprintf (filebuf, sizeof (filebuf), "%.*s", (int)len, data); | 692 } 693#endif 694 } 695 696 prev_state = parser->state; 697 parser->state = UCL_STATE_INIT; 698 699 res = ucl_parser_add_chunk (parser, buf, buflen); --- 27 unchanged lines hidden (view full) --- 727 bool res; 728 struct ucl_chunk *chunk; 729 unsigned char *buf = NULL; 730 size_t buflen; 731 char filebuf[PATH_MAX], realbuf[PATH_MAX]; 732 int prev_state; 733 734 snprintf (filebuf, sizeof (filebuf), "%.*s", (int)len, data); |
681 if (realpath (filebuf, realbuf) == NULL) { | 735 if (ucl_realpath (filebuf, realbuf) == NULL) { |
682 if (!must_exist) { 683 return true; 684 } 685 ucl_create_err (&parser->err, "cannot open file %s: %s", 686 filebuf, 687 strerror (errno)); 688 return false; 689 } --- 11 unchanged lines hidden (view full) --- 701 if (!ucl_fetch_file (filebuf, &sigbuf, &siglen, &parser->err, true)) { 702 return false; 703 } 704 if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) { 705 ucl_create_err (&parser->err, "cannot verify file %s: %s", 706 filebuf, 707 ERR_error_string (ERR_get_error (), NULL)); 708 if (siglen > 0) { | 736 if (!must_exist) { 737 return true; 738 } 739 ucl_create_err (&parser->err, "cannot open file %s: %s", 740 filebuf, 741 strerror (errno)); 742 return false; 743 } --- 11 unchanged lines hidden (view full) --- 755 if (!ucl_fetch_file (filebuf, &sigbuf, &siglen, &parser->err, true)) { 756 return false; 757 } 758 if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) { 759 ucl_create_err (&parser->err, "cannot verify file %s: %s", 760 filebuf, 761 ERR_error_string (ERR_get_error (), NULL)); 762 if (siglen > 0) { |
709 munmap (sigbuf, siglen); | 763 ucl_munmap (sigbuf, siglen); |
710 } 711 return false; 712 } 713 if (siglen > 0) { | 764 } 765 return false; 766 } 767 if (siglen > 0) { |
714 munmap (sigbuf, siglen); | 768 ucl_munmap (sigbuf, siglen); |
715 } 716#endif 717 } 718 719 ucl_parser_set_filevars (parser, realbuf, false); 720 721 prev_state = parser->state; 722 parser->state = UCL_STATE_INIT; --- 6 unchanged lines hidden (view full) --- 729 parser->chunks = chunk->next; 730 UCL_FREE (sizeof (struct ucl_chunk), chunk); 731 } 732 } 733 734 parser->state = prev_state; 735 736 if (buflen > 0) { | 769 } 770#endif 771 } 772 773 ucl_parser_set_filevars (parser, realbuf, false); 774 775 prev_state = parser->state; 776 parser->state = UCL_STATE_INIT; --- 6 unchanged lines hidden (view full) --- 783 parser->chunks = chunk->next; 784 UCL_FREE (sizeof (struct ucl_chunk), chunk); 785 } 786 } 787 788 parser->state = prev_state; 789 790 if (buflen > 0) { |
737 munmap (buf, buflen); | 791 ucl_munmap (buf, buflen); |
738 } 739 740 return res; 741} 742 743/** 744 * Handle include macro 745 * @param data include data --- 52 unchanged lines hidden (view full) --- 798 799UCL_EXTERN bool 800ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename, bool need_expand) 801{ 802 char realbuf[PATH_MAX], *curdir; 803 804 if (filename != NULL) { 805 if (need_expand) { | 792 } 793 794 return res; 795} 796 797/** 798 * Handle include macro 799 * @param data include data --- 52 unchanged lines hidden (view full) --- 852 853UCL_EXTERN bool 854ucl_parser_set_filevars (struct ucl_parser *parser, const char *filename, bool need_expand) 855{ 856 char realbuf[PATH_MAX], *curdir; 857 858 if (filename != NULL) { 859 if (need_expand) { |
806 if (realpath (filename, realbuf) == NULL) { | 860 if (ucl_realpath (filename, realbuf) == NULL) { |
807 return false; 808 } 809 } 810 else { 811 ucl_strlcpy (realbuf, filename, sizeof (realbuf)); 812 } 813 814 /* Define variables */ --- 14 unchanged lines hidden (view full) --- 829UCL_EXTERN bool 830ucl_parser_add_file (struct ucl_parser *parser, const char *filename) 831{ 832 unsigned char *buf; 833 size_t len; 834 bool ret; 835 char realbuf[PATH_MAX]; 836 | 861 return false; 862 } 863 } 864 else { 865 ucl_strlcpy (realbuf, filename, sizeof (realbuf)); 866 } 867 868 /* Define variables */ --- 14 unchanged lines hidden (view full) --- 883UCL_EXTERN bool 884ucl_parser_add_file (struct ucl_parser *parser, const char *filename) 885{ 886 unsigned char *buf; 887 size_t len; 888 bool ret; 889 char realbuf[PATH_MAX]; 890 |
837 if (realpath (filename, realbuf) == NULL) { | 891 if (ucl_realpath (filename, realbuf) == NULL) { |
838 ucl_create_err (&parser->err, "cannot open file %s: %s", 839 filename, 840 strerror (errno)); 841 return false; 842 } 843 844 if (!ucl_fetch_file (realbuf, &buf, &len, &parser->err, true)) { 845 return false; 846 } 847 848 ucl_parser_set_filevars (parser, realbuf, false); 849 ret = ucl_parser_add_chunk (parser, buf, len); 850 851 if (len > 0) { | 892 ucl_create_err (&parser->err, "cannot open file %s: %s", 893 filename, 894 strerror (errno)); 895 return false; 896 } 897 898 if (!ucl_fetch_file (realbuf, &buf, &len, &parser->err, true)) { 899 return false; 900 } 901 902 ucl_parser_set_filevars (parser, realbuf, false); 903 ret = ucl_parser_add_chunk (parser, buf, len); 904 905 if (len > 0) { |
852 munmap (buf, len); | 906 ucl_munmap (buf, len); |
853 } 854 855 return ret; 856} 857 858size_t 859ucl_strlcpy (char *dst, const char *src, size_t siz) 860{ --- 148 unchanged lines hidden (view full) --- 1009 } 1010 } 1011 if ((flags & UCL_STRING_PARSE) && dst != NULL) { 1012 /* Parse what we have */ 1013 if (flags & UCL_STRING_PARSE_BOOLEAN) { 1014 if (!ucl_maybe_parse_boolean (obj, dst, obj->len) && (flags & UCL_STRING_PARSE_NUMBER)) { 1015 ucl_maybe_parse_number (obj, dst, dst + obj->len, &pos, 1016 flags & UCL_STRING_PARSE_DOUBLE, | 907 } 908 909 return ret; 910} 911 912size_t 913ucl_strlcpy (char *dst, const char *src, size_t siz) 914{ --- 148 unchanged lines hidden (view full) --- 1063 } 1064 } 1065 if ((flags & UCL_STRING_PARSE) && dst != NULL) { 1066 /* Parse what we have */ 1067 if (flags & UCL_STRING_PARSE_BOOLEAN) { 1068 if (!ucl_maybe_parse_boolean (obj, dst, obj->len) && (flags & UCL_STRING_PARSE_NUMBER)) { 1069 ucl_maybe_parse_number (obj, dst, dst + obj->len, &pos, 1070 flags & UCL_STRING_PARSE_DOUBLE, |
1017 flags & UCL_STRING_PARSE_BYTES); | 1071 flags & UCL_STRING_PARSE_BYTES, 1072 flags & UCL_STRING_PARSE_TIME); |
1018 } 1019 } 1020 else { 1021 ucl_maybe_parse_number (obj, dst, dst + obj->len, &pos, 1022 flags & UCL_STRING_PARSE_DOUBLE, | 1073 } 1074 } 1075 else { 1076 ucl_maybe_parse_number (obj, dst, dst + obj->len, &pos, 1077 flags & UCL_STRING_PARSE_DOUBLE, |
1023 flags & UCL_STRING_PARSE_BYTES); | 1078 flags & UCL_STRING_PARSE_BYTES, 1079 flags & UCL_STRING_PARSE_TIME); |
1024 } 1025 } 1026 } 1027 1028 return obj; 1029} 1030 1031static ucl_object_t * --- 46 unchanged lines hidden (view full) --- 1078 ucl_copy_key_trash (elt); 1079 } 1080 1081 found = ucl_hash_search_obj (top->value.ov, elt); 1082 1083 if (!found) { 1084 top->value.ov = ucl_hash_insert_object (top->value.ov, elt); 1085 DL_APPEND (found, elt); | 1080 } 1081 } 1082 } 1083 1084 return obj; 1085} 1086 1087static ucl_object_t * --- 46 unchanged lines hidden (view full) --- 1134 ucl_copy_key_trash (elt); 1135 } 1136 1137 found = ucl_hash_search_obj (top->value.ov, elt); 1138 1139 if (!found) { 1140 top->value.ov = ucl_hash_insert_object (top->value.ov, elt); 1141 DL_APPEND (found, elt); |
1142 top->len ++; |
|
1086 } 1087 else { 1088 if (replace) { 1089 ucl_hash_delete (top->value.ov, found); 1090 ucl_object_unref (found); 1091 top->value.ov = ucl_hash_insert_object (top->value.ov, elt); 1092 found = NULL; 1093 DL_APPEND (found, elt); --- 30 unchanged lines hidden (view full) --- 1124 return top; 1125} 1126 1127bool 1128ucl_object_delete_keyl(ucl_object_t *top, const char *key, size_t keylen) 1129{ 1130 ucl_object_t *found; 1131 | 1143 } 1144 else { 1145 if (replace) { 1146 ucl_hash_delete (top->value.ov, found); 1147 ucl_object_unref (found); 1148 top->value.ov = ucl_hash_insert_object (top->value.ov, elt); 1149 found = NULL; 1150 DL_APPEND (found, elt); --- 30 unchanged lines hidden (view full) --- 1181 return top; 1182} 1183 1184bool 1185ucl_object_delete_keyl(ucl_object_t *top, const char *key, size_t keylen) 1186{ 1187 ucl_object_t *found; 1188 |
1189 if (top == NULL || key == NULL) { 1190 return false; 1191 } 1192 |
|
1132 found = ucl_object_find_keyl(top, key, keylen); 1133 | 1193 found = ucl_object_find_keyl(top, key, keylen); 1194 |
1134 if (found == NULL) | 1195 if (found == NULL) { |
1135 return false; | 1196 return false; |
1197 } |
|
1136 1137 ucl_hash_delete(top->value.ov, found); 1138 ucl_object_unref (found); 1139 top->len --; 1140 1141 return true; 1142} 1143 1144bool 1145ucl_object_delete_key(ucl_object_t *top, const char *key) 1146{ 1147 return ucl_object_delete_keyl(top, key, 0); 1148} 1149 | 1198 1199 ucl_hash_delete(top->value.ov, found); 1200 ucl_object_unref (found); 1201 top->len --; 1202 1203 return true; 1204} 1205 1206bool 1207ucl_object_delete_key(ucl_object_t *top, const char *key) 1208{ 1209 return ucl_object_delete_keyl(top, key, 0); 1210} 1211 |
1212ucl_object_t* 1213ucl_object_pop_keyl (ucl_object_t *top, const char *key, size_t keylen) 1214{ 1215 ucl_object_t *found; 1216 1217 if (top == NULL || key == NULL) { 1218 return false; 1219 } 1220 found = ucl_object_find_keyl(top, key, keylen); 1221 1222 if (found == NULL) { 1223 return NULL; 1224 } 1225 ucl_hash_delete(top->value.ov, found); 1226 top->len --; 1227 1228 return found; 1229} 1230 1231ucl_object_t* 1232ucl_object_pop_key (ucl_object_t *top, const char *key) 1233{ 1234 return ucl_object_pop_keyl (top, key, 0); 1235} 1236 |
|
1150ucl_object_t * 1151ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, 1152 const char *key, size_t keylen, bool copy_key) 1153{ 1154 return ucl_object_insert_key_common (top, elt, key, keylen, copy_key, false, false); 1155} 1156 1157ucl_object_t * --- 44 unchanged lines hidden (view full) --- 1202 return ret; 1203} 1204 1205ucl_object_t* 1206ucl_iterate_object (ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values) 1207{ 1208 ucl_object_t *elt; 1209 | 1237ucl_object_t * 1238ucl_object_insert_key (ucl_object_t *top, ucl_object_t *elt, 1239 const char *key, size_t keylen, bool copy_key) 1240{ 1241 return ucl_object_insert_key_common (top, elt, key, keylen, copy_key, false, false); 1242} 1243 1244ucl_object_t * --- 44 unchanged lines hidden (view full) --- 1289 return ret; 1290} 1291 1292ucl_object_t* 1293ucl_iterate_object (ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values) 1294{ 1295 ucl_object_t *elt; 1296 |
1297 if (obj == NULL || iter == NULL) { 1298 return NULL; 1299 } 1300 |
|
1210 if (expand_values) { 1211 switch (obj->type) { 1212 case UCL_OBJECT: 1213 return (ucl_object_t*)ucl_hash_iterate (obj->value.ov, iter); 1214 break; 1215 case UCL_ARRAY: 1216 elt = *iter; 1217 if (elt == NULL) { --- 24 unchanged lines hidden (view full) --- 1242 return NULL; 1243 } 1244 *iter = elt->next ? elt->next : obj; 1245 return elt; 1246 1247 /* Not reached */ 1248 return NULL; 1249} | 1301 if (expand_values) { 1302 switch (obj->type) { 1303 case UCL_OBJECT: 1304 return (ucl_object_t*)ucl_hash_iterate (obj->value.ov, iter); 1305 break; 1306 case UCL_ARRAY: 1307 elt = *iter; 1308 if (elt == NULL) { --- 24 unchanged lines hidden (view full) --- 1333 return NULL; 1334 } 1335 *iter = elt->next ? elt->next : obj; 1336 return elt; 1337 1338 /* Not reached */ 1339 return NULL; 1340} |
1341 1342 1343ucl_object_t * 1344ucl_object_new (void) 1345{ 1346 ucl_object_t *new; 1347 new = malloc (sizeof (ucl_object_t)); 1348 if (new != NULL) { 1349 memset (new, 0, sizeof (ucl_object_t)); 1350 new->ref = 1; 1351 new->type = UCL_NULL; 1352 } 1353 return new; 1354} 1355 1356ucl_object_t * 1357ucl_object_typed_new (unsigned int type) 1358{ 1359 ucl_object_t *new; 1360 new = malloc (sizeof (ucl_object_t)); 1361 if (new != NULL) { 1362 memset (new, 0, sizeof (ucl_object_t)); 1363 new->ref = 1; 1364 new->type = (type <= UCL_NULL ? type : UCL_NULL); 1365 } 1366 return new; 1367} 1368 1369ucl_object_t* 1370ucl_object_fromstring (const char *str) 1371{ 1372 return ucl_object_fromstring_common (str, 0, UCL_STRING_ESCAPE); 1373} 1374 1375ucl_object_t * 1376ucl_object_fromlstring (const char *str, size_t len) 1377{ 1378 return ucl_object_fromstring_common (str, len, UCL_STRING_ESCAPE); 1379} 1380 1381ucl_object_t * 1382ucl_object_fromint (int64_t iv) 1383{ 1384 ucl_object_t *obj; 1385 1386 obj = ucl_object_new (); 1387 if (obj != NULL) { 1388 obj->type = UCL_INT; 1389 obj->value.iv = iv; 1390 } 1391 1392 return obj; 1393} 1394 1395ucl_object_t * 1396ucl_object_fromdouble (double dv) 1397{ 1398 ucl_object_t *obj; 1399 1400 obj = ucl_object_new (); 1401 if (obj != NULL) { 1402 obj->type = UCL_FLOAT; 1403 obj->value.dv = dv; 1404 } 1405 1406 return obj; 1407} 1408 1409ucl_object_t* 1410ucl_object_frombool (bool bv) 1411{ 1412 ucl_object_t *obj; 1413 1414 obj = ucl_object_new (); 1415 if (obj != NULL) { 1416 obj->type = UCL_BOOLEAN; 1417 obj->value.iv = bv; 1418 } 1419 1420 return obj; 1421} 1422 1423ucl_object_t * 1424ucl_array_append (ucl_object_t *top, ucl_object_t *elt) 1425{ 1426 ucl_object_t *head; 1427 1428 if (elt == NULL) { 1429 return NULL; 1430 } 1431 1432 if (top == NULL) { 1433 top = ucl_object_typed_new (UCL_ARRAY); 1434 top->value.av = elt; 1435 elt->next = NULL; 1436 elt->prev = elt; 1437 top->len = 1; 1438 } 1439 else { 1440 head = top->value.av; 1441 if (head == NULL) { 1442 top->value.av = elt; 1443 elt->prev = elt; 1444 } 1445 else { 1446 elt->prev = head->prev; 1447 head->prev->next = elt; 1448 head->prev = elt; 1449 } 1450 elt->next = NULL; 1451 top->len ++; 1452 } 1453 1454 return top; 1455} 1456 1457ucl_object_t * 1458ucl_array_prepend (ucl_object_t *top, ucl_object_t *elt) 1459{ 1460 ucl_object_t *head; 1461 1462 if (elt == NULL) { 1463 return NULL; 1464 } 1465 1466 if (top == NULL) { 1467 top = ucl_object_typed_new (UCL_ARRAY); 1468 top->value.av = elt; 1469 elt->next = NULL; 1470 elt->prev = elt; 1471 top->len = 1; 1472 } 1473 else { 1474 head = top->value.av; 1475 if (head == NULL) { 1476 top->value.av = elt; 1477 elt->prev = elt; 1478 } 1479 else { 1480 elt->prev = head->prev; 1481 head->prev = elt; 1482 } 1483 elt->next = head; 1484 top->value.av = elt; 1485 top->len ++; 1486 } 1487 1488 return top; 1489} 1490 1491ucl_object_t * 1492ucl_array_delete (ucl_object_t *top, ucl_object_t *elt) 1493{ 1494 ucl_object_t *head; 1495 1496 if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 1497 return NULL; 1498 } 1499 head = top->value.av; 1500 1501 if (elt->prev == elt) { 1502 top->value.av = NULL; 1503 } 1504 else if (elt == head) { 1505 elt->next->prev = elt->prev; 1506 top->value.av = elt->next; 1507 } 1508 else { 1509 elt->prev->next = elt->next; 1510 if (elt->next) { 1511 elt->next->prev = elt->prev; 1512 } 1513 else { 1514 head->prev = elt->prev; 1515 } 1516 } 1517 elt->next = NULL; 1518 elt->prev = elt; 1519 top->len --; 1520 1521 return elt; 1522} 1523 1524ucl_object_t * 1525ucl_array_head (ucl_object_t *top) 1526{ 1527 if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 1528 return NULL; 1529 } 1530 return top->value.av; 1531} 1532 1533ucl_object_t * 1534ucl_array_tail (ucl_object_t *top) 1535{ 1536 if (top == NULL || top->type != UCL_ARRAY || top->value.av == NULL) { 1537 return NULL; 1538 } 1539 return top->value.av->prev; 1540} 1541 1542ucl_object_t * 1543ucl_array_pop_last (ucl_object_t *top) 1544{ 1545 return ucl_array_delete (top, ucl_array_tail (top)); 1546} 1547 1548ucl_object_t * 1549ucl_array_pop_first (ucl_object_t *top) 1550{ 1551 return ucl_array_delete (top, ucl_array_head (top)); 1552} 1553 1554ucl_object_t * 1555ucl_elt_append (ucl_object_t *head, ucl_object_t *elt) 1556{ 1557 1558 if (head == NULL) { 1559 elt->next = NULL; 1560 elt->prev = elt; 1561 head = elt; 1562 } 1563 else { 1564 elt->prev = head->prev; 1565 head->prev->next = elt; 1566 head->prev = elt; 1567 elt->next = NULL; 1568 } 1569 1570 return head; 1571} 1572 1573bool 1574ucl_object_todouble_safe (ucl_object_t *obj, double *target) 1575{ 1576 if (obj == NULL || target == NULL) { 1577 return false; 1578 } 1579 switch (obj->type) { 1580 case UCL_INT: 1581 *target = obj->value.iv; /* Probaly could cause overflow */ 1582 break; 1583 case UCL_FLOAT: 1584 case UCL_TIME: 1585 *target = obj->value.dv; 1586 break; 1587 default: 1588 return false; 1589 } 1590 1591 return true; 1592} 1593 1594double 1595ucl_object_todouble (ucl_object_t *obj) 1596{ 1597 double result = 0.; 1598 1599 ucl_object_todouble_safe (obj, &result); 1600 return result; 1601} 1602 1603bool 1604ucl_object_toint_safe (ucl_object_t *obj, int64_t *target) 1605{ 1606 if (obj == NULL || target == NULL) { 1607 return false; 1608 } 1609 switch (obj->type) { 1610 case UCL_INT: 1611 *target = obj->value.iv; 1612 break; 1613 case UCL_FLOAT: 1614 case UCL_TIME: 1615 *target = obj->value.dv; /* Loosing of decimal points */ 1616 break; 1617 default: 1618 return false; 1619 } 1620 1621 return true; 1622} 1623 1624int64_t 1625ucl_object_toint (ucl_object_t *obj) 1626{ 1627 int64_t result = 0; 1628 1629 ucl_object_toint_safe (obj, &result); 1630 return result; 1631} 1632 1633bool 1634ucl_object_toboolean_safe (ucl_object_t *obj, bool *target) 1635{ 1636 if (obj == NULL || target == NULL) { 1637 return false; 1638 } 1639 switch (obj->type) { 1640 case UCL_BOOLEAN: 1641 *target = (obj->value.iv == true); 1642 break; 1643 default: 1644 return false; 1645 } 1646 1647 return true; 1648} 1649 1650bool 1651ucl_object_toboolean (ucl_object_t *obj) 1652{ 1653 bool result = false; 1654 1655 ucl_object_toboolean_safe (obj, &result); 1656 return result; 1657} 1658 1659bool 1660ucl_object_tostring_safe (ucl_object_t *obj, const char **target) 1661{ 1662 if (obj == NULL || target == NULL) { 1663 return false; 1664 } 1665 1666 switch (obj->type) { 1667 case UCL_STRING: 1668 *target = ucl_copy_value_trash (obj); 1669 break; 1670 default: 1671 return false; 1672 } 1673 1674 return true; 1675} 1676 1677const char * 1678ucl_object_tostring (ucl_object_t *obj) 1679{ 1680 const char *result = NULL; 1681 1682 ucl_object_tostring_safe (obj, &result); 1683 return result; 1684} 1685 1686const char * 1687ucl_object_tostring_forced (ucl_object_t *obj) 1688{ 1689 return ucl_copy_value_trash (obj); 1690} 1691 1692bool 1693ucl_object_tolstring_safe (ucl_object_t *obj, const char **target, size_t *tlen) 1694{ 1695 if (obj == NULL || target == NULL) { 1696 return false; 1697 } 1698 switch (obj->type) { 1699 case UCL_STRING: 1700 *target = obj->value.sv; 1701 if (tlen != NULL) { 1702 *tlen = obj->len; 1703 } 1704 break; 1705 default: 1706 return false; 1707 } 1708 1709 return true; 1710} 1711 1712const char * 1713ucl_object_tolstring (ucl_object_t *obj, size_t *tlen) 1714{ 1715 const char *result = NULL; 1716 1717 ucl_object_tolstring_safe (obj, &result, tlen); 1718 return result; 1719} 1720 1721const char * 1722ucl_object_key (ucl_object_t *obj) 1723{ 1724 return ucl_copy_key_trash (obj); 1725} 1726 1727const char * 1728ucl_object_keyl (ucl_object_t *obj, size_t *len) 1729{ 1730 if (len == NULL || obj == NULL) { 1731 return NULL; 1732 } 1733 *len = obj->keylen; 1734 return obj->key; 1735} 1736 1737ucl_object_t * 1738ucl_object_ref (ucl_object_t *obj) 1739{ 1740 if (obj != NULL) { 1741 obj->ref ++; 1742 } 1743 return obj; 1744} 1745 1746void 1747ucl_object_unref (ucl_object_t *obj) 1748{ 1749 if (obj != NULL && --obj->ref <= 0) { 1750 ucl_object_free (obj); 1751 } 1752} 1753 1754int 1755ucl_object_compare (ucl_object_t *o1, ucl_object_t *o2) 1756{ 1757 ucl_object_t *it1, *it2; 1758 ucl_object_iter_t iter = NULL; 1759 int ret = 0; 1760 1761 if (o1->type != o2->type) { 1762 return (o1->type) - (o2->type); 1763 } 1764 1765 switch (o1->type) { 1766 case UCL_STRING: 1767 if (o1->len == o2->len) { 1768 ret = strcmp (ucl_object_tostring(o1), ucl_object_tostring(o2)); 1769 } 1770 else { 1771 ret = o1->len - o2->len; 1772 } 1773 break; 1774 case UCL_FLOAT: 1775 case UCL_INT: 1776 case UCL_TIME: 1777 ret = ucl_object_todouble (o1) - ucl_object_todouble (o2); 1778 break; 1779 case UCL_BOOLEAN: 1780 ret = ucl_object_toboolean (o1) - ucl_object_toboolean (o2); 1781 break; 1782 case UCL_ARRAY: 1783 if (o1->len == o2->len) { 1784 it1 = o1->value.av; 1785 it2 = o2->value.av; 1786 /* Compare all elements in both arrays */ 1787 while (it1 != NULL && it2 != NULL) { 1788 ret = ucl_object_compare (it1, it2); 1789 if (ret != 0) { 1790 break; 1791 } 1792 it1 = it1->next; 1793 it2 = it2->next; 1794 } 1795 } 1796 else { 1797 ret = o1->len - o2->len; 1798 } 1799 break; 1800 case UCL_OBJECT: 1801 if (o1->len == o2->len) { 1802 while ((it1 = ucl_iterate_object (o1, &iter, true)) != NULL) { 1803 it2 = ucl_object_find_key (o2, ucl_object_key (it1)); 1804 if (it2 == NULL) { 1805 ret = 1; 1806 break; 1807 } 1808 ret = ucl_object_compare (it1, it2); 1809 if (ret != 0) { 1810 break; 1811 } 1812 } 1813 } 1814 else { 1815 ret = o1->len - o2->len; 1816 } 1817 break; 1818 default: 1819 ret = 0; 1820 break; 1821 } 1822 1823 return ret; 1824} 1825 1826void 1827ucl_object_array_sort (ucl_object_t *ar, 1828 int (*cmp)(ucl_object_t *o1, ucl_object_t *o2)) 1829{ 1830 if (cmp == NULL || ar == NULL || ar->type != UCL_ARRAY) { 1831 return; 1832 } 1833 1834 DL_SORT (ar->value.av, cmp); 1835} |
|