sentrypeer_config_new:
   39|     99|{
   40|     99|	sentrypeer_config *self = malloc(sizeof(sentrypeer_config));
   41|     99|	assert(self);
  ------------------
  |  Branch (41:2): [True: 0, False: 99]
  |  Branch (41:2): [True: 99, False: 0]
  ------------------
   42|       |
   43|     99|	char *uuid_string = malloc(UTILS_UUID_STRING_LEN);
  ------------------
  |  |   18|     99|#define UTILS_UUID_STRING_LEN 37
  ------------------
   44|     99|	assert(uuid_string);
  ------------------
  |  Branch (44:2): [True: 0, False: 99]
  |  Branch (44:2): [True: 99, False: 0]
  ------------------
   45|       |
   46|     99|	self->api_mode = false;
   47|     99|	self->bgp_agent_mode = false;
   48|     99|	self->debug_mode = false;
   49|     99|	self->new_mode = false; 
   50|     99|	self->json_log_mode = false;
   51|     99|	self->node_id = util_uuid_generate_string(uuid_string);
   52|     99|	self->p2p_dht_mode = false;
   53|     99|	self->sip_agent_mode = false;
   54|     99|	self->sip_mode = true; // Default on
   55|     99|	self->sip_responsive_mode = false;
   56|     99|	self->syslog_mode = false;
   57|     99|	self->verbose_mode = false;
   58|     99|	self->webhook_mode = false;
   59|     99|	self->oauth2_mode = false;
   60|       |
   61|     99|	self->oauth2_client_id = 0;
   62|     99|	self->oauth2_client_secret = 0;
   63|     99|	self->oauth2_access_token = 0;
   64|       |	
   65|     99|	self->sip_daemon_thread = 0;
   66|     99|	self->sip_channel = 0;
   67|       |
   68|     99|	self->db_file = calloc(SENTRYPEER_PATH_MAX + 1, sizeof(char));
  ------------------
  |  |   27|     99|#define SENTRYPEER_PATH_MAX 4096
  ------------------
   69|     99|	assert(self->db_file);
  ------------------
  |  Branch (69:2): [True: 0, False: 99]
  |  Branch (69:2): [True: 99, False: 0]
  ------------------
   70|     99|	util_copy_string(self->db_file, DEFAULT_DB_FILE_NAME,
  ------------------
  |  |   22|     99|#define DEFAULT_DB_FILE_NAME "sentrypeer.db"
  ------------------
   71|     99|			 SENTRYPEER_PATH_MAX);
  ------------------
  |  |   27|     99|#define SENTRYPEER_PATH_MAX 4096
  ------------------
   72|       |
   73|     99|	self->json_log_file = calloc(SENTRYPEER_PATH_MAX + 1, sizeof(char));
  ------------------
  |  |   27|     99|#define SENTRYPEER_PATH_MAX 4096
  ------------------
   74|     99|	assert(self->json_log_file);
  ------------------
  |  Branch (74:2): [True: 0, False: 99]
  |  Branch (74:2): [True: 99, False: 0]
  ------------------
   75|     99|	util_copy_string(self->json_log_file, DEFAULT_JSON_LOG_FILE_NAME,
  ------------------
  |  |   17|     99|#define DEFAULT_JSON_LOG_FILE_NAME "sentrypeer_json.log"
  ------------------
   76|     99|			 SENTRYPEER_PATH_MAX);
  ------------------
  |  |   27|     99|#define SENTRYPEER_PATH_MAX 4096
  ------------------
   77|       |
   78|     99|	self->p2p_bootstrap_node = calloc(DNS_MAX_LENGTH + 1, sizeof(char));
  ------------------
  |  |   28|     99|#define DNS_MAX_LENGTH 256
  ------------------
   79|     99|	assert(self->p2p_bootstrap_node);
  ------------------
  |  Branch (79:2): [True: 0, False: 99]
  |  Branch (79:2): [True: 99, False: 0]
  ------------------
   80|     99|	util_copy_string(self->p2p_bootstrap_node, SENTRYPEER_BOOTSTRAP_NODE,
  ------------------
  |  |   29|     99|#define SENTRYPEER_BOOTSTRAP_NODE "bootstrap.sentrypeer.org"
  ------------------
   81|     99|			 DNS_MAX_LENGTH);
  ------------------
  |  |   28|     99|#define DNS_MAX_LENGTH 256
  ------------------
   82|       |
   83|     99|	self->webhook_url = calloc(DNS_MAX_LENGTH + 1, sizeof(char));
  ------------------
  |  |   28|     99|#define DNS_MAX_LENGTH 256
  ------------------
   84|     99|	assert(self->webhook_url);
  ------------------
  |  Branch (84:2): [True: 0, False: 99]
  |  Branch (84:2): [True: 99, False: 0]
  ------------------
   85|     99|	util_copy_string(self->webhook_url, SENTRYPEER_WEBHOOK_URL,
  ------------------
  |  |   30|     99|#define SENTRYPEER_WEBHOOK_URL "http://localhost:4000/api/events"
  ------------------
   86|     99|			 DNS_MAX_LENGTH);
  ------------------
  |  |   28|     99|#define DNS_MAX_LENGTH 256
  ------------------
   87|       |
   88|     99|	self->oauth2_client_id = calloc(DNS_MAX_LENGTH + 1, sizeof(char));
  ------------------
  |  |   28|     99|#define DNS_MAX_LENGTH 256
  ------------------
   89|     99|	assert(self->oauth2_client_id);
  ------------------
  |  Branch (89:2): [True: 0, False: 99]
  |  Branch (89:2): [True: 99, False: 0]
  ------------------
   90|     99|	util_copy_string(self->oauth2_client_id, SENTRYPEER_OAUTH2_CLIENT_ID,
  ------------------
  |  |   34|     99|#define SENTRYPEER_OAUTH2_CLIENT_ID "YOUR_CLIENT_ID"
  ------------------
   91|     99|			 DNS_MAX_LENGTH);
  ------------------
  |  |   28|     99|#define DNS_MAX_LENGTH 256
  ------------------
   92|       |
   93|     99|	self->oauth2_client_secret = calloc(DNS_MAX_LENGTH + 1, sizeof(char));
  ------------------
  |  |   28|     99|#define DNS_MAX_LENGTH 256
  ------------------
   94|     99|	assert(self->oauth2_client_secret);
  ------------------
  |  Branch (94:2): [True: 0, False: 99]
  |  Branch (94:2): [True: 99, False: 0]
  ------------------
   95|     99|	util_copy_string(self->oauth2_client_secret,
   96|     99|			 SENTRYPEER_OAUTH2_CLIENT_SECRET, DNS_MAX_LENGTH);
  ------------------
  |  |   35|     99|#define SENTRYPEER_OAUTH2_CLIENT_SECRET "YOUR_CLIENT_SECRET"
  ------------------
              			 SENTRYPEER_OAUTH2_CLIENT_SECRET, DNS_MAX_LENGTH);
  ------------------
  |  |   28|     99|#define DNS_MAX_LENGTH 256
  ------------------
   97|       |
   98|       |#if HAVE_OPENDHT_C != 0
   99|       |	// Generate our InfoHash from our key name
  100|       |	self->dht_info_hash = malloc(sizeof(dht_infohash));
  101|       |	assert(self->dht_info_hash);
  102|       |	dht_infohash_get_from_string(self->dht_info_hash, DHT_BAD_ACTORS_KEY);
  103|       |#endif
  104|       |	
  105|       |#if HAVE_RUST != 0
  106|       |	self->new_mode = true; // Default false above for fallback if no Rust
  107|       |	self->tls_cert_file = 0;
  108|       |	self->tls_key_file = 0;
  109|       |	self->tls_listen_address = 0;
  110|       |	self->config_file = 0;
  111|       |#endif
  112|       |
  113|     99|	return self;
  114|     99|}
sentrypeer_config_destroy:
  118|     99|{
  119|     99|	assert(self_ptr);
  ------------------
  |  Branch (119:2): [True: 0, False: 99]
  |  Branch (119:2): [True: 99, False: 0]
  ------------------
  120|     99|	if (*self_ptr) {
  ------------------
  |  Branch (120:6): [True: 99, False: 0]
  ------------------
  121|     99|		sentrypeer_config *self = *self_ptr;
  122|       |
  123|       |		// Modern C by Manning, Takeaway 6.19
  124|       |		// "6.19 Initialization or assignment with 0 makes a pointer null."
  125|     99|		if (self->node_id != 0) {
  ------------------
  |  Branch (125:7): [True: 99, False: 0]
  ------------------
  126|     99|			free(self->node_id);
  127|     99|			self->node_id = 0;
  128|     99|		}
  129|       |
  130|       |#if HAVE_OPENDHT_C != 0
  131|       |		if (self->dht_info_hash != 0) {
  132|       |			free(self->dht_info_hash);
  133|       |			self->dht_info_hash = 0;
  134|       |		}
  135|       |#endif
  136|       |
  137|     99|		if (self->p2p_bootstrap_node != 0) {
  ------------------
  |  Branch (137:7): [True: 99, False: 0]
  ------------------
  138|     99|			free(self->p2p_bootstrap_node);
  139|     99|			self->p2p_bootstrap_node = 0;
  140|     99|		}
  141|       |
  142|     99|		if (self->webhook_url != 0) {
  ------------------
  |  Branch (142:7): [True: 99, False: 0]
  ------------------
  143|     99|			free(self->webhook_url);
  144|     99|			self->webhook_url = 0;
  145|     99|		}
  146|       |
  147|     99|		if (self->oauth2_client_id != 0) {
  ------------------
  |  Branch (147:7): [True: 99, False: 0]
  ------------------
  148|     99|			free(self->oauth2_client_id);
  149|     99|			self->oauth2_client_id = 0;
  150|     99|		}
  151|       |
  152|     99|		if (self->oauth2_client_secret != 0) {
  ------------------
  |  Branch (152:7): [True: 99, False: 0]
  ------------------
  153|     99|			free(self->oauth2_client_secret);
  154|     99|			self->oauth2_client_secret = 0;
  155|     99|		}
  156|       |
  157|     99|		if (self->oauth2_access_token != 0) {
  ------------------
  |  Branch (157:7): [True: 0, False: 99]
  ------------------
  158|      0|			free(self->oauth2_access_token);
  159|      0|			self->oauth2_access_token = 0;
  160|      0|		}
  161|       |
  162|     99|		if (self->db_file != 0) {
  ------------------
  |  Branch (162:7): [True: 99, False: 0]
  ------------------
  163|     99|			free(self->db_file);
  164|     99|			self->db_file = 0;
  165|     99|		}
  166|       |
  167|     99|		if (self->json_log_file != 0) {
  ------------------
  |  Branch (167:7): [True: 99, False: 0]
  ------------------
  168|     99|			free(self->json_log_file);
  169|     99|			self->json_log_file = 0;
  170|     99|		}
  171|       |
  172|       |#if HAVE_RUST != 0
  173|       |		if (self->tls_cert_file != 0) {
  174|       |			free(self->tls_cert_file);
  175|       |			self->tls_cert_file = 0;
  176|       |		}
  177|       |
  178|       |		if (self->tls_key_file != 0) {
  179|       |			free(self->tls_key_file);
  180|       |			self->tls_key_file = 0;
  181|       |		}
  182|       |
  183|       |		if (self->tls_listen_address != 0) {
  184|       |			free(self->tls_listen_address);
  185|       |			self->tls_listen_address = 0;
  186|       |		}
  187|       |
  188|       |		if (self->config_file != 0) {
  189|       |			free(self->config_file);
  190|       |			self->config_file = 0;
  191|       |		}
  192|       |#endif
  193|       |
  194|     99|		free(self);
  195|     99|		*self_ptr = 0;
  196|     99|	}
  197|     99|}

regex_match:
   26|    198|{
   27|       |	// Basically all from https://www.pcre.org/current/doc/html/pcre2demo.html
   28|    198|	pcre2_code *re;
   29|    198|	PCRE2_SPTR
   30|    198|	pattern; /* PCRE2_SPTR is a pointer to unsigned code units of */
   31|    198|	PCRE2_SPTR subject; /* the appropriate width (in this case, 8 bits). */
   32|       |
   33|    198|	int errornumber;
   34|    198|	int rc;
   35|       |
   36|    198|	PCRE2_SIZE erroroffset;
   37|    198|	const PCRE2_SIZE *ovector;
   38|    198|	PCRE2_SIZE subject_length;
   39|       |
   40|    198|	pcre2_match_data *match_data;
   41|       |
   42|       |	/* Pattern and subject are char arguments, so they can be straightforwardly
   43|       |cast to PCRE2_SPTR because we are working in 8-bit code units. The subject
   44|       |length is cast to PCRE2_SIZE for completeness, though PCRE2_SIZE is in fact
   45|       |defined to be size_t. */
   46|       |
   47|    198|	pattern = (PCRE2_SPTR)regex;
   48|    198|	subject = (PCRE2_SPTR)string;
   49|    198|	subject_length = (PCRE2_SIZE)strlen((char *)subject);
   50|       |
   51|       |	/*************************************************************************
   52|       |* Now we are going to compile the regular expression pattern, and handle *
   53|       |* any errors that are detected.                                          *
   54|       |*************************************************************************/
   55|       |
   56|    198|	re = pcre2_compile(
   57|    198|		pattern, /* the pattern */
   58|    198|		PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */
   59|    198|		0, /* default options */
   60|    198|		&errornumber, /* for error number */
   61|    198|		&erroroffset, /* for error offset */
   62|    198|		NULL); /* use default compile context */
   63|       |
   64|       |	/* Compilation failed: print the error message and exit. */
   65|       |
   66|    198|	if (re == NULL) {
  ------------------
  |  Branch (66:6): [True: 0, False: 198]
  ------------------
   67|      0|		PCRE2_UCHAR buffer[256];
   68|      0|		pcre2_get_error_message(errornumber, buffer, sizeof(buffer));
   69|      0|		fprintf(stderr, "PCRE2 compilation failed at offset %d: %s\n",
   70|      0|			(int)erroroffset, buffer);
   71|      0|	}
   72|       |
   73|       |	/*************************************************************************
   74|       |* If the compilation succeeded, we call PCRE2 again, in order to do a    *
   75|       |* pattern match against the subject string. This does just ONE match. If *
   76|       |* further matching is needed, it will be done below. Before running the  *
   77|       |* match we must set up a match_data block for holding the result. Using  *
   78|       |* pcre2_match_data_create_from_pattern() ensures that the block is       *
   79|       |* exactly the right size for the number of capturing parentheses in the  *
   80|       |* pattern. If you need to know the actual size of a match_data block as  *
   81|       |* a number of bytes, you can find it like this:                          *
   82|       |*                                                                        *
   83|       |* PCRE2_SIZE match_data_size = pcre2_get_match_data_size(match_data);    *
   84|       |*************************************************************************/
   85|       |
   86|    198|	match_data = pcre2_match_data_create_from_pattern(re, NULL);
   87|       |
   88|       |	/* Now run the match. */
   89|       |
   90|    198|	rc = pcre2_match(re, /* the compiled pattern */
   91|    198|			 subject, /* the subject string */
   92|    198|			 subject_length, /* the length of the subject */
   93|    198|			 0, /* start at offset 0 in the subject */
   94|    198|			 0, /* default options */
   95|    198|			 match_data, /* block for storing the result */
   96|    198|			 NULL); /* use default match context */
   97|       |
   98|       |	/* Matching failed: handle error cases */
   99|       |
  100|    198|	if (rc < 0) {
  ------------------
  |  Branch (100:6): [True: 161, False: 37]
  ------------------
  101|    161|		pcre2_match_data_free(
  102|    161|			match_data); /* Release memory used for the match */
  103|    161|		pcre2_code_free(re); /*   data and the compiled pattern. */
  104|    161|		return EXIT_FAILURE;
  105|    161|	}
  106|       |
  107|       |	/* Match succeeded. Get a pointer to the output vector, where string offsets
  108|       |are stored. */
  109|       |
  110|     37|	ovector = pcre2_get_ovector_pointer(match_data);
  111|       |
  112|       |	/*************************************************************************
  113|       |* We have found the first match within the subject string. If the output *
  114|       |* vector wasn't big enough, say so. Then output any substrings that were *
  115|       |* captured.                                                              *
  116|       |*************************************************************************/
  117|       |
  118|       |	/* The output vector wasn't big enough. This should not happen, because we used
  119|       |pcre2_match_data_create_from_pattern() above. */
  120|       |
  121|     37|	if (rc == 0) {
  ------------------
  |  Branch (121:6): [True: 0, False: 37]
  ------------------
  122|      0|		fprintf(stderr,
  123|      0|			"ovector was not big enough for all the captured substrings\n");
  124|      0|		pcre2_match_data_free(match_data);
  125|      0|		pcre2_code_free(re);
  126|      0|		return EXIT_FAILURE;
  127|      0|	}
  128|       |
  129|       |	/* Since release 10.38 PCRE2 has locked out the use of \K in lookaround
  130|       |assertions. However, there is an option to re-enable the old behaviour. If that
  131|       |is set, it is possible to run patterns such as /(?=.\K)/ that use \K in an
  132|       |assertion to set the start of a match later than its end. In this demonstration
  133|       |program, we show how to detect this case, but it shouldn't arise because the
  134|       |option is never set. */
  135|       |
  136|     37|	if (ovector[0] > ovector[1]) {
  ------------------
  |  Branch (136:6): [True: 0, False: 37]
  ------------------
  137|      0|		fprintf(stderr,
  138|      0|			"\\K was used in an assertion to set the match start after its end.\n"
  139|      0|			"From end to start the match was: %.*s\n",
  140|      0|			(int)(ovector[0] - ovector[1]),
  141|      0|			(char *)(subject + ovector[1]));
  142|      0|		fprintf(stderr, "Run abandoned\n");
  143|      0|		pcre2_match_data_free(match_data);
  144|      0|		pcre2_code_free(re);
  145|      0|		return EXIT_FAILURE;
  146|      0|	}
  147|       |
  148|       |	// Our capture is the first, so when i = 1, 2 * 1 = 2, hence ovector[2 * 1]
  149|     37|	*matched_string = util_duplicate_string((char *)(subject + ovector[2]));
  150|     37|	assert(matched_string);
  ------------------
  |  Branch (150:2): [True: 0, False: 37]
  |  Branch (150:2): [True: 37, False: 0]
  ------------------
  151|       |
  152|     37|	if (config->debug_mode || config->verbose_mode) {
  ------------------
  |  Branch (152:6): [True: 0, False: 37]
  |  Branch (152:28): [True: 0, False: 37]
  ------------------
  153|      0|		fprintf(stderr, "\nroute_regex_check matched: %s\n",
  154|      0|			*matched_string);
  155|      0|	}
  156|       |
  157|     37|	pcre2_match_data_free(match_data);
  158|     37|	pcre2_code_free(re);
  159|       |
  160|       |	return EXIT_SUCCESS;
  161|     37|}

util_duplicate_string:
   52|     37|{
   53|     37|	char *duplicate = NULL;
   54|     37|	assert(string);
  ------------------
  |  Branch (54:2): [True: 0, False: 37]
  |  Branch (54:2): [True: 37, False: 0]
  ------------------
   55|       |
   56|     37|	duplicate = strndup(string, strlen(string));
   57|       |
   58|     37|	assert(duplicate);
  ------------------
  |  Branch (58:2): [True: 0, False: 37]
  |  Branch (58:2): [True: 37, False: 0]
  ------------------
   59|       |	// Must be freed by caller.
   60|     37|	return duplicate;
   61|     37|}
util_copy_string:
   64|    594|{
   65|    594|	assert(src);
  ------------------
  |  Branch (65:2): [True: 0, False: 594]
  |  Branch (65:2): [True: 594, False: 0]
  ------------------
   66|    594|	assert(dest);
  ------------------
  |  Branch (66:2): [True: 0, False: 594]
  |  Branch (66:2): [True: 594, False: 0]
  ------------------
   67|    594|	assert(dest_len > 0);
  ------------------
  |  Branch (67:2): [True: 0, False: 594]
  |  Branch (67:2): [True: 594, False: 0]
  ------------------
   68|       |
   69|    594|	if (strlen(src) > dest_len) {
  ------------------
  |  Branch (69:6): [True: 0, False: 594]
  ------------------
   70|      0|		return NULL;
   71|      0|	}
   72|       |
   73|    594|	strncpy(dest, src, dest_len);
   74|    594|	assert(dest);
  ------------------
  |  Branch (74:2): [True: 0, False: 594]
  |  Branch (74:2): [True: 594, False: 0]
  ------------------
   75|    594|	assert(dest[strlen(dest)] == 0);
  ------------------
  |  Branch (75:2): [True: 0, False: 594]
  |  Branch (75:2): [True: 594, False: 0]
  ------------------
   76|       |
   77|    594|	return dest;
   78|    594|}
util_uuid_generate_string:
   81|     99|{
   82|     99|	assert(uuid_string);
  ------------------
  |  Branch (82:2): [True: 0, False: 99]
  |  Branch (82:2): [True: 99, False: 0]
  ------------------
   83|       |
   84|     99|	uuid_t binary_uuid;
   85|     99|	uuid_generate(binary_uuid);
   86|     99|	assert(binary_uuid != NULL);
  ------------------
  |  Branch (86:2): [True: 0, Folded]
  |  Branch (86:2): [True: 99, Folded]
  ------------------
   87|       |
   88|     99|	uuid_unparse_lower(binary_uuid, uuid_string);
   89|       |
   90|     99|	assert(uuid_string);
  ------------------
  |  Branch (90:2): [True: 0, False: 99]
  |  Branch (90:2): [True: 99, False: 0]
  ------------------
   91|     99|	return uuid_string;
   92|     99|}
valid_ip_address_format:
   95|    117|{
   96|    117|	assert(ip_address_to_check);
  ------------------
  |  Branch (96:2): [True: 0, False: 117]
  |  Branch (96:2): [True: 117, False: 0]
  ------------------
   97|    117|	unsigned char buf_not_used[sizeof(struct in6_addr)];
   98|       |
   99|    117|	if (inet_pton(AF_INET, ip_address_to_check, buf_not_used) == 1) {
  ------------------
  |  Branch (99:6): [True: 1, False: 116]
  ------------------
  100|      1|		return EXIT_SUCCESS;
  101|    116|	} else if (inet_pton(AF_INET6, ip_address_to_check, buf_not_used) ==
  ------------------
  |  Branch (101:13): [True: 2, False: 114]
  ------------------
  102|    116|		   1) {
  103|      2|		return EXIT_SUCCESS;
  104|    114|	} else {
  105|       |		return EXIT_FAILURE;
  106|    114|	}
  107|    117|}
is_valid_uuid:
  147|     99|{
  148|     99|	uuid_t uuid;
  149|     99|	if (uuid_parse(uuid_to_check, uuid) != 0) {
  ------------------
  |  Branch (149:6): [True: 99, False: 0]
  ------------------
  150|     99|		return false;
  151|     99|	}
  152|      0|	return true;
  153|     99|}
util_sanitise_for_log:
  165|     99|{
  166|     99|	assert(src);
  ------------------
  |  Branch (166:2): [True: 0, False: 99]
  |  Branch (166:2): [True: 99, False: 0]
  ------------------
  167|     99|	assert(dest);
  ------------------
  |  Branch (167:2): [True: 0, False: 99]
  |  Branch (167:2): [True: 99, False: 0]
  ------------------
  168|     99|	assert(dest_len > 0);
  ------------------
  |  Branch (168:2): [True: 0, False: 99]
  |  Branch (168:2): [True: 99, False: 0]
  ------------------
  169|       |
  170|     99|	if (src == NULL || dest == NULL || dest_len == 0) {
  ------------------
  |  Branch (170:6): [True: 0, False: 99]
  |  Branch (170:21): [True: 0, False: 99]
  |  Branch (170:37): [True: 0, False: 99]
  ------------------
  171|      0|		return NULL;
  172|      0|	}
  173|       |
  174|     99|	size_t i = 0;
  175|  8.11k|	while (i < dest_len - 1 && src[i] != '\0') {
  ------------------
  |  Branch (175:9): [True: 8.09k, False: 25]
  |  Branch (175:29): [True: 8.02k, False: 74]
  ------------------
  176|  8.02k|		unsigned char c = (unsigned char)src[i];
  177|  8.02k|		if (c == '\r' || c == '\n' || iscntrl(c) || !isprint(c)) {
  ------------------
  |  Branch (177:7): [True: 4.42k, False: 3.59k]
  |  Branch (177:20): [True: 280, False: 3.31k]
  |  Branch (177:33): [True: 392, False: 2.92k]
  |  Branch (177:47): [True: 1.72k, False: 1.20k]
  ------------------
  178|  6.81k|			dest[i] = '_';
  179|  6.81k|		} else {
  180|  1.20k|			dest[i] = (char)c;
  181|  1.20k|		}
  182|  8.02k|		i++;
  183|  8.02k|	}
  184|     99|	dest[i] = '\0';
  185|       |
  186|     99|	return dest;
  187|     99|}

LLVMFuzzerTestOneInput:
   27|     99|{
   28|     99|	sentrypeer_config *config = sentrypeer_config_new();
   29|     99|	if (config == NULL) {
  ------------------
  |  Branch (29:6): [True: 0, False: 99]
  ------------------
   30|      0|		return 0;
   31|      0|	}
   32|       |
   33|       |	// The inputs below are NUL-terminated strings, like a URL from libmicrohttpd.
   34|     99|	char *str = malloc(size + 1);
   35|     99|	if (str == NULL) {
  ------------------
  |  Branch (35:6): [True: 0, False: 99]
  ------------------
   36|      0|		sentrypeer_config_destroy(&config);
   37|      0|		return 0;
   38|      0|	}
   39|     99|	if (size > 0) {
  ------------------
  |  Branch (39:6): [True: 99, False: 0]
  ------------------
   40|     99|		memcpy(str, data, size);
   41|     99|	}
   42|     99|	str[size] = '\0';
   43|       |
   44|     99|	char *matched = NULL;
   45|     99|	if (regex_match(str, IP_ADDRESS_ROUTE, &matched, config) ==
  ------------------
  |  |   23|     99|#define IP_ADDRESS_ROUTE "/ip-addresses/(.+)"
  ------------------
  |  Branch (45:6): [True: 18, False: 81]
  ------------------
   46|     99|	    EXIT_SUCCESS) {
   47|     18|		if (matched != NULL) {
  ------------------
  |  Branch (47:7): [True: 18, False: 0]
  ------------------
   48|     18|			valid_ip_address_format(matched);
   49|     18|		}
   50|     18|		free(matched);
   51|     18|	}
   52|       |
   53|     99|	matched = NULL;
   54|     99|	if (regex_match(str, NUMBER_ROUTE, &matched, config) == EXIT_SUCCESS) {
  ------------------
  |  |   24|     99|#define NUMBER_ROUTE "/numbers/(\\+?[0-9]+$)"
  ------------------
  |  Branch (54:6): [True: 19, False: 80]
  ------------------
   55|     19|		free(matched);
   56|     19|	}
   57|       |
   58|     99|	valid_ip_address_format(str);
   59|     99|	is_valid_uuid(str);
   60|       |
   61|     99|	char log_buf[256];
   62|     99|	util_sanitise_for_log(log_buf, str, sizeof(log_buf));
   63|       |
   64|     99|	free(str);
   65|     99|	sentrypeer_config_destroy(&config);
   66|     99|	return 0;
   67|     99|}

