LLVMFuzzerTestOneInput:
   26|  2.36k|{
   27|  2.36k|	plist_t root_node = NULL;
   28|  2.36k|	plist_from_bin(reinterpret_cast<const char*>(data), size, &root_node);
   29|  2.36k|	plist_free(root_node);
   30|       |
   31|  2.36k|	return 0;
   32|  2.36k|}

node_destroy:
   31|   175k|{
   32|   175k|	if(!node) return;
  ------------------
  |  Branch (32:5): [True: 0, False: 175k]
  ------------------
   33|       |
   34|   175k|	if (node->children && node->children->count > 0) {
  ------------------
  |  Branch (34:6): [True: 14.0k, False: 161k]
  |  Branch (34:24): [True: 0, False: 14.0k]
  ------------------
   35|      0|		node_t ch;
   36|      0|		while ((ch = node->children->begin)) {
  ------------------
  |  Branch (36:10): [True: 0, False: 0]
  ------------------
   37|      0|			node_list_remove(node->children, ch);
   38|      0|			node_destroy(ch);
   39|      0|		}
   40|      0|	}
   41|   175k|	node_list_destroy(node->children);
   42|   175k|	node->children = NULL;
   43|       |
   44|   175k|	free(node);
   45|   175k|}
node_create:
   48|   175k|{
   49|   175k|	int error = 0;
   50|       |
   51|   175k|	node_t node = (node_t)calloc(1, sizeof(struct node));
   52|   175k|	if (node == NULL) {
  ------------------
  |  Branch (52:6): [True: 0, False: 175k]
  ------------------
   53|      0|		return NULL;
   54|      0|	}
   55|       |
   56|   175k|	node->data = data;
   57|   175k|	node->next = NULL;
   58|   175k|	node->prev = NULL;
   59|   175k|	node->count = 0;
   60|   175k|	node->parent = NULL;
   61|   175k|	node->children = NULL;
   62|       |
   63|       |	// Pass NULL to create a root node
   64|   175k|	if (parent != NULL) {
  ------------------
  |  Branch (64:6): [True: 0, False: 175k]
  ------------------
   65|       |		// This is a child node so attach it to it's parent
   66|      0|		error = node_attach(parent, node);
   67|      0|		if (error < 0) {
  ------------------
  |  Branch (67:7): [True: 0, False: 0]
  ------------------
   68|       |			// Unable to attach nodes
   69|      0|			node_destroy(node);
   70|      0|			return NULL;
   71|      0|		}
   72|      0|	}
   73|       |
   74|   175k|	return node;
   75|   175k|}
node_attach:
  133|   172k|{
  134|   172k|	if (!parent || !child) return NODE_ERR_INVALID_ARG;
  ------------------
  |  |   37|      0|#define NODE_ERR_INVALID_ARG  -1
  ------------------
  |  Branch (134:6): [True: 0, False: 172k]
  |  Branch (134:17): [True: 0, False: 172k]
  ------------------
  135|       |
  136|       |	// already parented?
  137|   172k|	if (child->parent) return NODE_ERR_PARENT;
  ------------------
  |  |   39|      0|#define NODE_ERR_PARENT       -3
  ------------------
  |  Branch (137:6): [True: 0, False: 172k]
  ------------------
  138|       |
  139|       |	// self/cycle guard
  140|   172k|	if (parent == child) return NODE_ERR_CIRCULAR_REF;
  ------------------
  |  |   40|      0|#define NODE_ERR_CIRCULAR_REF -4
  ------------------
  |  Branch (140:6): [True: 0, False: 172k]
  ------------------
  141|   172k|	if (would_create_cycle(parent, child)) return NODE_ERR_CIRCULAR_REF;
  ------------------
  |  |   40|      0|#define NODE_ERR_CIRCULAR_REF -4
  ------------------
  |  Branch (141:6): [True: 0, False: 172k]
  ------------------
  142|       |
  143|       |	// depth guard: depth(parent)+1+max_depth(child_subtree) <= NODE_MAX_DEPTH
  144|   172k|	int pd = node_depth_from_root(parent);
  145|   172k|	int cd = node_subtree_max_depth(child);
  146|   172k|	if (pd + 1 + cd > NODE_MAX_DEPTH) {
  ------------------
  |  |   33|   172k|#define NODE_MAX_DEPTH 512
  ------------------
  |  Branch (146:6): [True: 0, False: 172k]
  ------------------
  147|      0|		return NODE_ERR_MAX_DEPTH;
  ------------------
  |  |   41|      0|#define NODE_ERR_MAX_DEPTH    -5
  ------------------
  148|      0|	}
  149|       |
  150|   172k|	if (!parent->children) {
  ------------------
  |  Branch (150:6): [True: 14.0k, False: 158k]
  ------------------
  151|  14.0k|		parent->children = node_list_create();
  152|  14.0k|		if (!parent->children) return NODE_ERR_NO_MEM;
  ------------------
  |  |   38|      0|#define NODE_ERR_NO_MEM       -2
  ------------------
  |  Branch (152:7): [True: 0, False: 14.0k]
  ------------------
  153|  14.0k|	}
  154|   172k|	int res = node_list_add(parent->children, child);
  155|   172k|	if (res == 0) {
  ------------------
  |  Branch (155:6): [True: 172k, False: 0]
  ------------------
  156|   172k|		child->parent = parent;
  157|   172k|		parent->count++;
  158|   172k|	}
  159|   172k|	return res;
  160|   172k|}
node_detach:
  163|   172k|{
  164|   172k|	if (!parent || !child) return NODE_ERR_INVALID_ARG;
  ------------------
  |  |   37|      0|#define NODE_ERR_INVALID_ARG  -1
  ------------------
  |  Branch (164:6): [True: 0, False: 172k]
  |  Branch (164:17): [True: 0, False: 172k]
  ------------------
  165|   172k|	if (!parent->children) return NODE_ERR_NOT_FOUND;
  ------------------
  |  |   42|      0|#define NODE_ERR_NOT_FOUND    -6
  ------------------
  |  Branch (165:6): [True: 0, False: 172k]
  ------------------
  166|   172k|	if (child->parent && child->parent != parent) return NODE_ERR_PARENT;
  ------------------
  |  |   39|      0|#define NODE_ERR_PARENT       -3
  ------------------
  |  Branch (166:6): [True: 172k, False: 0]
  |  Branch (166:23): [True: 0, False: 172k]
  ------------------
  167|       |
  168|   172k|	int node_index = node_list_remove(parent->children, child);
  169|   172k|	if (node_index >= 0) {
  ------------------
  |  Branch (169:6): [True: 172k, False: 0]
  ------------------
  170|   172k|		if (parent->count > 0) parent->count--;
  ------------------
  |  Branch (170:7): [True: 172k, False: 0]
  ------------------
  171|   172k|		child->parent = NULL;
  172|   172k|		child->prev = NULL;
  173|       |		child->next = NULL;
  174|   172k|	}
  175|   172k|	return node_index;
  176|   172k|}
node_first_child:
  262|   421k|{
  263|   421k|	if (!node || !node->children) return NULL;
  ------------------
  |  Branch (263:6): [True: 0, False: 421k]
  |  Branch (263:15): [True: 161k, False: 260k]
  ------------------
  264|   260k|	return node->children->begin;
  265|   421k|}
node_next_sibling:
  274|   936k|{
  275|   936k|	if (!node) return NULL;
  ------------------
  |  Branch (275:6): [True: 0, False: 936k]
  ------------------
  276|   936k|	return node->next;
  277|   936k|}
node.c:would_create_cycle:
  124|   172k|{
  125|       |	// if parent is anywhere in child's ancestor chain => cycle
  126|   344k|	for (node_t p = parent; p; p = p->parent) {
  ------------------
  |  Branch (126:26): [True: 172k, False: 172k]
  ------------------
  127|   172k|		if (p == child) return 1;
  ------------------
  |  Branch (127:7): [True: 0, False: 172k]
  ------------------
  128|   172k|	}
  129|   172k|	return 0;
  130|   172k|}
node.c:node_depth_from_root:
   78|   172k|{
   79|   172k|	int d = 0;
   80|   172k|	while (n && n->parent) {
  ------------------
  |  Branch (80:9): [True: 172k, False: 0]
  |  Branch (80:14): [True: 0, False: 172k]
  ------------------
   81|      0|		d++;
   82|      0|		n = n->parent;
   83|      0|		if (d > NODE_MAX_DEPTH) return d; // early out
  ------------------
  |  |   33|      0|#define NODE_MAX_DEPTH 512
  ------------------
  |  Branch (83:7): [True: 0, False: 0]
  ------------------
   84|      0|	}
   85|   172k|	return d;
   86|   172k|}
node.c:node_subtree_max_depth:
   89|   172k|{
   90|   172k|	if (!root) return 0;
  ------------------
  |  Branch (90:6): [True: 0, False: 172k]
  ------------------
   91|       |
   92|   172k|	typedef struct { node_t n; int depth; } frame_t;
   93|   172k|	size_t cap = 64, sp = 0;
   94|   172k|	frame_t *st = (frame_t*)malloc(cap * sizeof(*st));
   95|   172k|	if (!st) return NODE_MAX_DEPTH + 1;
  ------------------
  |  |   33|      0|#define NODE_MAX_DEPTH 512
  ------------------
  |  Branch (95:6): [True: 0, False: 172k]
  ------------------
   96|       |
   97|   172k|	st[sp++] = (frame_t){ root, 0 };
   98|   172k|	int maxd = 0;
   99|       |
  100|  1.28M|	while (sp) {
  ------------------
  |  Branch (100:9): [True: 1.10M, False: 172k]
  ------------------
  101|  1.10M|		frame_t f = st[--sp];
  102|  1.10M|		if (f.depth > maxd) maxd = f.depth;
  ------------------
  |  Branch (102:7): [True: 25.9k, False: 1.08M]
  ------------------
  103|  1.10M|		if (maxd > NODE_MAX_DEPTH) break;
  ------------------
  |  |   33|  1.10M|#define NODE_MAX_DEPTH 512
  ------------------
  |  Branch (103:7): [True: 0, False: 1.10M]
  ------------------
  104|       |
  105|  1.10M|		if (!f.n->children) continue;
  ------------------
  |  Branch (105:7): [True: 1.03M, False: 72.8k]
  ------------------
  106|       |
  107|  1.00M|		for (node_t ch = node_first_child(f.n); ch; ch = node_next_sibling(ch)) {
  ------------------
  |  Branch (107:43): [True: 936k, False: 72.8k]
  ------------------
  108|   936k|			if (sp == cap) {
  ------------------
  |  Branch (108:8): [True: 643, False: 935k]
  ------------------
  109|    643|				cap *= 2;
  110|    643|				frame_t *tmp = (frame_t*)realloc(st, cap * sizeof(*st));
  111|    643|				if (!tmp) { maxd = NODE_MAX_DEPTH + 1; goto out; }
  ------------------
  |  |   33|      0|#define NODE_MAX_DEPTH 512
  ------------------
  |  Branch (111:9): [True: 0, False: 643]
  ------------------
  112|    643|				st = tmp;
  113|    643|			}
  114|   936k|			st[sp++] = (frame_t){ ch, f.depth + 1 };
  115|   936k|		}
  116|  72.8k|	}
  117|       |
  118|   172k|out:
  119|   172k|	free(st);
  120|   172k|	return maxd;
  121|   172k|}

node_list_destroy:
   32|   175k|{
   33|   175k|	free(list);
   34|   175k|}
node_list_create:
   37|  14.0k|{
   38|  14.0k|	node_list_t list = (node_list_t)calloc(1, sizeof(struct node_list));
   39|  14.0k|	if (list == NULL) {
  ------------------
  |  Branch (39:6): [True: 0, False: 14.0k]
  ------------------
   40|      0|		return NULL;
   41|      0|	}
   42|       |
   43|       |	// Initialize structure
   44|  14.0k|	list->begin = NULL;
   45|       |	list->end = NULL;
   46|  14.0k|	list->count = 0;
   47|  14.0k|	return list;
   48|  14.0k|}
node_list_add:
   51|   172k|{
   52|   172k|	if (!list || !node) return NODE_ERR_INVALID_ARG;
  ------------------
  |  |   37|      0|#define NODE_ERR_INVALID_ARG  -1
  ------------------
  |  Branch (52:6): [True: 0, False: 172k]
  |  Branch (52:15): [True: 0, False: 172k]
  ------------------
   53|       |
   54|       |	// Find the last element in the list
   55|   172k|	node_t last = list->end;
   56|       |
   57|       |	// Setup our new node as the new last element
   58|   172k|	node->next = NULL;
   59|   172k|	node->prev = last;
   60|       |
   61|       |	// Set the next element of our old "last" element
   62|   172k|	if (last) {
  ------------------
  |  Branch (62:6): [True: 158k, False: 14.0k]
  ------------------
   63|       |		// but only if the node list is not empty
   64|   158k|		last->next = node;
   65|   158k|	} else {
   66|       |		// otherwise this is the start of the list
   67|  14.0k|		list->begin = node;
   68|  14.0k|	}
   69|       |
   70|       |	// Set the lists prev to the new last element
   71|   172k|	list->end = node;
   72|       |
   73|       |	// Increment our node count for this list
   74|   172k|	list->count++;
   75|   172k|	return NODE_ERR_SUCCESS;
  ------------------
  |  |   36|   172k|#define NODE_ERR_SUCCESS       0
  ------------------
   76|   172k|}
node_list_remove:
  120|   172k|{
  121|   172k|	if (!list || !node) return NODE_ERR_INVALID_ARG;
  ------------------
  |  |   37|      0|#define NODE_ERR_INVALID_ARG  -1
  ------------------
  |  Branch (121:6): [True: 0, False: 172k]
  |  Branch (121:15): [True: 0, False: 172k]
  ------------------
  122|   172k|	if (list->count == 0) return NODE_ERR_NOT_FOUND;
  ------------------
  |  |   42|      0|#define NODE_ERR_NOT_FOUND    -6
  ------------------
  |  Branch (122:6): [True: 0, False: 172k]
  ------------------
  123|       |
  124|   172k|	int node_index = 0;
  125|   172k|	for (node_t n = list->begin; n; n = n->next, node_index++) {
  ------------------
  |  Branch (125:31): [True: 172k, False: 0]
  ------------------
  126|   172k|		if (node != n) continue;
  ------------------
  |  Branch (126:7): [True: 0, False: 172k]
  ------------------
  127|       |
  128|   172k|		node_t newnode = node->next;
  129|   172k|		if (node->prev) {
  ------------------
  |  Branch (129:7): [True: 0, False: 172k]
  ------------------
  130|      0|			node->prev->next = newnode;
  131|   172k|		} else {
  132|       |			// we just removed the first element
  133|   172k|			list->begin = newnode;
  134|   172k|		}
  135|       |
  136|   172k|		if (newnode) {
  ------------------
  |  Branch (136:7): [True: 158k, False: 14.0k]
  ------------------
  137|   158k|			newnode->prev = node->prev;
  138|   158k|		} else {
  139|       |			// we removed the last element, set new end
  140|  14.0k|			list->end = node->prev;
  141|  14.0k|		}
  142|       |
  143|       |		// fully detach node from list
  144|   172k|		node->prev = NULL;
  145|   172k|		node->next = NULL;
  146|       |
  147|   172k|		list->count--;
  148|   172k|		return node_index;
  149|   172k|	}
  150|      0|	return NODE_ERR_NOT_FOUND;
  ------------------
  |  |   42|      0|#define NODE_ERR_NOT_FOUND    -6
  ------------------
  151|   172k|}

plist_bin_init:
  254|      2|{
  255|       |    /* init binary plist stuff */
  256|      2|#ifdef DEBUG
  257|      2|    char *env_debug = getenv("PLIST_BIN_DEBUG");
  258|      2|    if (env_debug && !strcmp(env_debug, "1")) {
  ------------------
  |  Branch (258:9): [True: 0, False: 2]
  |  Branch (258:22): [True: 0, False: 0]
  ------------------
  259|      0|        plist_bin_debug = 1;
  260|      0|    }
  261|      2|#endif
  262|      2|}
plist_from_bin:
  906|  2.36k|{
  907|  2.36k|    bplist_trailer_t *trailer = NULL;
  908|  2.36k|    uint8_t offset_size = 0;
  909|  2.36k|    uint8_t ref_size = 0;
  910|  2.36k|    uint64_t num_objects = 0;
  911|  2.36k|    uint64_t root_object = 0;
  912|  2.36k|    const char *offset_table = NULL;
  913|  2.36k|    uint64_t offset_table_size = 0;
  914|  2.36k|    const char *start_data = NULL;
  915|  2.36k|    const char *end_data = NULL;
  916|       |
  917|  2.36k|    if (!plist) {
  ------------------
  |  Branch (917:9): [True: 0, False: 2.36k]
  ------------------
  918|      0|        return PLIST_ERR_INVALID_ARG;
  919|      0|    }
  920|  2.36k|    *plist = NULL;
  921|  2.36k|    if (!plist_bin || length == 0) {
  ------------------
  |  Branch (921:9): [True: 0, False: 2.36k]
  |  Branch (921:23): [True: 0, False: 2.36k]
  ------------------
  922|      0|        return PLIST_ERR_INVALID_ARG;
  923|      0|    }
  924|       |
  925|       |    //first check we have enough data
  926|  2.36k|    if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + sizeof(bplist_trailer_t))) {
  ------------------
  |  |   44|  2.36k|#define BPLIST_MAGIC_SIZE       6
  ------------------
                  if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + sizeof(bplist_trailer_t))) {
  ------------------
  |  |   47|  2.36k|#define BPLIST_VERSION_SIZE     2
  ------------------
  |  Branch (926:9): [True: 12, False: 2.35k]
  ------------------
  927|     12|        PLIST_BIN_ERR("plist data is to small to hold a binary plist\n");
  ------------------
  |  |  246|     12|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 12]
  |  |  ------------------
  ------------------
  928|     12|        return PLIST_ERR_PARSE;
  929|     12|    }
  930|       |    //check that plist_bin in actually a plist
  931|  2.35k|    if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0) {
  ------------------
  |  |   43|  2.35k|#define BPLIST_MAGIC            ((uint8_t*)"bplist")
  ------------------
                  if (memcmp(plist_bin, BPLIST_MAGIC, BPLIST_MAGIC_SIZE) != 0) {
  ------------------
  |  |   44|  2.35k|#define BPLIST_MAGIC_SIZE       6
  ------------------
  |  Branch (931:9): [True: 36, False: 2.31k]
  ------------------
  932|     36|        PLIST_BIN_ERR("bplist magic mismatch\n");
  ------------------
  |  |  246|     36|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 36]
  |  |  ------------------
  ------------------
  933|     36|        return PLIST_ERR_PARSE;
  934|     36|    }
  935|       |    //check for known version
  936|  2.31k|    if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0) {
  ------------------
  |  |   44|  2.31k|#define BPLIST_MAGIC_SIZE       6
  ------------------
                  if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0) {
  ------------------
  |  |   46|  2.31k|#define BPLIST_VERSION          ((uint8_t*)"00")
  ------------------
                  if (memcmp(plist_bin + BPLIST_MAGIC_SIZE, BPLIST_VERSION, BPLIST_VERSION_SIZE) != 0) {
  ------------------
  |  |   47|  2.31k|#define BPLIST_VERSION_SIZE     2
  ------------------
  |  Branch (936:9): [True: 38, False: 2.28k]
  ------------------
  937|     38|        PLIST_BIN_ERR("unsupported binary plist version '%.2s\n", plist_bin+BPLIST_MAGIC_SIZE);
  ------------------
  |  |  246|     38|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 38]
  |  |  ------------------
  ------------------
  938|     38|        return PLIST_ERR_PARSE;
  939|     38|    }
  940|       |
  941|  2.28k|    start_data = plist_bin + BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE;
  ------------------
  |  |   44|  2.28k|#define BPLIST_MAGIC_SIZE       6
  ------------------
                  start_data = plist_bin + BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE;
  ------------------
  |  |   47|  2.28k|#define BPLIST_VERSION_SIZE     2
  ------------------
  942|  2.28k|    end_data = plist_bin + length - sizeof(bplist_trailer_t);
  943|       |
  944|       |    //now parse trailer
  945|  2.28k|    trailer = (bplist_trailer_t*)end_data;
  946|       |
  947|  2.28k|    offset_size = trailer->offset_size;
  948|  2.28k|    ref_size = trailer->ref_size;
  949|  2.28k|    num_objects = be64toh(trailer->num_objects);
  950|  2.28k|    root_object = be64toh(trailer->root_object_index);
  951|       |
  952|  2.28k|    uint64_t offset_table_offset = be64toh(trailer->offset_table_offset);
  953|  2.28k|    uint64_t max_valid_offset = (uint64_t)length - sizeof(bplist_trailer_t);
  954|  2.28k|    if (offset_table_offset > max_valid_offset) {
  ------------------
  |  Branch (954:9): [True: 105, False: 2.17k]
  ------------------
  955|    105|        PLIST_BIN_ERR("offset table offset outside of valid range\n");
  ------------------
  |  |  246|    105|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 105]
  |  |  ------------------
  ------------------
  956|    105|        return PLIST_ERR_PARSE;
  957|    105|    }
  958|  2.17k|    offset_table = (char *)(plist_bin + offset_table_offset);
  959|       |
  960|  2.17k|    if (num_objects == 0) {
  ------------------
  |  Branch (960:9): [True: 1, False: 2.17k]
  ------------------
  961|      1|        PLIST_BIN_ERR("number of objects must be larger than 0\n");
  ------------------
  |  |  246|      1|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 1]
  |  |  ------------------
  ------------------
  962|      1|        return PLIST_ERR_PARSE;
  963|      1|    }
  964|       |
  965|  2.17k|    if (offset_size == 0) {
  ------------------
  |  Branch (965:9): [True: 11, False: 2.16k]
  ------------------
  966|     11|        PLIST_BIN_ERR("offset size in trailer must be larger than 0\n");
  ------------------
  |  |  246|     11|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 11]
  |  |  ------------------
  ------------------
  967|     11|        return PLIST_ERR_PARSE;
  968|     11|    }
  969|       |
  970|  2.16k|    if (ref_size == 0) {
  ------------------
  |  Branch (970:9): [True: 3, False: 2.16k]
  ------------------
  971|      3|        PLIST_BIN_ERR("object reference size in trailer must be larger than 0\n");
  ------------------
  |  |  246|      3|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 3]
  |  |  ------------------
  ------------------
  972|      3|        return PLIST_ERR_PARSE;
  973|      3|    }
  974|       |
  975|  2.16k|    if (root_object >= num_objects) {
  ------------------
  |  Branch (975:9): [True: 80, False: 2.08k]
  ------------------
  976|     80|        PLIST_BIN_ERR("root object index (%" PRIu64 ") must be smaller than number of objects (%" PRIu64 ")\n", root_object, num_objects);
  ------------------
  |  |  246|     80|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 80]
  |  |  ------------------
  ------------------
  977|     80|        return PLIST_ERR_PARSE;
  978|     80|    }
  979|       |
  980|  2.08k|    if (offset_table < start_data || offset_table >= end_data) {
  ------------------
  |  Branch (980:9): [True: 47, False: 2.03k]
  |  Branch (980:38): [True: 33, False: 2.00k]
  ------------------
  981|     80|        PLIST_BIN_ERR("offset table offset points outside of valid range\n");
  ------------------
  |  |  246|     80|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 80]
  |  |  ------------------
  ------------------
  982|     80|        return PLIST_ERR_PARSE;
  983|     80|    }
  984|       |
  985|  2.00k|    if (uint64_mul_overflow(num_objects, offset_size, &offset_table_size)) {
  ------------------
  |  |  221|  2.00k|#define uint64_mul_overflow(a, b, r) __builtin_umulll_overflow(a, b, (unsigned long long*)(r))
  |  |  ------------------
  |  |  |  Branch (221:38): [True: 4, False: 1.99k]
  |  |  ------------------
  ------------------
  986|      4|        PLIST_BIN_ERR("integer overflow when calculating offset table size\n");
  ------------------
  |  |  246|      4|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 4]
  |  |  ------------------
  ------------------
  987|      4|        return PLIST_ERR_PARSE;
  988|      4|    }
  989|       |
  990|  1.99k|    if (offset_table_size > (uint64_t)(end_data - offset_table)) {
  ------------------
  |  Branch (990:9): [True: 104, False: 1.89k]
  ------------------
  991|    104|        PLIST_BIN_ERR("offset table points outside of valid range\n");
  ------------------
  |  |  246|    104|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 104]
  |  |  ------------------
  ------------------
  992|    104|        return PLIST_ERR_PARSE;
  993|    104|    }
  994|       |
  995|  1.89k|    struct bplist_data bplist;
  996|  1.89k|    bplist.data = plist_bin;
  997|  1.89k|    bplist.size = length;
  998|  1.89k|    bplist.num_objects = num_objects;
  999|  1.89k|    bplist.ref_size = ref_size;
 1000|  1.89k|    bplist.offset_size = offset_size;
 1001|  1.89k|    bplist.offset_table = offset_table;
 1002|  1.89k|    bplist.level = 0;
 1003|  1.89k|    bplist.used_indexes = ptr_array_new(16);
 1004|  1.89k|    bplist.err = PLIST_ERR_SUCCESS;
 1005|       |
 1006|  1.89k|    if (!bplist.used_indexes) {
  ------------------
  |  Branch (1006:9): [True: 0, False: 1.89k]
  ------------------
 1007|      0|        PLIST_BIN_ERR("failed to create array to hold used node indexes. Out of memory?\n");
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1008|      0|        return PLIST_ERR_NO_MEM;
 1009|      0|    }
 1010|       |
 1011|  1.89k|    *plist = parse_bin_node_at_index(&bplist, root_object);
 1012|       |
 1013|  1.89k|    ptr_array_free(bplist.used_indexes);
 1014|       |
 1015|  1.89k|    if (!*plist) {
  ------------------
  |  Branch (1015:9): [True: 1.67k, False: 218]
  ------------------
 1016|  1.67k|        return (bplist.err != PLIST_ERR_SUCCESS) ? bplist.err : PLIST_ERR_PARSE;
  ------------------
  |  Branch (1016:16): [True: 453, False: 1.22k]
  ------------------
 1017|  1.67k|    }
 1018|       |
 1019|    218|    return PLIST_ERR_SUCCESS;
 1020|  1.89k|}
bplist.c:parse_bin_node_at_index:
  835|   176k|{
  836|   176k|    int i = 0;
  837|   176k|    const char* ptr = NULL;
  838|   176k|    plist_t plist = NULL;
  839|   176k|    const char* idx_ptr = NULL;
  840|       |
  841|   176k|    if (node_index >= bplist->num_objects) {
  ------------------
  |  Branch (841:9): [True: 0, False: 176k]
  ------------------
  842|      0|        PLIST_BIN_ERR("node index (%u) must be smaller than the number of objects (%" PRIu64 ")\n", node_index, bplist->num_objects);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  843|      0|        bplist->err = PLIST_ERR_PARSE;
  844|      0|        return NULL;
  845|      0|    }
  846|       |
  847|   176k|    idx_ptr = bplist->offset_table + node_index * bplist->offset_size;
  848|   176k|    if (idx_ptr < bplist->offset_table ||
  ------------------
  |  Branch (848:9): [True: 0, False: 176k]
  ------------------
  849|   176k|        idx_ptr >= bplist->offset_table + bplist->num_objects * bplist->offset_size) {
  ------------------
  |  Branch (849:9): [True: 0, False: 176k]
  ------------------
  850|      0|        PLIST_BIN_ERR("node index %u points outside of valid range\n", node_index);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  851|      0|        bplist->err = PLIST_ERR_PARSE;
  852|      0|        return NULL;
  853|      0|    }
  854|       |
  855|   176k|    uint64_t node_offset = UINT_TO_HOST(idx_ptr, bplist->offset_size);
  ------------------
  |  |  187|   176k|	({ \
  |  |  188|   176k|		union plist_uint_ptr __up; \
  |  |  189|   176k|		__up.src = ((n) > 8) ? (const char*)(x) + ((n) - 8) : (const char*)(x); \
  |  |  ------------------
  |  |  |  Branch (189:14): [True: 222, False: 176k]
  |  |  ------------------
  |  |  190|   176k|		((n) >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (190:4): [True: 446, False: 175k]
  |  |  ------------------
  |  |  191|   176k|		((n) == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (191:4): [True: 211, False: 175k]
  |  |  ------------------
  |  |  192|   175k|		((n) == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (192:4): [True: 489, False: 175k]
  |  |  ------------------
  |  |  193|   175k|		((n) == 1 ? *__up.u8ptr : \
  |  |  ------------------
  |  |  |  Branch (193:4): [True: 175k, False: 244]
  |  |  ------------------
  |  |  194|   175k|		beNtoh( get_unaligned(__up.u64ptr), n) \
  |  |  ------------------
  |  |  |  |  170|   175k|#define beNtoh(x,n) be64toh((x) << ((8-(n)) << 3))
  |  |  ------------------
  |  |  195|   175k|		)))); \
  |  |  196|   176k|	})
  ------------------
  856|   176k|    if (node_offset > (uint64_t)bplist->size) {
  ------------------
  |  Branch (856:9): [True: 126, False: 176k]
  ------------------
  857|    126|        PLIST_BIN_ERR("node offset overflow (%llu)\n", node_offset);
  ------------------
  |  |  246|    126|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 126]
  |  |  ------------------
  ------------------
  858|    126|        bplist->err = PLIST_ERR_PARSE;
  859|    126|        return NULL;
  860|    126|    }
  861|   176k|    ptr = bplist->data + node_offset;
  862|       |    /* make sure the node offset is in a sane range */
  863|   176k|    if ((ptr < bplist->data+BPLIST_MAGIC_SIZE+BPLIST_VERSION_SIZE) || (ptr >= bplist->offset_table)) {
  ------------------
  |  |   44|   176k|#define BPLIST_MAGIC_SIZE       6
  ------------------
                  if ((ptr < bplist->data+BPLIST_MAGIC_SIZE+BPLIST_VERSION_SIZE) || (ptr >= bplist->offset_table)) {
  ------------------
  |  |   47|   176k|#define BPLIST_VERSION_SIZE     2
  ------------------
  |  Branch (863:9): [True: 10, False: 176k]
  |  Branch (863:71): [True: 25, False: 176k]
  ------------------
  864|     35|        PLIST_BIN_ERR("offset for node index %u points outside of valid range\n", node_index);
  ------------------
  |  |  246|     35|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 35]
  |  |  ------------------
  ------------------
  865|     35|        bplist->err = PLIST_ERR_PARSE;
  866|     35|        return NULL;
  867|     35|    }
  868|       |
  869|       |    /* check nesting depth */
  870|   176k|    if (bplist->level > PLIST_MAX_NESTING_DEPTH) {
  ------------------
  |  |   56|   176k|#define PLIST_MAX_NESTING_DEPTH NODE_MAX_DEPTH
  |  |  ------------------
  |  |  |  |   33|   176k|#define NODE_MAX_DEPTH 512
  |  |  ------------------
  ------------------
  |  Branch (870:9): [True: 0, False: 176k]
  ------------------
  871|      0|        PLIST_BIN_ERR("maximum nesting depth (%u) exceeded\n",(unsigned)PLIST_MAX_NESTING_DEPTH);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  872|      0|        bplist->err = PLIST_ERR_MAX_NESTING;
  873|      0|        return NULL;
  874|      0|    }
  875|       |
  876|       |    /* store node_index for current recursion level */
  877|   176k|    if ((uint32_t)ptr_array_size(bplist->used_indexes) < bplist->level+1) {
  ------------------
  |  Branch (877:9): [True: 3.92k, False: 172k]
  ------------------
  878|  7.85k|        while ((uint32_t)ptr_array_size(bplist->used_indexes) < bplist->level+1) {
  ------------------
  |  Branch (878:16): [True: 3.92k, False: 3.92k]
  ------------------
  879|  3.92k|            ptr_array_add(bplist->used_indexes, (void*)(uintptr_t)node_index);
  880|  3.92k|        }
  881|   172k|    } else {
  882|   172k|	ptr_array_set(bplist->used_indexes, (void*)(uintptr_t)node_index, bplist->level);
  883|   172k|    }
  884|       |
  885|       |    /* recursion check */
  886|   176k|    if (bplist->level > 0) {
  ------------------
  |  Branch (886:9): [True: 174k, False: 1.74k]
  ------------------
  887|  1.34M|        for (i = bplist->level-1; i >= 0; i--) {
  ------------------
  |  Branch (887:35): [True: 1.17M, False: 174k]
  ------------------
  888|  1.17M|            void *node_i = ptr_array_index(bplist->used_indexes, i);
  889|  1.17M|            void *node_level = ptr_array_index(bplist->used_indexes, bplist->level);
  890|  1.17M|            if (node_i == node_level) {
  ------------------
  |  Branch (890:17): [True: 292, False: 1.17M]
  ------------------
  891|    292|                PLIST_BIN_ERR("recursion detected in binary plist\n");
  ------------------
  |  |  246|    292|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 292]
  |  |  ------------------
  ------------------
  892|    292|                bplist->err = PLIST_ERR_CIRCULAR_REF;
  893|    292|                return NULL;
  894|    292|            }
  895|  1.17M|        }
  896|   174k|    }
  897|       |
  898|       |    /* finally parse node */
  899|   175k|    bplist->level++;
  900|   175k|    plist = parse_bin_node(bplist, &ptr);
  901|   175k|    bplist->level--;
  902|   175k|    return plist;
  903|   176k|}
bplist.c:parse_bin_node:
  662|   175k|{
  663|   175k|    uint16_t type = 0;
  664|   175k|    uint64_t size = 0;
  665|   175k|    uint64_t pobject = 0;
  666|   175k|    uint64_t poffset_table = (uint64_t)(uintptr_t)bplist->offset_table;
  667|       |
  668|   175k|    if (!object)
  ------------------
  |  Branch (668:9): [True: 0, False: 175k]
  ------------------
  669|      0|        return NULL;
  670|       |
  671|   175k|    type = (**object) & BPLIST_MASK;
  672|   175k|    size = (**object) & BPLIST_FILL;
  673|   175k|    (*object)++;
  674|       |
  675|   175k|    if (size == BPLIST_FILL) {
  ------------------
  |  Branch (675:9): [True: 3.29k, False: 172k]
  ------------------
  676|  3.29k|        switch (type) {
  677|    347|        case BPLIST_DATA:
  ------------------
  |  Branch (677:9): [True: 347, False: 2.94k]
  ------------------
  678|  1.01k|        case BPLIST_STRING:
  ------------------
  |  Branch (678:9): [True: 672, False: 2.62k]
  ------------------
  679|  1.42k|        case BPLIST_UNICODE:
  ------------------
  |  Branch (679:9): [True: 410, False: 2.88k]
  ------------------
  680|  1.85k|        case BPLIST_ARRAY:
  ------------------
  |  Branch (680:9): [True: 426, False: 2.86k]
  ------------------
  681|  2.23k|        case BPLIST_SET:
  ------------------
  |  Branch (681:9): [True: 381, False: 2.91k]
  ------------------
  682|  2.74k|        case BPLIST_DICT:
  ------------------
  |  Branch (682:9): [True: 506, False: 2.78k]
  ------------------
  683|  2.74k|        {
  684|  2.74k|            uint16_t next_size = **object & BPLIST_FILL;
  685|  2.74k|            if ((**object & BPLIST_MASK) != BPLIST_INT) {
  ------------------
  |  Branch (685:17): [True: 9, False: 2.73k]
  ------------------
  686|      9|                PLIST_BIN_ERR("%s: invalid size node type for node type 0x%02x: found 0x%02x, expected 0x%02x\n", __func__, type, **object & BPLIST_MASK, BPLIST_INT);
  ------------------
  |  |  246|      9|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 9]
  |  |  ------------------
  ------------------
  687|      9|                return NULL;
  688|      9|            }
  689|  2.73k|            (*object)++;
  690|  2.73k|            next_size = 1 << next_size;
  691|  2.73k|            if (*object + next_size > bplist->offset_table) {
  ------------------
  |  Branch (691:17): [True: 2, False: 2.73k]
  ------------------
  692|      2|                PLIST_BIN_ERR("%s: size node data bytes for node type 0x%02x point outside of valid range\n", __func__, type);
  ------------------
  |  |  246|      2|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 2]
  |  |  ------------------
  ------------------
  693|      2|                return NULL;
  694|      2|            }
  695|  2.73k|            size = UINT_TO_HOST(*object, next_size);
  ------------------
  |  |  187|  2.73k|	({ \
  |  |  188|  2.73k|		union plist_uint_ptr __up; \
  |  |  189|  2.73k|		__up.src = ((n) > 8) ? (const char*)(x) + ((n) - 8) : (const char*)(x); \
  |  |  ------------------
  |  |  |  Branch (189:14): [True: 411, False: 2.32k]
  |  |  ------------------
  |  |  190|  2.73k|		((n) >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (190:4): [True: 792, False: 1.93k]
  |  |  ------------------
  |  |  191|  2.73k|		((n) == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (191:4): [True: 319, False: 1.62k]
  |  |  ------------------
  |  |  192|  1.93k|		((n) == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (192:4): [True: 333, False: 1.28k]
  |  |  ------------------
  |  |  193|  1.62k|		((n) == 1 ? *__up.u8ptr : \
  |  |  ------------------
  |  |  |  Branch (193:4): [True: 1.28k, False: 0]
  |  |  ------------------
  |  |  194|  1.28k|		beNtoh( get_unaligned(__up.u64ptr), n) \
  |  |  ------------------
  |  |  |  |  170|  1.28k|#define beNtoh(x,n) be64toh((x) << ((8-(n)) << 3))
  |  |  ------------------
  |  |  195|  1.28k|		)))); \
  |  |  196|  2.73k|	})
  ------------------
  696|  2.73k|            (*object) += next_size;
  697|  2.73k|            break;
  698|  2.73k|        }
  699|    550|        default:
  ------------------
  |  Branch (699:9): [True: 550, False: 2.74k]
  ------------------
  700|    550|            break;
  701|  3.29k|        }
  702|  3.29k|    }
  703|       |
  704|   175k|    pobject = (uint64_t)(uintptr_t)*object;
  705|       |
  706|   175k|    switch (type)
  707|   175k|    {
  708|       |
  709|  7.20k|    case BPLIST_NULL:
  ------------------
  |  Branch (709:5): [True: 7.20k, False: 168k]
  ------------------
  710|  7.20k|        switch (size)
  711|  7.20k|        {
  712|       |
  713|    329|        case BPLIST_TRUE:
  ------------------
  |  Branch (713:9): [True: 329, False: 6.87k]
  ------------------
  714|    329|        {
  715|    329|            plist_data_t data = plist_new_plist_data();
  716|    329|            if (!data) {
  ------------------
  |  Branch (716:17): [True: 0, False: 329]
  ------------------
  717|      0|                PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  718|      0|                return NULL;
  719|      0|            }
  720|    329|            data->type = PLIST_BOOLEAN;
  721|    329|            data->boolval = TRUE;
  ------------------
  |  |   28|    329|#define TRUE 1
  ------------------
  722|    329|            data->length = 1;
  723|    329|            return node_create(NULL, data);
  724|    329|        }
  725|       |
  726|    299|        case BPLIST_FALSE:
  ------------------
  |  Branch (726:9): [True: 299, False: 6.90k]
  ------------------
  727|    299|        {
  728|    299|            plist_data_t data = plist_new_plist_data();
  729|    299|            if (!data) {
  ------------------
  |  Branch (729:17): [True: 0, False: 299]
  ------------------
  730|      0|                PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  731|      0|                return NULL;
  732|      0|            }
  733|    299|            data->type = PLIST_BOOLEAN;
  734|    299|            data->boolval = FALSE;
  ------------------
  |  |   32|    299|#define FALSE 0
  ------------------
  735|    299|            data->length = 1;
  736|    299|            return node_create(NULL, data);
  737|    299|        }
  738|       |
  739|  6.57k|        case BPLIST_NULL:
  ------------------
  |  Branch (739:9): [True: 6.57k, False: 629]
  ------------------
  740|  6.57k|        {
  741|  6.57k|            plist_data_t data = plist_new_plist_data();
  742|  6.57k|            if (!data) {
  ------------------
  |  Branch (742:17): [True: 0, False: 6.57k]
  ------------------
  743|      0|                PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  744|      0|                return NULL;
  745|      0|            }
  746|  6.57k|            data->type = PLIST_NULL;
  747|  6.57k|            data->length = 0;
  748|  6.57k|            return node_create(NULL, data);
  749|  6.57k|        }
  750|       |
  751|      1|        default:
  ------------------
  |  Branch (751:9): [True: 1, False: 7.20k]
  ------------------
  752|      1|            return NULL;
  753|  7.20k|        }
  754|       |
  755|  4.97k|    case BPLIST_INT:
  ------------------
  |  Branch (755:5): [True: 4.97k, False: 170k]
  ------------------
  756|  4.97k|        if (pobject + (uint64_t)(1 << size) > poffset_table) {
  ------------------
  |  Branch (756:13): [True: 29, False: 4.94k]
  ------------------
  757|     29|            PLIST_BIN_ERR("%s: BPLIST_INT data bytes point outside of valid range\n", __func__);
  ------------------
  |  |  246|     29|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 29]
  |  |  ------------------
  ------------------
  758|     29|            return NULL;
  759|     29|        }
  760|  4.94k|        return parse_int_node(object, size);
  761|       |
  762|    506|    case BPLIST_REAL:
  ------------------
  |  Branch (762:5): [True: 506, False: 175k]
  ------------------
  763|    506|        if (pobject + (uint64_t)(1 << size) > poffset_table) {
  ------------------
  |  Branch (763:13): [True: 31, False: 475]
  ------------------
  764|     31|            PLIST_BIN_ERR("%s: BPLIST_REAL data bytes point outside of valid range\n", __func__);
  ------------------
  |  |  246|     31|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 31]
  |  |  ------------------
  ------------------
  765|     31|            return NULL;
  766|     31|        }
  767|    475|        return parse_real_node(object, size);
  768|       |
  769|  1.07k|    case BPLIST_DATE:
  ------------------
  |  Branch (769:5): [True: 1.07k, False: 174k]
  ------------------
  770|  1.07k|        if (3 != size) {
  ------------------
  |  Branch (770:13): [True: 5, False: 1.07k]
  ------------------
  771|      5|            PLIST_BIN_ERR("%s: invalid data size for BPLIST_DATE node\n", __func__);
  ------------------
  |  |  246|      5|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 5]
  |  |  ------------------
  ------------------
  772|      5|            return NULL;
  773|      5|        }
  774|  1.07k|        if (pobject + (uint64_t)(1 << size) > poffset_table) {
  ------------------
  |  Branch (774:13): [True: 6, False: 1.06k]
  ------------------
  775|      6|            PLIST_BIN_ERR("%s: BPLIST_DATE data bytes point outside of valid range\n", __func__);
  ------------------
  |  |  246|      6|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 6]
  |  |  ------------------
  ------------------
  776|      6|            return NULL;
  777|      6|        }
  778|  1.06k|        return parse_date_node(object, size);
  779|       |
  780|  76.4k|    case BPLIST_DATA:
  ------------------
  |  Branch (780:5): [True: 76.4k, False: 99.4k]
  ------------------
  781|  76.4k|        if (pobject + size < pobject || pobject + size > poffset_table) {
  ------------------
  |  Branch (781:13): [True: 3, False: 76.4k]
  |  Branch (781:41): [True: 96, False: 76.3k]
  ------------------
  782|     99|            PLIST_BIN_ERR("%s: BPLIST_DATA data bytes point outside of valid range\n", __func__);
  ------------------
  |  |  246|     99|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 99]
  |  |  ------------------
  ------------------
  783|     99|            return NULL;
  784|     99|        }
  785|  76.3k|        return parse_data_node(object, size);
  786|       |
  787|  43.7k|    case BPLIST_STRING:
  ------------------
  |  Branch (787:5): [True: 43.7k, False: 132k]
  ------------------
  788|  43.7k|        if (pobject + size < pobject || pobject + size > poffset_table) {
  ------------------
  |  Branch (788:13): [True: 1, False: 43.7k]
  |  Branch (788:41): [True: 100, False: 43.6k]
  ------------------
  789|    101|            PLIST_BIN_ERR("%s: BPLIST_STRING data bytes point outside of valid range\n", __func__);
  ------------------
  |  |  246|    101|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 101]
  |  |  ------------------
  ------------------
  790|    101|            return NULL;
  791|    101|        }
  792|  43.6k|        return parse_string_node(object, size);
  793|       |
  794|  19.9k|    case BPLIST_UNICODE:
  ------------------
  |  Branch (794:5): [True: 19.9k, False: 155k]
  ------------------
  795|  19.9k|        if (size*2 < size) {
  ------------------
  |  Branch (795:13): [True: 68, False: 19.9k]
  ------------------
  796|     68|            PLIST_BIN_ERR("%s: Integer overflow when calculating BPLIST_UNICODE data size.\n", __func__);
  ------------------
  |  |  246|     68|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 68]
  |  |  ------------------
  ------------------
  797|     68|            return NULL;
  798|     68|        }
  799|  19.9k|        if (pobject + size*2 < pobject || pobject + size*2 > poffset_table) {
  ------------------
  |  Branch (799:13): [True: 1, False: 19.9k]
  |  Branch (799:43): [True: 127, False: 19.8k]
  ------------------
  800|    128|            PLIST_BIN_ERR("%s: BPLIST_UNICODE data bytes point outside of valid range\n", __func__);
  ------------------
  |  |  246|    128|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 128]
  |  |  ------------------
  ------------------
  801|    128|            return NULL;
  802|    128|        }
  803|  19.8k|        return parse_unicode_node(object, size);
  804|       |
  805|  4.06k|    case BPLIST_SET:
  ------------------
  |  Branch (805:5): [True: 4.06k, False: 171k]
  ------------------
  806|  13.0k|    case BPLIST_ARRAY:
  ------------------
  |  Branch (806:5): [True: 8.98k, False: 166k]
  ------------------
  807|  13.0k|        if (pobject + size < pobject || pobject + size > poffset_table) {
  ------------------
  |  Branch (807:13): [True: 0, False: 13.0k]
  |  Branch (807:41): [True: 100, False: 12.9k]
  ------------------
  808|    100|            PLIST_BIN_ERR("%s: BPLIST_ARRAY data bytes point outside of valid range\n", __func__);
  ------------------
  |  |  246|    100|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 100]
  |  |  ------------------
  ------------------
  809|    100|            return NULL;
  810|    100|        }
  811|  12.9k|        return parse_array_node(bplist, object, size);
  812|       |
  813|  4.26k|    case BPLIST_UID:
  ------------------
  |  Branch (813:5): [True: 4.26k, False: 171k]
  ------------------
  814|  4.26k|        if (pobject + size+1 > poffset_table) {
  ------------------
  |  Branch (814:13): [True: 7, False: 4.26k]
  ------------------
  815|      7|            PLIST_BIN_ERR("%s: BPLIST_UID data bytes point outside of valid range\n", __func__);
  ------------------
  |  |  246|      7|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 7]
  |  |  ------------------
  ------------------
  816|      7|            return NULL;
  817|      7|        }
  818|  4.26k|        return parse_uid_node(object, size);
  819|       |
  820|  4.57k|    case BPLIST_DICT:
  ------------------
  |  Branch (820:5): [True: 4.57k, False: 171k]
  ------------------
  821|  4.57k|        if (pobject + size < pobject || pobject + size > poffset_table) {
  ------------------
  |  Branch (821:13): [True: 1, False: 4.57k]
  |  Branch (821:41): [True: 100, False: 4.47k]
  ------------------
  822|    101|            PLIST_BIN_ERR("%s: BPLIST_DICT data bytes point outside of valid range\n", __func__);
  ------------------
  |  |  246|    101|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 101]
  |  |  ------------------
  ------------------
  823|    101|            return NULL;
  824|    101|        }
  825|  4.47k|        return parse_dict_node(bplist, object, size);
  826|       |
  827|      5|    default:
  ------------------
  |  Branch (827:5): [True: 5, False: 175k]
  ------------------
  828|      5|        PLIST_BIN_ERR("%s: unexpected node type 0x%02x\n", __func__, type);
  ------------------
  |  |  246|      5|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 5]
  |  |  ------------------
  ------------------
  829|      5|        return NULL;
  830|   175k|    }
  831|      0|    return NULL;
  832|   175k|}
bplist.c:parse_int_node:
  279|  4.94k|{
  280|  4.94k|    plist_data_t data = plist_new_plist_data();
  281|  4.94k|    if (!data) {
  ------------------
  |  Branch (281:9): [True: 0, False: 4.94k]
  ------------------
  282|      0|        PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  283|      0|        return NULL;
  284|      0|    }
  285|       |
  286|  4.94k|    size = 1 << size;			// make length less misleading
  287|  4.94k|    switch (size)
  288|  4.94k|    {
  289|  1.45k|    case sizeof(uint8_t):
  ------------------
  |  Branch (289:5): [True: 1.45k, False: 3.49k]
  ------------------
  290|  2.18k|    case sizeof(uint16_t):
  ------------------
  |  Branch (290:5): [True: 730, False: 4.21k]
  ------------------
  291|  3.04k|    case sizeof(uint32_t):
  ------------------
  |  Branch (291:5): [True: 865, False: 4.08k]
  ------------------
  292|  4.16k|    case sizeof(uint64_t):
  ------------------
  |  Branch (292:5): [True: 1.11k, False: 3.83k]
  ------------------
  293|  4.16k|        data->length = sizeof(uint64_t);
  294|  4.16k|        break;
  295|    782|    case 16:
  ------------------
  |  Branch (295:5): [True: 782, False: 4.16k]
  ------------------
  296|    782|        data->length = size;
  297|    782|        break;
  298|      1|    default:
  ------------------
  |  Branch (298:5): [True: 1, False: 4.94k]
  ------------------
  299|      1|        free(data);
  300|      1|        PLIST_BIN_ERR("%s: Invalid byte size for integer node\n", __func__);
  ------------------
  |  |  246|      1|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 1]
  |  |  ------------------
  ------------------
  301|      1|        return NULL;
  302|  4.94k|    };
  303|       |
  304|  4.94k|    data->intval = UINT_TO_HOST(*bnode, size);
  ------------------
  |  |  187|  4.94k|	({ \
  |  |  188|  4.94k|		union plist_uint_ptr __up; \
  |  |  189|  4.94k|		__up.src = ((n) > 8) ? (const char*)(x) + ((n) - 8) : (const char*)(x); \
  |  |  ------------------
  |  |  |  Branch (189:14): [True: 782, False: 4.16k]
  |  |  ------------------
  |  |  190|  4.94k|		((n) >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (190:4): [True: 1.89k, False: 3.04k]
  |  |  ------------------
  |  |  191|  4.94k|		((n) == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (191:4): [True: 865, False: 2.18k]
  |  |  ------------------
  |  |  192|  3.04k|		((n) == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (192:4): [True: 730, False: 1.45k]
  |  |  ------------------
  |  |  193|  2.18k|		((n) == 1 ? *__up.u8ptr : \
  |  |  ------------------
  |  |  |  Branch (193:4): [True: 1.45k, False: 0]
  |  |  ------------------
  |  |  194|  1.45k|		beNtoh( get_unaligned(__up.u64ptr), n) \
  |  |  ------------------
  |  |  |  |  170|  1.45k|#define beNtoh(x,n) be64toh((x) << ((8-(n)) << 3))
  |  |  ------------------
  |  |  195|  1.45k|		)))); \
  |  |  196|  4.94k|	})
  ------------------
  305|       |
  306|  4.94k|    (*bnode) += size;
  307|  4.94k|    data->type = PLIST_INT;
  308|       |
  309|       |    return node_create(NULL, data);
  310|  4.94k|}
bplist.c:parse_real_node:
  313|  1.54k|{
  314|  1.54k|    plist_data_t data = plist_new_plist_data();
  315|  1.54k|    if (!data) {
  ------------------
  |  Branch (315:9): [True: 0, False: 1.54k]
  ------------------
  316|      0|        PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  317|      0|        return NULL;
  318|      0|    }
  319|       |
  320|  1.54k|    size = 1 << size;			// make length less misleading
  321|  1.54k|    switch (size)
  322|  1.54k|    {
  323|    278|    case sizeof(uint32_t):
  ------------------
  |  Branch (323:5): [True: 278, False: 1.26k]
  ------------------
  324|    278|    {
  325|    278|        uint32_t ival;
  326|    278|        memcpy(&ival, *bnode, sizeof(uint32_t));
  327|    278|        ival = float_bswap32(ival);
  ------------------
  |  |  213|    278|#define float_bswap32(x) bswap32(x)
  |  |  ------------------
  |  |  |  |  126|    278|#define bswap32(x)   ((((x) & 0xFF000000) >> 24) \
  |  |  |  |  127|    278|                    | (((x) & 0x00FF0000) >>  8) \
  |  |  |  |  128|    278|                    | (((x) & 0x0000FF00) <<  8) \
  |  |  |  |  129|    278|                    | (((x) & 0x000000FF) << 24))
  |  |  ------------------
  ------------------
  328|    278|        float fval;
  329|    278|        memcpy(&fval, &ival, sizeof(float));
  330|    278|        data->realval = fval;
  331|    278|    }
  332|    278|    break;
  333|       |
  334|  1.26k|    case sizeof(uint64_t):
  ------------------
  |  Branch (334:5): [True: 1.26k, False: 280]
  ------------------
  335|  1.26k|    {
  336|  1.26k|        uint64_t ival;
  337|  1.26k|        memcpy(&ival, *bnode, sizeof(uint64_t));
  338|  1.26k|        ival = float_bswap64(ival);
  ------------------
  |  |  212|  1.26k|#define float_bswap64(x) bswap64(x)
  |  |  ------------------
  |  |  |  |  133|  1.26k|#define bswap64(x)   ((((x) & 0xFF00000000000000ull) >> 56) \
  |  |  |  |  134|  1.26k|                    | (((x) & 0x00FF000000000000ull) >> 40) \
  |  |  |  |  135|  1.26k|                    | (((x) & 0x0000FF0000000000ull) >> 24) \
  |  |  |  |  136|  1.26k|                    | (((x) & 0x000000FF00000000ull) >>  8) \
  |  |  |  |  137|  1.26k|                    | (((x) & 0x00000000FF000000ull) <<  8) \
  |  |  |  |  138|  1.26k|                    | (((x) & 0x0000000000FF0000ull) << 24) \
  |  |  |  |  139|  1.26k|                    | (((x) & 0x000000000000FF00ull) << 40) \
  |  |  |  |  140|  1.26k|                    | (((x) & 0x00000000000000FFull) << 56))
  |  |  ------------------
  ------------------
  339|  1.26k|        memcpy(&data->realval, &ival, sizeof(double));
  340|  1.26k|        break;
  341|      0|    }
  342|       |
  343|      2|    default:
  ------------------
  |  Branch (343:5): [True: 2, False: 1.53k]
  ------------------
  344|      2|        free(data);
  345|      2|        PLIST_BIN_ERR("%s: Invalid byte size for real node\n", __func__);
  ------------------
  |  |  246|      2|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 2]
  |  |  ------------------
  ------------------
  346|      2|        return NULL;
  347|  1.54k|    }
  348|  1.53k|    data->type = PLIST_REAL;
  349|  1.53k|    data->length = sizeof(double);
  350|       |
  351|       |    return node_create(NULL, data);
  352|  1.54k|}
bplist.c:parse_date_node:
  355|  1.06k|{
  356|  1.06k|    plist_t node = parse_real_node(bnode, size);
  357|  1.06k|    plist_data_t data = plist_get_data(node);
  358|       |
  359|  1.06k|    data->type = PLIST_DATE;
  360|       |
  361|  1.06k|    return node;
  362|  1.06k|}
bplist.c:parse_data_node:
  479|  76.3k|{
  480|  76.3k|    plist_data_t data = plist_new_plist_data();
  481|  76.3k|    if (!data) {
  ------------------
  |  Branch (481:9): [True: 0, False: 76.3k]
  ------------------
  482|      0|        PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  483|      0|        return NULL;
  484|      0|    }
  485|  76.3k|    data->type = PLIST_DATA;
  486|  76.3k|    data->length = size;
  487|  76.3k|    data->buff = (uint8_t *) malloc(sizeof(uint8_t) * size);
  488|  76.3k|    if (!data->buff) {
  ------------------
  |  Branch (488:9): [True: 0, False: 76.3k]
  ------------------
  489|      0|        plist_free_data(data);
  490|      0|        PLIST_BIN_ERR("%s: Could not allocate %" PRIu64 " bytes\n", __func__, sizeof(uint8_t) * size);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  491|      0|        return NULL;
  492|      0|    }
  493|  76.3k|    memcpy(data->buff, *bnode, sizeof(uint8_t) * size);
  494|       |
  495|       |    return node_create(NULL, data);
  496|  76.3k|}
bplist.c:parse_string_node:
  365|  43.6k|{
  366|  43.6k|    plist_data_t data = plist_new_plist_data();
  367|  43.6k|    if (!data) {
  ------------------
  |  Branch (367:9): [True: 0, False: 43.6k]
  ------------------
  368|      0|        PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  369|      0|        return NULL;
  370|      0|    }
  371|       |
  372|  43.6k|    data->type = PLIST_STRING;
  373|  43.6k|    data->strval = (char *) malloc(sizeof(char) * (size + 1));
  374|  43.6k|    if (!data->strval) {
  ------------------
  |  Branch (374:9): [True: 0, False: 43.6k]
  ------------------
  375|      0|        plist_free_data(data);
  376|      0|        PLIST_BIN_ERR("%s: Could not allocate %" PRIu64 " bytes\n", __func__, sizeof(char) * (size + 1));
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  377|      0|        return NULL;
  378|      0|    }
  379|  43.6k|    memcpy(data->strval, *bnode, size);
  380|  43.6k|    data->strval[size] = '\0';
  381|  43.6k|    data->length = strlen(data->strval);
  382|       |
  383|       |    return node_create(NULL, data);
  384|  43.6k|}
bplist.c:parse_unicode_node:
  458|  19.8k|{
  459|  19.8k|    plist_data_t data = plist_new_plist_data();
  460|  19.8k|    if (!data) {
  ------------------
  |  Branch (460:9): [True: 0, False: 19.8k]
  ------------------
  461|      0|        PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  462|      0|        return NULL;
  463|      0|    }
  464|  19.8k|    size_t items_read = 0;
  465|  19.8k|    size_t items_written = 0;
  466|       |
  467|  19.8k|    data->type = PLIST_STRING;
  468|  19.8k|    data->strval = plist_utf16be_to_utf8((uint16_t*)(*bnode), size, &items_read, &items_written);
  469|  19.8k|    if (!data->strval) {
  ------------------
  |  Branch (469:9): [True: 2, False: 19.8k]
  ------------------
  470|      2|        plist_free_data(data);
  471|      2|        return NULL;
  472|      2|    }
  473|  19.8k|    data->length = items_written;
  474|       |
  475|       |    return node_create(NULL, data);
  476|  19.8k|}
bplist.c:plist_utf16be_to_utf8:
  387|  19.8k|{
  388|  19.8k|	if (!unistr || (len <= 0)) return NULL;
  ------------------
  |  Branch (388:6): [True: 0, False: 19.8k]
  |  Branch (388:17): [True: 2, False: 19.8k]
  ------------------
  389|  19.8k|	char* outbuf;
  390|  19.8k|	char* outbuf_new;
  391|  19.8k|	size_t p = 0;
  392|  19.8k|	size_t i = 0;
  393|       |
  394|  19.8k|	uint16_t wc;
  395|  19.8k|	uint32_t w;
  396|  19.8k|	int read_lead_surrogate = 0;
  397|       |
  398|       |	/* allocate with enough space */
  399|  19.8k|	outbuf = (char*)malloc(4*(len+1));
  400|  19.8k|	if (!outbuf) {
  ------------------
  |  Branch (400:6): [True: 0, False: 19.8k]
  ------------------
  401|      0|		PLIST_BIN_ERR("%s: Could not allocate %" PRIu64 " bytes\n", __func__, (uint64_t)(4*(len+1)));
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  402|      0|		return NULL;
  403|      0|	}
  404|       |
  405|   100k|	while (i < len) {
  ------------------
  |  Branch (405:9): [True: 80.9k, False: 19.8k]
  ------------------
  406|  80.9k|		wc = UINT_TO_HOST(unistr + i, sizeof(wc));
  ------------------
  |  |  187|  80.9k|	({ \
  |  |  188|  80.9k|		union plist_uint_ptr __up; \
  |  |  189|  80.9k|		__up.src = ((n) > 8) ? (const char*)(x) + ((n) - 8) : (const char*)(x); \
  |  |  ------------------
  |  |  |  Branch (189:14): [Folded, False: 80.9k]
  |  |  ------------------
  |  |  190|  80.9k|		((n) >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (190:4): [Folded, False: 80.9k]
  |  |  ------------------
  |  |  191|  80.9k|		((n) == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (191:4): [Folded, False: 80.9k]
  |  |  ------------------
  |  |  192|  80.9k|		((n) == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (192:4): [True: 80.9k, Folded]
  |  |  ------------------
  |  |  193|  80.9k|		((n) == 1 ? *__up.u8ptr : \
  |  |  ------------------
  |  |  |  Branch (193:4): [Folded, False: 0]
  |  |  ------------------
  |  |  194|      0|		beNtoh( get_unaligned(__up.u64ptr), n) \
  |  |  ------------------
  |  |  |  |  170|      0|#define beNtoh(x,n) be64toh((x) << ((8-(n)) << 3))
  |  |  ------------------
  |  |  195|      0|		)))); \
  |  |  196|  80.9k|	})
  ------------------
  407|  80.9k|		i++;
  408|  80.9k|		if (wc >= 0xD800 && wc <= 0xDBFF) {
  ------------------
  |  Branch (408:7): [True: 11.8k, False: 69.0k]
  |  Branch (408:23): [True: 2.12k, False: 9.71k]
  ------------------
  409|  2.12k|			if (!read_lead_surrogate) {
  ------------------
  |  Branch (409:8): [True: 1.60k, False: 526]
  ------------------
  410|  1.60k|				read_lead_surrogate = 1;
  411|  1.60k|				w = 0x010000 + ((wc & 0x3FF) << 10);
  412|  1.60k|			} else {
  413|       |				// This is invalid, the next 16 bit char should be a trail surrogate.
  414|       |				// Handling error by skipping.
  415|    526|				read_lead_surrogate = 0;
  416|    526|			}
  417|  78.7k|		} else if (wc >= 0xDC00 && wc <= 0xDFFF) {
  ------------------
  |  Branch (417:14): [True: 9.71k, False: 69.0k]
  |  Branch (417:30): [True: 6.83k, False: 2.87k]
  ------------------
  418|  6.83k|			if (read_lead_surrogate) {
  ------------------
  |  Branch (418:8): [True: 822, False: 6.01k]
  ------------------
  419|    822|				read_lead_surrogate = 0;
  420|    822|				w = w | (wc & 0x3FF);
  421|    822|				outbuf[p++] = (char)(0xF0 + ((w >> 18) & 0x7));
  422|    822|				outbuf[p++] = (char)(0x80 + ((w >> 12) & 0x3F));
  423|    822|				outbuf[p++] = (char)(0x80 + ((w >> 6) & 0x3F));
  424|    822|				outbuf[p++] = (char)(0x80 + (w & 0x3F));
  425|  6.01k|			} else {
  426|       |				// This is invalid.  A trail surrogate should always follow a lead surrogate.
  427|       |				// Handling error by skipping
  428|  6.01k|			}
  429|  71.9k|		} else if (wc >= 0x800) {
  ------------------
  |  Branch (429:14): [True: 54.4k, False: 17.4k]
  ------------------
  430|  54.4k|			outbuf[p++] = (char)(0xE0 + ((wc >> 12) & 0xF));
  431|  54.4k|			outbuf[p++] = (char)(0x80 + ((wc >> 6) & 0x3F));
  432|  54.4k|			outbuf[p++] = (char)(0x80 + (wc & 0x3F));
  433|  54.4k|		} else if (wc >= 0x80) {
  ------------------
  |  Branch (433:14): [True: 9.16k, False: 8.32k]
  ------------------
  434|  9.16k|			outbuf[p++] = (char)(0xC0 + ((wc >> 6) & 0x1F));
  435|  9.16k|			outbuf[p++] = (char)(0x80 + (wc & 0x3F));
  436|  9.16k|		} else {
  437|  8.32k|			outbuf[p++] = (char)(wc & 0x7F);
  438|  8.32k|		}
  439|  80.9k|	}
  440|  19.8k|	if (items_read) {
  ------------------
  |  Branch (440:6): [True: 19.8k, False: 0]
  ------------------
  441|  19.8k|		*items_read = i;
  442|  19.8k|	}
  443|  19.8k|	if (items_written) {
  ------------------
  |  Branch (443:6): [True: 19.8k, False: 0]
  ------------------
  444|  19.8k|		*items_written = p;
  445|  19.8k|	}
  446|  19.8k|	outbuf[p] = 0;
  447|       |
  448|       |	/* reduce the size to the actual size */
  449|  19.8k|	outbuf_new = (char*)realloc(outbuf, p+1);
  450|  19.8k|	if (outbuf_new) {
  ------------------
  |  Branch (450:6): [True: 19.8k, False: 0]
  ------------------
  451|  19.8k|		outbuf = outbuf_new;
  452|  19.8k|	}
  453|       |
  454|  19.8k|	return outbuf;
  455|  19.8k|}
bplist.c:parse_array_node:
  587|  12.9k|{
  588|  12.9k|    uint64_t j;
  589|  12.9k|    uint64_t str_j = 0;
  590|  12.9k|    uint64_t index1;
  591|  12.9k|    plist_data_t data = plist_new_plist_data();
  592|  12.9k|    if (!data) {
  ------------------
  |  Branch (592:9): [True: 0, False: 12.9k]
  ------------------
  593|      0|        PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  594|      0|        return NULL;
  595|      0|    }
  596|  12.9k|    const char *index1_ptr = NULL;
  597|       |
  598|  12.9k|    data->type = PLIST_ARRAY;
  599|  12.9k|    data->length = size;
  600|       |
  601|  12.9k|    plist_t node = node_create(NULL, data);
  602|  12.9k|    if (!node) {
  ------------------
  |  Branch (602:9): [True: 0, False: 12.9k]
  ------------------
  603|      0|        plist_free_data(data);
  604|      0|        PLIST_BIN_ERR("%s: failed to create node\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  605|      0|        return NULL;
  606|      0|    }
  607|       |
  608|   129k|    for (j = 0; j < data->length; j++) {
  ------------------
  |  Branch (608:17): [True: 117k, False: 11.8k]
  ------------------
  609|   117k|        str_j = j * bplist->ref_size;
  610|   117k|        index1_ptr = (*bnode) + str_j;
  611|       |
  612|   117k|        if (index1_ptr < bplist->data || index1_ptr + bplist->ref_size > bplist->offset_table) {
  ------------------
  |  Branch (612:13): [True: 0, False: 117k]
  |  Branch (612:42): [True: 4, False: 117k]
  ------------------
  613|      4|            plist_free(node);
  614|      4|            PLIST_BIN_ERR("%s: array item %" PRIu64 " is outside of valid range\n", __func__, j);
  ------------------
  |  |  246|      4|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 4]
  |  |  ------------------
  ------------------
  615|      4|            return NULL;
  616|      4|        }
  617|       |
  618|   117k|        index1 = UINT_TO_HOST(index1_ptr, bplist->ref_size);
  ------------------
  |  |  187|   117k|	({ \
  |  |  188|   117k|		union plist_uint_ptr __up; \
  |  |  189|   117k|		__up.src = ((n) > 8) ? (const char*)(x) + ((n) - 8) : (const char*)(x); \
  |  |  ------------------
  |  |  |  Branch (189:14): [True: 251, False: 117k]
  |  |  ------------------
  |  |  190|   117k|		((n) >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (190:4): [True: 272, False: 117k]
  |  |  ------------------
  |  |  191|   117k|		((n) == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (191:4): [True: 267, False: 116k]
  |  |  ------------------
  |  |  192|   117k|		((n) == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (192:4): [True: 265, False: 116k]
  |  |  ------------------
  |  |  193|   116k|		((n) == 1 ? *__up.u8ptr : \
  |  |  ------------------
  |  |  |  Branch (193:4): [True: 116k, False: 325]
  |  |  ------------------
  |  |  194|   116k|		beNtoh( get_unaligned(__up.u64ptr), n) \
  |  |  ------------------
  |  |  |  |  170|   116k|#define beNtoh(x,n) be64toh((x) << ((8-(n)) << 3))
  |  |  ------------------
  |  |  195|   116k|		)))); \
  |  |  196|   117k|	})
  ------------------
  619|       |
  620|   117k|        if (index1 >= bplist->num_objects) {
  ------------------
  |  Branch (620:13): [True: 197, False: 117k]
  ------------------
  621|    197|            plist_free(node);
  622|    197|            PLIST_BIN_ERR("%s: array item %" PRIu64 " object index (%" PRIu64 ") must be smaller than the number of objects (%" PRIu64 ")\n", __func__, j, index1, bplist->num_objects);
  ------------------
  |  |  246|    197|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 197]
  |  |  ------------------
  ------------------
  623|    197|            return NULL;
  624|    197|        }
  625|       |
  626|       |        /* process value node */
  627|   117k|        plist_t val = parse_bin_node_at_index(bplist, index1);
  628|   117k|        if (!val) {
  ------------------
  |  Branch (628:13): [True: 941, False: 116k]
  ------------------
  629|    941|            plist_free(node);
  630|    941|            return NULL;
  631|    941|        }
  632|       |
  633|   116k|        node_attach((node_t)node, (node_t)val);
  634|   116k|    }
  635|       |
  636|  11.8k|    return node;
  637|  12.9k|}
bplist.c:parse_uid_node:
  640|  4.26k|{
  641|  4.26k|    plist_data_t data = plist_new_plist_data();
  642|  4.26k|    if (!data) {
  ------------------
  |  Branch (642:9): [True: 0, False: 4.26k]
  ------------------
  643|      0|        PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  644|      0|        return NULL;
  645|      0|    }
  646|  4.26k|    size = size + 1;
  647|  4.26k|    data->intval = UINT_TO_HOST(*bnode, size);
  ------------------
  |  |  187|  4.26k|	({ \
  |  |  188|  4.26k|		union plist_uint_ptr __up; \
  |  |  189|  4.26k|		__up.src = ((n) > 8) ? (const char*)(x) + ((n) - 8) : (const char*)(x); \
  |  |  ------------------
  |  |  |  Branch (189:14): [True: 1.35k, False: 2.90k]
  |  |  ------------------
  |  |  190|  4.26k|		((n) >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (190:4): [True: 1.39k, False: 2.86k]
  |  |  ------------------
  |  |  191|  4.26k|		((n) == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (191:4): [True: 228, False: 2.64k]
  |  |  ------------------
  |  |  192|  2.86k|		((n) == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (192:4): [True: 204, False: 2.43k]
  |  |  ------------------
  |  |  193|  2.64k|		((n) == 1 ? *__up.u8ptr : \
  |  |  ------------------
  |  |  |  Branch (193:4): [True: 366, False: 2.07k]
  |  |  ------------------
  |  |  194|  2.43k|		beNtoh( get_unaligned(__up.u64ptr), n) \
  |  |  ------------------
  |  |  |  |  170|  2.43k|#define beNtoh(x,n) be64toh((x) << ((8-(n)) << 3))
  |  |  ------------------
  |  |  195|  2.43k|		)))); \
  |  |  196|  4.26k|	})
  ------------------
  648|  4.26k|    if (data->intval > UINT32_MAX) {
  ------------------
  |  Branch (648:9): [True: 60, False: 4.20k]
  ------------------
  649|     60|        PLIST_BIN_ERR("%s: value %" PRIu64 " too large for UID node (must be <= %u)\n", __func__, (uint64_t)data->intval, UINT32_MAX);
  ------------------
  |  |  246|     60|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 60]
  |  |  ------------------
  ------------------
  650|     60|        free(data);
  651|     60|        return NULL;
  652|     60|    }
  653|       |
  654|  4.20k|    (*bnode) += size;
  655|  4.20k|    data->type = PLIST_UID;
  656|  4.20k|    data->length = sizeof(uint64_t);
  657|       |
  658|       |    return node_create(NULL, data);
  659|  4.26k|}
bplist.c:parse_dict_node:
  499|  4.47k|{
  500|  4.47k|    uint64_t j;
  501|  4.47k|    uint64_t str_i = 0, str_j = 0;
  502|  4.47k|    uint64_t index1, index2;
  503|  4.47k|    plist_data_t data = plist_new_plist_data();
  504|  4.47k|    if (!data) {
  ------------------
  |  Branch (504:9): [True: 0, False: 4.47k]
  ------------------
  505|      0|        PLIST_BIN_ERR("%s: failed to allocate plist data\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  506|      0|        return NULL;
  507|      0|    }
  508|  4.47k|    const char *index1_ptr = NULL;
  509|  4.47k|    const char *index2_ptr = NULL;
  510|       |
  511|  4.47k|    data->type = PLIST_DICT;
  512|  4.47k|    data->length = size;
  513|       |
  514|  4.47k|    plist_t node = node_create(NULL, data);
  515|  4.47k|    if (!node) {
  ------------------
  |  Branch (515:9): [True: 0, False: 4.47k]
  ------------------
  516|      0|        plist_free_data(data);
  517|      0|        PLIST_BIN_ERR("%s: failed to create node\n", __func__);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  518|      0|        return NULL;
  519|      0|    }
  520|       |
  521|  32.5k|    for (j = 0; j < data->length; j++) {
  ------------------
  |  Branch (521:17): [True: 29.1k, False: 3.40k]
  ------------------
  522|  29.1k|        str_i = j * bplist->ref_size;
  523|  29.1k|        str_j = (j + size) * bplist->ref_size;
  524|  29.1k|        index1_ptr = (*bnode) + str_i;
  525|  29.1k|        index2_ptr = (*bnode) + str_j;
  526|       |
  527|  29.1k|        if ((index1_ptr < bplist->data || index1_ptr + bplist->ref_size > bplist->offset_table) ||
  ------------------
  |  Branch (527:14): [True: 0, False: 29.1k]
  |  Branch (527:43): [True: 4, False: 29.1k]
  ------------------
  528|  29.1k|            (index2_ptr < bplist->data || index2_ptr + bplist->ref_size > bplist->offset_table)) {
  ------------------
  |  Branch (528:14): [True: 0, False: 29.1k]
  |  Branch (528:43): [True: 19, False: 29.1k]
  ------------------
  529|     23|            plist_free(node);
  530|     23|            PLIST_BIN_ERR("%s: dict entry %" PRIu64 " is outside of valid range\n", __func__, j);
  ------------------
  |  |  246|     23|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 23]
  |  |  ------------------
  ------------------
  531|     23|            return NULL;
  532|     23|        }
  533|       |
  534|  29.1k|        index1 = UINT_TO_HOST(index1_ptr, bplist->ref_size);
  ------------------
  |  |  187|  29.1k|	({ \
  |  |  188|  29.1k|		union plist_uint_ptr __up; \
  |  |  189|  29.1k|		__up.src = ((n) > 8) ? (const char*)(x) + ((n) - 8) : (const char*)(x); \
  |  |  ------------------
  |  |  |  Branch (189:14): [True: 255, False: 28.8k]
  |  |  ------------------
  |  |  190|  29.1k|		((n) >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (190:4): [True: 289, False: 28.8k]
  |  |  ------------------
  |  |  191|  29.1k|		((n) == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (191:4): [True: 224, False: 28.6k]
  |  |  ------------------
  |  |  192|  28.8k|		((n) == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (192:4): [True: 238, False: 28.3k]
  |  |  ------------------
  |  |  193|  28.6k|		((n) == 1 ? *__up.u8ptr : \
  |  |  ------------------
  |  |  |  Branch (193:4): [True: 28.0k, False: 313]
  |  |  ------------------
  |  |  194|  28.3k|		beNtoh( get_unaligned(__up.u64ptr), n) \
  |  |  ------------------
  |  |  |  |  170|  28.3k|#define beNtoh(x,n) be64toh((x) << ((8-(n)) << 3))
  |  |  ------------------
  |  |  195|  28.3k|		)))); \
  |  |  196|  29.1k|	})
  ------------------
  535|  29.1k|        index2 = UINT_TO_HOST(index2_ptr, bplist->ref_size);
  ------------------
  |  |  187|  29.1k|	({ \
  |  |  188|  29.1k|		union plist_uint_ptr __up; \
  |  |  189|  29.1k|		__up.src = ((n) > 8) ? (const char*)(x) + ((n) - 8) : (const char*)(x); \
  |  |  ------------------
  |  |  |  Branch (189:14): [True: 255, False: 28.8k]
  |  |  ------------------
  |  |  190|  29.1k|		((n) >= 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (190:4): [True: 289, False: 28.8k]
  |  |  ------------------
  |  |  191|  29.1k|		((n) == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (191:4): [True: 224, False: 28.6k]
  |  |  ------------------
  |  |  192|  28.8k|		((n) == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
  |  |  ------------------
  |  |  |  Branch (192:4): [True: 238, False: 28.3k]
  |  |  ------------------
  |  |  193|  28.6k|		((n) == 1 ? *__up.u8ptr : \
  |  |  ------------------
  |  |  |  Branch (193:4): [True: 28.0k, False: 313]
  |  |  ------------------
  |  |  194|  28.3k|		beNtoh( get_unaligned(__up.u64ptr), n) \
  |  |  ------------------
  |  |  |  |  170|  28.3k|#define beNtoh(x,n) be64toh((x) << ((8-(n)) << 3))
  |  |  ------------------
  |  |  195|  28.3k|		)))); \
  |  |  196|  29.1k|	})
  ------------------
  536|       |
  537|  29.1k|        if (index1 >= bplist->num_objects) {
  ------------------
  |  Branch (537:13): [True: 118, False: 29.0k]
  ------------------
  538|    118|            plist_free(node);
  539|    118|            PLIST_BIN_ERR("%s: dict entry %" PRIu64 ": key index (%" PRIu64 ") must be smaller than the number of objects (%" PRIu64 ")\n", __func__, j, index1, bplist->num_objects);
  ------------------
  |  |  246|    118|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 118]
  |  |  ------------------
  ------------------
  540|    118|            return NULL;
  541|    118|        }
  542|  29.0k|        if (index2 >= bplist->num_objects) {
  ------------------
  |  Branch (542:13): [True: 118, False: 28.9k]
  ------------------
  543|    118|            plist_free(node);
  544|    118|            PLIST_BIN_ERR("%s: dict entry %" PRIu64 ": value index (%" PRIu64 ") must be smaller than the number of objects (%" PRIu64 ")\n", __func__, j, index1, bplist->num_objects);
  ------------------
  |  |  246|    118|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 118]
  |  |  ------------------
  ------------------
  545|    118|            return NULL;
  546|    118|        }
  547|       |
  548|       |        /* process key node */
  549|  28.9k|        plist_t key = parse_bin_node_at_index(bplist, index1);
  550|  28.9k|        if (!key) {
  ------------------
  |  Branch (550:13): [True: 516, False: 28.3k]
  ------------------
  551|    516|            plist_free(node);
  552|    516|            return NULL;
  553|    516|        }
  554|       |
  555|  28.3k|        if (plist_get_data(key)->type != PLIST_STRING) {
  ------------------
  |  Branch (555:13): [True: 4, False: 28.3k]
  ------------------
  556|      4|            PLIST_BIN_ERR("%s: dict entry %" PRIu64 ": invalid node type for key\n", __func__, j);
  ------------------
  |  |  246|      4|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 4]
  |  |  ------------------
  ------------------
  557|      4|            plist_free(key);
  558|      4|            plist_free(node);
  559|      4|            return NULL;
  560|      4|        }
  561|       |
  562|       |        /* enforce key type */
  563|  28.3k|        plist_get_data(key)->type = PLIST_KEY;
  564|  28.3k|        if (!plist_get_data(key)->strval) {
  ------------------
  |  Branch (564:13): [True: 0, False: 28.3k]
  ------------------
  565|      0|            PLIST_BIN_ERR("%s: dict entry %" PRIu64 ": key must not be NULL\n", __func__, j);
  ------------------
  |  |  246|      0|#define PLIST_BIN_ERR(...) if (plist_bin_debug) { fprintf(stderr, "libplist[binparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (246:32): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  566|      0|            plist_free(key);
  567|      0|            plist_free(node);
  568|      0|            return NULL;
  569|      0|        }
  570|       |
  571|       |        /* process value node */
  572|  28.3k|        plist_t val = parse_bin_node_at_index(bplist, index2);
  573|  28.3k|        if (!val) {
  ------------------
  |  Branch (573:13): [True: 296, False: 28.0k]
  ------------------
  574|    296|            plist_free(key);
  575|    296|            plist_free(node);
  576|    296|            return NULL;
  577|    296|        }
  578|       |
  579|  28.0k|        node_attach((node_t)node, (node_t)key);
  580|  28.0k|        node_attach((node_t)node, (node_t)val);
  581|  28.0k|    }
  582|       |
  583|  3.40k|    return node;
  584|  4.47k|}

hash_table_destroy:
   38|  4.47k|{
   39|  4.47k|	if (!ht) return;
  ------------------
  |  Branch (39:6): [True: 4.47k, False: 0]
  ------------------
   40|       |
   41|      0|	int i = 0;
   42|      0|	for (i = 0; i < 4096; i++) {
  ------------------
  |  Branch (42:14): [True: 0, False: 0]
  ------------------
   43|      0|		if (ht->entries[i]) {
  ------------------
  |  Branch (43:7): [True: 0, False: 0]
  ------------------
   44|      0|			hashentry_t* e = ht->entries[i];
   45|      0|			while (e) {
  ------------------
  |  Branch (45:11): [True: 0, False: 0]
  ------------------
   46|      0|				if (ht->free_func) {
  ------------------
  |  Branch (46:9): [True: 0, False: 0]
  ------------------
   47|      0|					ht->free_func(e->value);
   48|      0|				}
   49|      0|				hashentry_t* old = e;
   50|      0|				e = e->next;
   51|      0|				free(old);
   52|      0|			}
   53|      0|		}
   54|      0|	}
   55|      0|	free(ht);
   56|      0|}

plist_json_init:
   57|      2|{
   58|       |    /* init JSON stuff */
   59|      2|#ifdef DEBUG
   60|      2|    char *env_debug = getenv("PLIST_JSON_DEBUG");
   61|      2|    if (env_debug && !strcmp(env_debug, "1")) {
  ------------------
  |  Branch (61:9): [True: 0, False: 2]
  |  Branch (61:22): [True: 0, False: 0]
  ------------------
   62|      0|        plist_json_debug = 1;
   63|      0|    }
   64|      2|#endif
   65|      2|}

plist_ostep_init:
   55|      2|{
   56|       |    /* init OpenStep stuff */
   57|      2|#ifdef DEBUG
   58|      2|    char *env_debug = getenv("PLIST_OSTEP_DEBUG");
   59|      2|    if (env_debug && !strcmp(env_debug, "1")) {
  ------------------
  |  Branch (59:9): [True: 0, False: 2]
  |  Branch (59:22): [True: 0, False: 0]
  ------------------
   60|      0|        plist_ostep_debug = 1;
   61|      0|    }
   62|      2|#endif
   63|      2|}

plist.c:internal_plist_init:
  153|      2|{
  154|      2|    plist_bin_init();
  155|      2|    plist_xml_init();
  156|      2|    plist_json_init();
  157|      2|    plist_ostep_init();
  158|      2|    atexit(internal_plist_deinit);
  159|      2|}
plist_get_data:
  353|   261k|{
  354|   261k|    if (!node)
  ------------------
  |  Branch (354:9): [True: 0, False: 261k]
  ------------------
  355|      0|        return NULL;
  356|   261k|    return (plist_data_t)((node_t)node)->data;
  357|   261k|}
plist_new_plist_data:
  360|   175k|{
  361|   175k|    return (plist_data_t) calloc(1, sizeof(struct plist_data_s));
  362|   175k|}
plist_free_data:
  421|   175k|{
  422|   175k|    if (!data) return;
  ------------------
  |  Branch (422:9): [True: 0, False: 175k]
  ------------------
  423|   175k|    _plist_free_data(data);
  424|   175k|    free(data);
  425|   175k|}
plist_free:
  713|  4.88k|{
  714|  4.88k|    if (plist)
  ------------------
  |  Branch (714:9): [True: 2.73k, False: 2.14k]
  ------------------
  715|  2.73k|    {
  716|  2.73k|        plist_free_node((node_t)plist);
  717|  2.73k|    }
  718|  4.88k|}
plist.c:_plist_free_data:
  390|   175k|{
  391|   175k|    if (!data) return;
  ------------------
  |  Branch (391:9): [True: 0, False: 175k]
  ------------------
  392|   175k|    switch (data->type) {
  393|  28.3k|        case PLIST_KEY:
  ------------------
  |  Branch (393:9): [True: 28.3k, False: 146k]
  ------------------
  394|  63.4k|        case PLIST_STRING:
  ------------------
  |  Branch (394:9): [True: 35.1k, False: 140k]
  ------------------
  395|  63.4k|            free(data->strval);
  396|  63.4k|            data->strval = NULL;
  397|  63.4k|            break;
  398|  76.3k|        case PLIST_DATA:
  ------------------
  |  Branch (398:9): [True: 76.3k, False: 98.8k]
  ------------------
  399|  76.3k|            free(data->buff);
  400|  76.3k|            data->buff = NULL;
  401|  76.3k|            break;
  402|  12.9k|        case PLIST_ARRAY:
  ------------------
  |  Branch (402:9): [True: 12.9k, False: 162k]
  ------------------
  403|  12.9k|            ptr_array_free((ptrarray_t*)data->hashtable);
  404|  12.9k|            data->hashtable = NULL;
  405|  12.9k|            break;
  406|  4.47k|        case PLIST_DICT: {
  ------------------
  |  Branch (406:9): [True: 4.47k, False: 170k]
  ------------------
  407|  4.47k|            hashtable_t *ht = (hashtable_t*)data->hashtable;
  408|       |            // PLIST_DICT hashtables must not own/free values; values are freed via node tree.
  409|  4.47k|            assert(!ht || ht->free_func == NULL);
  ------------------
  |  Branch (409:13): [True: 4.47k, False: 0]
  |  Branch (409:13): [True: 0, False: 0]
  |  Branch (409:13): [True: 4.47k, False: 0]
  |  Branch (409:13): [True: 0, False: 0]
  ------------------
  410|  4.47k|            if (ht) ht->free_func = NULL;
  ------------------
  |  Branch (410:17): [True: 0, False: 4.47k]
  ------------------
  411|  4.47k|            hash_table_destroy(ht);
  412|  4.47k|            data->hashtable = NULL;
  413|  4.47k|            break;
  414|  4.47k|        }
  415|  17.8k|        default:
  ------------------
  |  Branch (415:9): [True: 17.8k, False: 157k]
  ------------------
  416|  17.8k|            break;
  417|   175k|    }
  418|   175k|}
plist.c:plist_free_node:
  500|  2.73k|{
  501|  2.73k|    if (!root) return NODE_ERR_INVALID_ARG;
  ------------------
  |  |   37|      0|#define NODE_ERR_INVALID_ARG  -1
  ------------------
  |  Branch (501:9): [True: 0, False: 2.73k]
  ------------------
  502|       |
  503|  2.73k|    int root_index = -1;
  504|       |
  505|  2.73k|    if (root->parent) {
  ------------------
  |  Branch (505:9): [True: 0, False: 2.73k]
  ------------------
  506|      0|        root_index = node_detach(root->parent, root);
  507|      0|        if (root_index < 0) {
  ------------------
  |  Branch (507:13): [True: 0, False: 0]
  ------------------
  508|      0|            return root_index;
  509|      0|        }
  510|      0|    }
  511|       |
  512|  2.73k|    int r = plist_free_children(root);
  513|  2.73k|    if (r < 0) {
  ------------------
  |  Branch (513:9): [True: 0, False: 2.73k]
  ------------------
  514|       |        // root is already detached; caller should treat as error.
  515|      0|        return r;
  516|      0|    }
  517|       |
  518|  2.73k|    plist_data_t data = plist_get_data(root);
  519|  2.73k|    plist_free_data(data);
  520|  2.73k|    root->data = NULL;
  521|       |
  522|  2.73k|    node_destroy(root);
  523|       |
  524|  2.73k|    return root_index;
  525|  2.73k|}
plist.c:plist_free_children:
  428|  2.73k|{
  429|  2.73k|    if (!root) return NODE_ERR_INVALID_ARG;
  ------------------
  |  |   37|      0|#define NODE_ERR_INVALID_ARG  -1
  ------------------
  |  Branch (429:9): [True: 0, False: 2.73k]
  ------------------
  430|       |
  431|  2.73k|    if (!node_first_child(root)) {
  ------------------
  |  Branch (431:9): [True: 2.02k, False: 713]
  ------------------
  432|  2.02k|        return NODE_ERR_SUCCESS;
  ------------------
  |  |   36|  2.02k|#define NODE_ERR_SUCCESS       0
  ------------------
  433|  2.02k|    }
  434|       |
  435|    713|    size_t cap = 64, sp = 0;
  436|    713|    node_t *stack = (node_t*)malloc(cap * sizeof(*stack));
  437|    713|    if (!stack) return NODE_ERR_NO_MEM;
  ------------------
  |  |   38|      0|#define NODE_ERR_NO_MEM       -2
  ------------------
  |  Branch (437:9): [True: 0, False: 713]
  ------------------
  438|       |
  439|       |    // Push *direct* children onto the stack, detached from root.
  440|  13.5k|    for (;;) {
  441|  13.5k|        node_t ch = node_first_child(root);
  442|  13.5k|        if (!ch) break;
  ------------------
  |  Branch (442:13): [True: 713, False: 12.8k]
  ------------------
  443|       |
  444|  12.8k|        int di = node_detach(root, ch);
  445|  12.8k|        if (di < 0) {
  ------------------
  |  Branch (445:13): [True: 0, False: 12.8k]
  ------------------
  446|      0|            free(stack);
  447|      0|            return di;
  448|      0|        }
  449|       |
  450|  12.8k|        if (sp == cap) {
  ------------------
  |  Branch (450:13): [True: 130, False: 12.7k]
  ------------------
  451|    130|            cap += 64;
  452|    130|            node_t *tmp = (node_t*)realloc(stack, cap * sizeof(*stack));
  453|    130|            if (!tmp) {
  ------------------
  |  Branch (453:17): [True: 0, False: 130]
  ------------------
  454|      0|                free(stack);
  455|      0|                return NODE_ERR_NO_MEM;
  ------------------
  |  |   38|      0|#define NODE_ERR_NO_MEM       -2
  ------------------
  456|      0|            }
  457|    130|            stack = tmp;
  458|    130|        }
  459|  12.8k|        stack[sp++] = ch;
  460|  12.8k|    }
  461|       |
  462|       |    // Now free the detached subtree nodes (and their descendants).
  463|   332k|    while (sp) {
  ------------------
  |  Branch (463:12): [True: 332k, False: 713]
  ------------------
  464|   332k|        node_t node = stack[sp - 1];
  465|   332k|        node_t ch = node_first_child(node);
  466|   332k|        if (ch) {
  ------------------
  |  Branch (466:13): [True: 159k, False: 172k]
  ------------------
  467|   159k|            int di = node_detach(node, ch);
  468|   159k|            if (di < 0) {
  ------------------
  |  Branch (468:17): [True: 0, False: 159k]
  ------------------
  469|      0|                free(stack);
  470|      0|                return di;
  471|      0|            }
  472|       |
  473|   159k|            if (sp == cap) {
  ------------------
  |  Branch (473:17): [True: 6, False: 159k]
  ------------------
  474|      6|                cap += 64;
  475|      6|                node_t *tmp = (node_t*)realloc(stack, cap * sizeof(*stack));
  476|      6|                if (!tmp) {
  ------------------
  |  Branch (476:21): [True: 0, False: 6]
  ------------------
  477|      0|                    free(stack);
  478|      0|                    return NODE_ERR_NO_MEM;
  ------------------
  |  |   38|      0|#define NODE_ERR_NO_MEM       -2
  ------------------
  479|      0|                }
  480|      6|                stack = tmp;
  481|      6|            }
  482|   159k|            stack[sp++] = ch;
  483|   159k|            continue;
  484|   159k|        }
  485|       |
  486|   172k|        plist_data_t data = plist_get_data(node);
  487|   172k|        plist_free_data(data);
  488|   172k|        node->data = NULL;
  489|       |
  490|   172k|        node_destroy(node);
  491|       |
  492|   172k|        sp--;
  493|   172k|    }
  494|       |
  495|    713|    free(stack);
  496|    713|    return NODE_ERR_SUCCESS;
  ------------------
  |  |   36|    713|#define NODE_ERR_SUCCESS       0
  ------------------
  497|    713|}

ptr_array_new:
   25|  1.89k|{
   26|  1.89k|	ptrarray_t *pa = (ptrarray_t*)malloc(sizeof(ptrarray_t));
   27|  1.89k|	pa->pdata = (void**)malloc(sizeof(void*) * capacity);
   28|  1.89k|	pa->capacity = capacity;
   29|  1.89k|	pa->capacity_step = (capacity > 4096) ? 4096 : capacity;
  ------------------
  |  Branch (29:22): [True: 0, False: 1.89k]
  ------------------
   30|  1.89k|	pa->len = 0;
   31|  1.89k|	return pa;
   32|  1.89k|}
ptr_array_free:
   35|  14.8k|{
   36|  14.8k|	if (!pa) return;
  ------------------
  |  Branch (36:6): [True: 12.9k, False: 1.89k]
  ------------------
   37|  1.89k|	if (pa->pdata) {
  ------------------
  |  Branch (37:6): [True: 1.89k, False: 0]
  ------------------
   38|  1.89k|		free(pa->pdata);
   39|  1.89k|	}
   40|  1.89k|	free(pa);
   41|  1.89k|}
ptr_array_insert:
   44|  3.92k|{
   45|  3.92k|	if (!pa || !pa->pdata) return;
  ------------------
  |  Branch (45:6): [True: 0, False: 3.92k]
  |  Branch (45:13): [True: 0, False: 3.92k]
  ------------------
   46|  3.92k|	long remaining = pa->capacity-pa->len;
   47|  3.92k|	if (remaining == 0) {
  ------------------
  |  Branch (47:6): [True: 55, False: 3.87k]
  ------------------
   48|     55|		pa->pdata = (void**)realloc(pa->pdata, sizeof(void*) * (pa->capacity + pa->capacity_step));
   49|     55|		pa->capacity += pa->capacity_step;
   50|     55|	}
   51|  3.92k|	if (array_index < 0 || array_index >= pa->len) {
  ------------------
  |  Branch (51:6): [True: 3.92k, False: 0]
  |  Branch (51:25): [True: 0, False: 0]
  ------------------
   52|  3.92k|		pa->pdata[pa->len] = data;
   53|  3.92k|	} else {
   54|      0|		memmove(&pa->pdata[array_index+1], &pa->pdata[array_index], (pa->len-array_index) * sizeof(void*));
   55|      0|		pa->pdata[array_index] = data;
   56|      0|	}
   57|  3.92k|	pa->len++;
   58|  3.92k|}
ptr_array_add:
   61|  3.92k|{
   62|  3.92k|	ptr_array_insert(pa, data, -1);
   63|  3.92k|}
ptr_array_set:
   78|   172k|{
   79|   172k|	if (!pa || !pa->pdata || array_index < 0) return;
  ------------------
  |  Branch (79:6): [True: 0, False: 172k]
  |  Branch (79:13): [True: 0, False: 172k]
  |  Branch (79:27): [True: 0, False: 172k]
  ------------------
   80|   172k|	if (pa->len == 0 || array_index >= pa->len) return;
  ------------------
  |  Branch (80:6): [True: 0, False: 172k]
  |  Branch (80:22): [True: 0, False: 172k]
  ------------------
   81|   172k|	pa->pdata[array_index] = data;
   82|   172k|}
ptr_array_index:
   85|  2.34M|{
   86|  2.34M|	if (!pa) return NULL;
  ------------------
  |  Branch (86:6): [True: 0, False: 2.34M]
  ------------------
   87|  2.34M|	if (array_index < 0 || array_index >= pa->len) {
  ------------------
  |  Branch (87:6): [True: 0, False: 2.34M]
  |  Branch (87:25): [True: 0, False: 2.34M]
  ------------------
   88|      0|		return NULL;
   89|      0|	}
   90|  2.34M|	return pa->pdata[array_index];
   91|  2.34M|}
ptr_array_size:
   94|   184k|{
   95|   184k|	return pa->len;
   96|   184k|}

plist_xml_init:
   92|      2|{
   93|       |    /* init XML stuff */
   94|      2|#ifdef DEBUG
   95|      2|    char *env_debug = getenv("PLIST_XML_DEBUG");
   96|      2|    if (env_debug && !strcmp(env_debug, "1")) {
  ------------------
  |  Branch (96:9): [True: 0, False: 2]
  |  Branch (96:22): [True: 0, False: 0]
  ------------------
   97|      0|        plist_xml_debug = 1;
   98|      0|    }
   99|      2|#endif
  100|      2|}

