diff options
Diffstat (limited to 'contrib/libucl/src/ucl_util.c')
| -rw-r--r-- | contrib/libucl/src/ucl_util.c | 87 | 
1 files changed, 54 insertions, 33 deletions
| diff --git a/contrib/libucl/src/ucl_util.c b/contrib/libucl/src/ucl_util.c index b00a34787e5a..8f97c20db503 100644 --- a/contrib/libucl/src/ucl_util.c +++ b/contrib/libucl/src/ucl_util.c @@ -67,7 +67,7 @@ typedef kvec_t(ucl_object_t *) ucl_array_t;  #include <fetch.h>  #endif -#if defined(_MSC_VER) +#if defined(_WIN32)  #include <windows.h>  #include <io.h>  #include <direct.h> @@ -889,44 +889,49 @@ ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *bufl  {  	int fd;  	struct stat st; +	if ((fd = open (filename, O_RDONLY)) == -1) { +		ucl_create_err (err, "cannot open file %s: %s", +				filename, strerror (errno)); +		return false; +	} -	if (stat (filename, &st) == -1) { +	if (fstat (fd, &st) == -1) {  		if (must_exist || errno == EPERM) {  			ucl_create_err (err, "cannot stat file %s: %s",  					filename, strerror (errno));  		} +		close (fd); +  		return false;  	}  	if (!S_ISREG (st.st_mode)) {  		if (must_exist) {  			ucl_create_err (err, "file %s is not a regular file", filename);  		} +		close (fd);  		return false;  	} +  	if (st.st_size == 0) {  		/* Do not map empty files */  		*buf = NULL;  		*buflen = 0;  	}  	else { -		if ((fd = open (filename, O_RDONLY)) == -1) { -			ucl_create_err (err, "cannot open file %s: %s", -					filename, strerror (errno)); -			return false; -		} -		if ((*buf = ucl_mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { -			close (fd); -			ucl_create_err (err, "cannot mmap file %s: %s", -					filename, strerror (errno)); +		if ((*buf = ucl_mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { +			close(fd); +			ucl_create_err(err, "cannot mmap file %s: %s", +					filename, strerror(errno));  			*buf = NULL;  			return false;  		}  		*buflen = st.st_size; -		close (fd);  	} +	close (fd); +  	return true;  } @@ -1017,6 +1022,9 @@ ucl_include_url (const unsigned char *data, size_t len,  	snprintf (urlbuf, sizeof (urlbuf), "%.*s", (int)len, data);  	if (!ucl_fetch_url (urlbuf, &buf, &buflen, &parser->err, params->must_exist)) { +		if (!params->must_exist) { +			ucl_parser_clear_error (parser); +		}  		return !params->must_exist;  	} @@ -1092,6 +1100,11 @@ ucl_include_file_single (const unsigned char *data, size_t len,  	ucl_hash_t *container = NULL;  	struct ucl_stack *st = NULL; +	if (parser->state == UCL_STATE_ERROR) { +		/* Return immediately if we are in the error state... */ +		return false; +	} +  	snprintf (filebuf, sizeof (filebuf), "%.*s", (int)len, data);  	if (ucl_realpath (filebuf, realbuf) == NULL) {  		if (params->soft_fail) { @@ -1128,6 +1141,8 @@ ucl_include_file_single (const unsigned char *data, size_t len,  			return false;  		} +		ucl_parser_clear_error (parser); +  		return true;  	} @@ -1138,6 +1153,10 @@ ucl_include_file_single (const unsigned char *data, size_t len,  		/* We need to check signature first */  		snprintf (filebuf, sizeof (filebuf), "%s.sig", realbuf);  		if (!ucl_fetch_file (filebuf, &sigbuf, &siglen, &parser->err, true)) { +			if (buf) { +				ucl_munmap (buf, buflen); +			} +  			return false;  		}  		if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) { @@ -1147,8 +1166,13 @@ ucl_include_file_single (const unsigned char *data, size_t len,  			if (sigbuf) {  				ucl_munmap (sigbuf, siglen);  			} +			if (buf) { +				ucl_munmap (buf, buflen); +			} +  			return false;  		} +  		if (sigbuf) {  			ucl_munmap (sigbuf, siglen);  		} @@ -1257,6 +1281,8 @@ ucl_include_file_single (const unsigned char *data, size_t len,  							ucl_munmap (buf, buflen);  						} +						ucl_object_unref (new_obj); +  						return false;  					}  					nest_obj->prev = nest_obj; @@ -1576,11 +1602,6 @@ ucl_include_common (const unsigned char *data, size_t len,  			else if (param->type == UCL_INT) {  				if (strncmp (param->key, "priority", param->keylen) == 0) {  					params.priority = ucl_object_toint (param); -					if (params.priority > UCL_PRIORITY_MAX) { -						ucl_create_err (&parser->err, "Invalid priority value in macro: %d", -							params.priority); -						return false; -					}  				}  			}  		} @@ -1719,9 +1740,8 @@ ucl_priority_handler (const unsigned char *data, size_t len,  	if (len > 0) {  		value = malloc(len + 1);  		ucl_strlcpy(value, (const char *)data, len + 1); -		errno = 0; -		priority = strtoul(value, &leftover, 10); -		if (errno != 0 || *leftover != '\0' || priority > UCL_PRIORITY_MAX) { +		priority = strtol(value, &leftover, 10); +		if (*leftover != '\0') {  			ucl_create_err (&parser->err, "Invalid priority value in macro: %s",  				value);  			free(value); @@ -1842,6 +1862,10 @@ ucl_load_handler (const unsigned char *data, size_t len,  				!try_load)) {  			free (load_file); +			if (try_load) { +				ucl_parser_clear_error (parser); +			} +  			return (try_load || false);  		} @@ -1919,7 +1943,7 @@ ucl_inherit_handler (const unsigned char *data, size_t len,  	/* Some sanity checks */  	if (parent == NULL || ucl_object_type (parent) != UCL_OBJECT) { -		ucl_create_err (&parser->err, "Unable to find inherited object %*.s", +		ucl_create_err (&parser->err, "Unable to find inherited object %.*s",  				(int)len, data);  		return false;  	} @@ -2177,7 +2201,7 @@ ucl_strnstr (const char *s, const char *find, int len)  		mlen = strlen (find);  		do {  			do { -				if ((sc = *s++) == 0 || len-- == 0) +				if ((sc = *s++) == 0 || len-- < mlen)  					return (NULL);  			} while (sc != c);  		} while (strncmp (s, find, mlen) != 0); @@ -2596,6 +2620,7 @@ ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy)  						if (!ucl_object_merge (found, cp, copy)) {  							return false;  						} +						ucl_object_unref (cp);  					}  					else {  						ucl_hash_replace (top->value.ov, found, cp); @@ -2627,6 +2652,7 @@ ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy)  					if (!ucl_object_merge (found, cp, copy)) {  						return false;  					} +					ucl_object_unref (cp);  				}  				else {  					ucl_hash_replace (top->value.ov, found, cp); @@ -3068,13 +3094,13 @@ ucl_object_type (const ucl_object_t *obj)  ucl_object_t*  ucl_object_fromstring (const char *str)  { -	return ucl_object_fromstring_common (str, 0, UCL_STRING_ESCAPE); +	return ucl_object_fromstring_common (str, 0, UCL_STRING_RAW);  }  ucl_object_t *  ucl_object_fromlstring (const char *str, size_t len)  { -	return ucl_object_fromstring_common (str, len, UCL_STRING_ESCAPE); +	return ucl_object_fromstring_common (str, len, UCL_STRING_RAW);  }  ucl_object_t * @@ -3594,9 +3620,11 @@ ucl_object_copy_internal (const ucl_object_t *other, bool allow_array)  		/* deep copy of values stored */  		if (other->trash_stack[UCL_TRASH_KEY] != NULL) { -			new->trash_stack[UCL_TRASH_KEY] = -					strdup (other->trash_stack[UCL_TRASH_KEY]); +			new->trash_stack[UCL_TRASH_KEY] = NULL;  			if (other->key == (const char *)other->trash_stack[UCL_TRASH_KEY]) { +				new->trash_stack[UCL_TRASH_KEY] = malloc(other->keylen + 1); +				memcpy(new->trash_stack[UCL_TRASH_KEY], other->trash_stack[UCL_TRASH_KEY], other->keylen); +				new->trash_stack[UCL_TRASH_KEY][other->keylen] = '\0';  				new->key = new->trash_stack[UCL_TRASH_KEY];  			}  		} @@ -3666,13 +3694,6 @@ ucl_object_compare (const ucl_object_t *o1, const ucl_object_t *o2)  	ucl_object_iter_t iter = NULL;  	int ret = 0; -    // Must check for NULL or code will segfault -    if ((o1 == NULL) || (o2 == NULL)) -    { -        // The only way this could be true is of both are NULL -        return (o1 == NULL) && (o2 == NULL); -    } -      	if (o1->type != o2->type) {  		return (o1->type) - (o2->type);  	} | 
