Deleted Added
sdiff udiff text old ( 262975 ) new ( 263648 )
full compact
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#include <libgen.h> /* For dirname */
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
38#ifdef _WIN32
39#include <windows.h>
40
41#define PROT_READ 1
42#define PROT_WRITE 2
43#define PROT_READWRITE 3
44#define MAP_SHARED 1
45#define MAP_PRIVATE 2
46#define MAP_FAILED ((void *) -1)
47
48static void *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
86static int munmap(void *map,size_t length)
87{
88 if (!UnmapViewOfFile(map)) {
89 return(-1);
90 }
91 return(0);
92}
93
94static char* 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}
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
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;
191 for (i = 0; i < 4; i++) {
192 uval <<= 4;
193 if (isdigit (h[i])) {
194 uval += h[i] - '0';
195 }
196 else if (h[i] >= 'a' && h[i] <= 'f') {
197 uval += h[i] - 'a' + 10;
198 }
199 else if (h[i] >= 'A' && h[i] <= 'F') {
200 uval += h[i] - 'A' + 10;
201 }
202 }
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 {
229 *t++ = '?';
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{
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{
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
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{
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));
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 }
530 if ((*buf = 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) {
632 munmap (sigbuf, siglen);
633 }
634 return false;
635 }
636 if (siglen > 0) {
637 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);
681 if (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) {
709 munmap (sigbuf, siglen);
710 }
711 return false;
712 }
713 if (siglen > 0) {
714 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) {
737 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) {
806 if (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
837 if (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) {
852 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,
1017 flags & UCL_STRING_PARSE_BYTES);
1018 }
1019 }
1020 else {
1021 ucl_maybe_parse_number (obj, dst, dst + obj->len, &pos,
1022 flags & UCL_STRING_PARSE_DOUBLE,
1023 flags & UCL_STRING_PARSE_BYTES);
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);
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
1132 found = ucl_object_find_keyl(top, key, keylen);
1133
1134 if (found == NULL)
1135 return false;
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
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
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}