fuzz.c:_ZL9mock_initP11mg_tcpip_if:
    1|  5.02k|static bool mock_init(struct mg_tcpip_if *ifp) {
    2|  5.02k|  (void) ifp;
    3|  5.02k|  return true;
    4|  5.02k|}
fuzz.c:_ZL7mock_txPKvmP11mg_tcpip_if:
    6|  10.1k|static size_t mock_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
    7|  10.1k|  (void) buf, (void) len, (void) ifp;
    8|  10.1k|  return len;
    9|  10.1k|}
fuzz.c:_ZL7mock_rxPvmP11mg_tcpip_if:
   11|  5.02k|static size_t mock_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
   12|  5.02k|  (void) buf, (void) len, (void) ifp;
   13|  5.02k|  return 0;
   14|  5.02k|}
fuzz.c:_ZL7mock_upP11mg_tcpip_if:
   16|  5.02k|static bool mock_up(struct mg_tcpip_if *ifp) {
   17|  5.02k|  (void) ifp;
   18|  5.02k|  return true;
   19|  5.02k|}

LLVMFuzzerTestOneInput:
   24|  5.02k|int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   25|  5.02k|  mg_log_set(MG_LL_INFO);
  ------------------
  |  |  943|  5.02k|#define mg_log_set(level_) mg_log_level = (level_)
  ------------------
   26|       |
   27|  5.02k|  struct mg_dns_message dm;
   28|  5.02k|  mg_dns_parse(data, size, &dm);
   29|  5.02k|  mg_dns_parse(NULL, 0, &dm);
   30|       |
   31|  5.02k|  struct mg_http_message hm;
   32|  5.02k|  if (mg_http_parse((const char *) data, size, &hm) > 0) {
  ------------------
  |  Branch (32:7): [True: 2.31k, False: 2.71k]
  ------------------
   33|  2.31k|    mg_crc32(0, hm.method.buf, hm.method.len);
   34|  2.31k|    mg_crc32(0, hm.uri.buf, hm.uri.len);
   35|  2.31k|    mg_crc32(0, hm.uri.buf, hm.uri.len);
   36|  71.7k|    for (size_t i = 0; i < sizeof(hm.headers) / sizeof(hm.headers[0]); i++) {
  ------------------
  |  Branch (36:24): [True: 69.4k, False: 2.31k]
  ------------------
   37|  69.4k|      struct mg_str *k = &hm.headers[i].name, *v = &hm.headers[i].value;
   38|  69.4k|      mg_crc32(0, k->buf, k->len);
   39|  69.4k|      mg_crc32(0, v->buf, v->len);
   40|  69.4k|    }
   41|  2.31k|  }
   42|  5.02k|  mg_http_parse(NULL, 0, &hm);
   43|       |
   44|  5.02k|  struct mg_str body = mg_str_n((const char *) data, size);
   45|  5.02k|  char tmp[256];
   46|  5.02k|  mg_http_get_var(&body, "key", tmp, sizeof(tmp));
   47|  5.02k|  mg_http_get_var(&body, "key", NULL, 0);
   48|  5.02k|  mg_url_decode((char *) data, size, tmp, sizeof(tmp), 1);
   49|  5.02k|  mg_url_decode((char *) data, size, tmp, 1, 1);
   50|  5.02k|  mg_url_decode(NULL, 0, tmp, 1, 1);
   51|       |
   52|  5.02k|  struct mg_mqtt_message mm;
   53|  5.02k|  if (mg_mqtt_parse(data, size, 0, &mm) == MQTT_OK) {
  ------------------
  |  Branch (53:7): [True: 1.97k, False: 3.05k]
  ------------------
   54|  1.97k|    mg_crc32(0, mm.topic.buf, mm.topic.len);
   55|  1.97k|    mg_crc32(0, mm.data.buf, mm.data.len);
   56|  1.97k|    mg_crc32(0, mm.dgram.buf, mm.dgram.len);
   57|  1.97k|  }
   58|  5.02k|  mg_mqtt_parse(NULL, 0, 0, &mm);
   59|  5.02k|  if (mg_mqtt_parse(data, size, 5, &mm) == MQTT_OK) {
  ------------------
  |  Branch (59:7): [True: 1.96k, False: 3.06k]
  ------------------
   60|  1.96k|    mg_crc32(0, mm.topic.buf, mm.topic.len);
   61|  1.96k|    mg_crc32(0, mm.data.buf, mm.data.len);
   62|  1.96k|    mg_crc32(0, mm.dgram.buf, mm.dgram.len);
   63|  1.96k|  }
   64|  5.02k|  mg_mqtt_parse(NULL, 0, 5, &mm);
   65|       |
   66|  5.02k|  mg_sntp_parse(data, size);
   67|  5.02k|  mg_sntp_parse(NULL, 0);
   68|       |
   69|  5.02k|  char buf[size * 4 / 3 + 5];  // At least 4 chars and nul termination
   70|  5.02k|  mg_base64_decode((char *) data, size, buf, sizeof(buf));
   71|  5.02k|  mg_base64_decode(NULL, 0, buf, sizeof(buf));
   72|  5.02k|  mg_base64_encode(data, size, buf, sizeof(buf));
   73|  5.02k|  mg_base64_encode(NULL, 0, buf, sizeof(buf));
   74|       |
   75|  5.02k|  mg_match(mg_str_n((char *) data, size), mg_str_n((char *) data, size), NULL);
   76|       |
   77|  5.02k|  struct mg_str entry, s = mg_str_n((char *) data, size);
   78|  1.87M|  while (mg_span(s, &entry, &s, ',')) entry.len = 0;
  ------------------
  |  Branch (78:10): [True: 1.86M, False: 5.02k]
  ------------------
   79|       |
   80|  5.02k|  int n;
   81|  5.02k|  mg_json_get(mg_str_n((char *) data, size), "$", &n);
   82|  5.02k|  mg_json_get(mg_str_n((char *) data, size), "$.a.b", &n);
   83|  5.02k|  mg_json_get(mg_str_n((char *) data, size), "$[0]", &n);
   84|       |
   85|  5.02k|  if (size > 0) {
  ------------------
  |  Branch (85:7): [True: 5.02k, False: 0]
  ------------------
   86|  5.02k|    struct mg_tcpip_if mif = {.ip = 0x01020304,
   87|  5.02k|                              .mask = 255,
   88|  5.02k|                              .gw = 0x01010101,
   89|  5.02k|                              .driver = &mg_tcpip_driver_mock};
   90|  5.02k|    struct mg_mgr mgr;
   91|  5.02k|    mg_mgr_init(&mgr);
   92|  5.02k|    mg_tcpip_init(&mgr, &mif);
   93|       |
   94|       |    // Make a copy of the random data, in order to modify it
   95|  5.02k|    void *pkt = malloc(size);
   96|  5.02k|    struct eth *eth = (struct eth *) pkt;
   97|  5.02k|    memcpy(pkt, data, size);
   98|  5.02k|    if (size > sizeof(*eth)) {
  ------------------
  |  Branch (98:9): [True: 3.33k, False: 1.69k]
  ------------------
   99|  3.33k|      static size_t i;
  100|  3.33k|      uint16_t eth_types[] = {0x800, 0x800, 0x806, 0x86dd};
  101|  3.33k|      memcpy(eth->dst, mif.mac, 6);  // Set valid destination MAC
  102|  3.33k|      eth->type = mg_htons(eth_types[i++]);
  ------------------
  |  | 1059|  3.33k|#define mg_htons(x) mg_ntohs(x)
  ------------------
  103|  3.33k|      if (i >= sizeof(eth_types) / sizeof(eth_types[0])) i = 0;
  ------------------
  |  Branch (103:11): [True: 833, False: 2.49k]
  ------------------
  104|  3.33k|    }
  105|       |
  106|  5.02k|    mg_tcpip_rx(&mif, pkt, size);
  107|       |
  108|       |    // Test HTTP serving
  109|  5.02k|    const char *url = "http://localhost:12345";
  110|  5.02k|    struct mg_connection *c = mg_http_connect(&mgr, url, fn, NULL);
  111|  5.02k|    mg_iobuf_add(&c->recv, 0, data, size);
  112|  5.02k|    c->pfn(c, MG_EV_READ, NULL); // manually invoke protocol event handler
  113|       |
  114|  5.02k|    mg_mgr_free(&mgr);
  115|  5.02k|    free(pkt);
  116|  5.02k|    mg_tcpip_free(&mif);
  117|  5.02k|  }
  118|       |
  119|  5.02k|  return 0;
  120|  5.02k|}
fuzz.c:_ZL2fnP13mg_connectioniPv:
   17|   817k|static void fn(struct mg_connection *c, int ev, void *ev_data) {
   18|   817k|  struct mg_http_serve_opts opts = {.root_dir = "."};
   19|   817k|  if (ev == MG_EV_HTTP_MSG) {
  ------------------
  |  Branch (19:7): [True: 395k, False: 421k]
  ------------------
   20|   395k|    mg_http_serve_dir(c, (struct mg_http_message *) ev_data, &opts);
   21|   395k|  }
   22|   817k|}

mg_base64_update:
   57|   156M|size_t mg_base64_update(unsigned char ch, char *to, size_t n) {
   58|   156M|  unsigned long rem = (n & 3) % 3;
   59|   156M|  if (rem == 0) {
  ------------------
  |  Branch (59:7): [True: 52.1M, False: 104M]
  ------------------
   60|  52.1M|    to[n] = (char) mg_base64_encode_single(ch >> 2);
   61|  52.1M|    to[++n] = (char) ((ch & 3) << 4);
   62|   104M|  } else if (rem == 1) {
  ------------------
  |  Branch (62:14): [True: 52.1M, False: 52.1M]
  ------------------
   63|  52.1M|    to[n] = (char) mg_base64_encode_single(to[n] | (ch >> 4));
   64|  52.1M|    to[++n] = (char) ((ch & 15) << 2);
   65|  52.1M|  } else {
   66|  52.1M|    to[n] = (char) mg_base64_encode_single(to[n] | (ch >> 6));
   67|  52.1M|    to[++n] = (char) mg_base64_encode_single(ch & 63);
   68|  52.1M|    n++;
   69|  52.1M|  }
   70|   156M|  return n;
   71|   156M|}
mg_base64_final:
   73|  10.0k|size_t mg_base64_final(char *to, size_t n) {
   74|  10.0k|  size_t saved = n;
   75|       |  // printf("---[%.*s]\n", n, to);
   76|  10.0k|  if (n & 3) n = mg_base64_update(0, to, n);
  ------------------
  |  Branch (76:7): [True: 3.30k, False: 6.74k]
  ------------------
   77|  10.0k|  if ((saved & 3) == 2) n--;
  ------------------
  |  Branch (77:7): [True: 1.61k, False: 8.44k]
  ------------------
   78|       |  // printf("    %d[%.*s]\n", n, n, to);
   79|  15.0k|  while (n & 3) to[n++] = '=';
  ------------------
  |  Branch (79:10): [True: 5.00k, False: 10.0k]
  ------------------
   80|  10.0k|  to[n] = '\0';
   81|  10.0k|  return n;
   82|  10.0k|}
mg_base64_encode:
   84|  10.0k|size_t mg_base64_encode(const unsigned char *p, size_t n, char *to, size_t dl) {
   85|  10.0k|  size_t i, len = 0;
   86|  10.0k|  if (dl > 0) to[0] = '\0';
  ------------------
  |  Branch (86:7): [True: 10.0k, False: 0]
  ------------------
   87|  10.0k|  if (dl < ((n / 3) + (n % 3 ? 1 : 0)) * 4 + 1) return 0;
  ------------------
  |  Branch (87:7): [True: 0, False: 10.0k]
  |  Branch (87:24): [True: 3.30k, False: 6.74k]
  ------------------
   88|   156M|  for (i = 0; i < n; i++) len = mg_base64_update(p[i], to, len);
  ------------------
  |  Branch (88:15): [True: 156M, False: 10.0k]
  ------------------
   89|  10.0k|  len = mg_base64_final(to, len);
   90|  10.0k|  return len;
   91|  10.0k|}
mg_base64_decode:
   93|  10.0k|size_t mg_base64_decode(const char *src, size_t n, char *dst, size_t dl) {
   94|  10.0k|  const char *end = src == NULL ? NULL : src + n;  // Cannot add to NULL
  ------------------
  |  Branch (94:21): [True: 5.02k, False: 5.02k]
  ------------------
   95|  10.0k|  size_t len = 0;
   96|  10.0k|  if (dl < n / 4 * 3 + 1) goto fail;
  ------------------
  |  Branch (96:7): [True: 0, False: 10.0k]
  ------------------
   97|  1.44M|  while (src != NULL && src + 3 < end) {
  ------------------
  |  Branch (97:10): [True: 1.44M, False: 5.02k]
  |  Branch (97:25): [True: 1.44M, False: 622]
  ------------------
   98|  1.44M|    int a = mg_base64_decode_single(src[0]),
   99|  1.44M|        b = mg_base64_decode_single(src[1]),
  100|  1.44M|        c = mg_base64_decode_single(src[2]),
  101|  1.44M|        d = mg_base64_decode_single(src[3]);
  102|  1.44M|    if (a == 64 || a < 0 || b == 64 || b < 0 || c < 0 || d < 0) {
  ------------------
  |  Branch (102:9): [True: 25, False: 1.44M]
  |  Branch (102:20): [True: 2.48k, False: 1.43M]
  |  Branch (102:29): [True: 5, False: 1.43M]
  |  Branch (102:40): [True: 1.60k, False: 1.43M]
  |  Branch (102:49): [True: 106, False: 1.43M]
  |  Branch (102:58): [True: 181, False: 1.43M]
  ------------------
  103|  4.40k|      goto fail;
  104|  4.40k|    }
  105|  1.43M|    dst[len++] = (char) ((a << 2) | (b >> 4));
  106|  1.43M|    if (src[2] != '=') {
  ------------------
  |  Branch (106:9): [True: 1.43M, False: 325]
  ------------------
  107|  1.43M|      dst[len++] = (char) ((b << 4) | (c >> 2));
  108|  1.43M|      if (src[3] != '=') dst[len++] = (char) ((c << 6) | d);
  ------------------
  |  Branch (108:11): [True: 1.43M, False: 293]
  ------------------
  109|  1.43M|    }
  110|  1.43M|    src += 4;
  111|  1.43M|  }
  112|  5.65k|  dst[len] = '\0';
  113|  5.65k|  return len;
  114|  4.40k|fail:
  115|  4.40k|  if (dl > 0) dst[0] = '\0';
  ------------------
  |  Branch (115:7): [True: 4.40k, False: 0]
  ------------------
  116|  4.40k|  return 0;
  117|  10.0k|}
mg_resolve_cancel:
 1086|  5.02k|void mg_resolve_cancel(struct mg_connection *c) {
 1087|  5.02k|  struct dns_data *tmp, *d;
 1088|  5.02k|  struct dns_data **head = (struct dns_data **) &c->mgr->active_dns_requests;
 1089|  5.02k|  for (d = *head; d != NULL; d = tmp) {
  ------------------
  |  Branch (1089:19): [True: 0, False: 5.02k]
  ------------------
 1090|      0|    tmp = d->next;
 1091|      0|    if (d->c == c) mg_dns_free(head, d);
  ------------------
  |  Branch (1091:9): [True: 0, False: 0]
  ------------------
 1092|      0|  }
 1093|  5.02k|}
mg_dns_parse_rr:
 1138|    752|                       bool is_question, struct mg_dns_rr *rr) {
 1139|    752|  const uint8_t *s = buf + ofs, *e = &buf[len];
 1140|       |
 1141|    752|  memset(rr, 0, sizeof(*rr));
 1142|    752|  if (len < sizeof(struct mg_dns_header)) return 0;  // Too small
  ------------------
  |  Branch (1142:7): [True: 0, False: 752]
  ------------------
 1143|    752|  if (len > 512) return 0;  //  Too large, we don't expect that
  ------------------
  |  Branch (1143:7): [True: 51, False: 701]
  ------------------
 1144|    701|  if (s >= e) return 0;     //  Overflow
  ------------------
  |  Branch (1144:7): [True: 102, False: 599]
  ------------------
 1145|       |
 1146|    599|  if ((rr->nlen = (uint16_t) mg_dns_parse_name(buf, len, ofs, NULL, 0)) == 0)
  ------------------
  |  Branch (1146:7): [True: 68, False: 531]
  ------------------
 1147|     68|    return 0;
 1148|    531|  s += rr->nlen + 4;
 1149|    531|  if (s > e) return 0;
  ------------------
  |  Branch (1149:7): [True: 68, False: 463]
  ------------------
 1150|    463|  rr->atype = (uint16_t) (((uint16_t) s[-4] << 8) | s[-3]);
 1151|    463|  rr->aclass = (uint16_t) (((uint16_t) s[-2] << 8) | s[-1]);
 1152|    463|  if (is_question) return (size_t) (rr->nlen + 4);
  ------------------
  |  Branch (1152:7): [True: 89, False: 374]
  ------------------
 1153|       |
 1154|    374|  s += 6;
 1155|    374|  if (s > e) return 0;
  ------------------
  |  Branch (1155:7): [True: 3, False: 371]
  ------------------
 1156|    371|  rr->alen = (uint16_t) (((uint16_t) s[-2] << 8) | s[-1]);
 1157|    371|  if (s + rr->alen > e) return 0;
  ------------------
  |  Branch (1157:7): [True: 64, False: 307]
  ------------------
 1158|    307|  return (size_t) (rr->nlen + rr->alen + 10);
 1159|    371|}
mg_dns_parse:
 1161|  10.0k|bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
 1162|  10.0k|  const struct mg_dns_header *h = (struct mg_dns_header *) buf;
 1163|  10.0k|  struct mg_dns_rr rr;
 1164|  10.0k|  size_t i, n, num_answers, ofs = sizeof(*h);
 1165|  10.0k|  memset(dm, 0, sizeof(*dm));
 1166|       |
 1167|  10.0k|  if (len < sizeof(*h)) return 0;                // Too small, headers dont fit
  ------------------
  |  Branch (1167:7): [True: 6.44k, False: 3.61k]
  ------------------
 1168|  3.61k|  if (mg_ntohs(h->num_questions) > 1) return 0;  // Sanity
  ------------------
  |  Branch (1168:7): [True: 3.22k, False: 391]
  ------------------
 1169|    391|  num_answers = mg_ntohs(h->num_answers);
 1170|    391|  if (num_answers > 10) {
  ------------------
  |  Branch (1170:7): [True: 310, False: 81]
  ------------------
 1171|    310|    MG_DEBUG(("Got %u answers, ignoring beyond 10th one", num_answers));
  ------------------
  |  |  962|    310|#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  |  |  ------------------
  |  |  |  |  955|    310|  do {                      \
  |  |  |  |  956|    310|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|    310|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1172|    310|    num_answers = 10;  // Sanity cap
 1173|    310|  }
 1174|    391|  dm->txnid = mg_ntohs(h->txnid);
 1175|       |
 1176|    480|  for (i = 0; i < mg_ntohs(h->num_questions); i++) {
  ------------------
  |  Branch (1176:15): [True: 151, False: 329]
  ------------------
 1177|    151|    if ((n = mg_dns_parse_rr(buf, len, ofs, true, &rr)) == 0) return false;
  ------------------
  |  Branch (1177:9): [True: 62, False: 89]
  ------------------
 1178|       |    // MG_INFO(("Q %lu %lu %hu/%hu", ofs, n, rr.atype, rr.aclass));
 1179|     89|    ofs += n;
 1180|     89|  }
 1181|    634|  for (i = 0; i < num_answers; i++) {
  ------------------
  |  Branch (1181:15): [True: 601, False: 33]
  ------------------
 1182|    601|    if ((n = mg_dns_parse_rr(buf, len, ofs, false, &rr)) == 0) return false;
  ------------------
  |  Branch (1182:9): [True: 294, False: 307]
  ------------------
 1183|       |    // MG_INFO(("A -- %lu %lu %hu/%hu %s", ofs, n, rr.atype, rr.aclass,
 1184|       |    // dm->name));
 1185|    307|    mg_dns_parse_name(buf, len, ofs, dm->name, sizeof(dm->name));
 1186|    307|    ofs += n;
 1187|       |
 1188|    307|    if (rr.alen == 4 && rr.atype == 1 && rr.aclass == 1) {
  ------------------
  |  Branch (1188:9): [True: 64, False: 243]
  |  Branch (1188:25): [True: 33, False: 31]
  |  Branch (1188:42): [True: 1, False: 32]
  ------------------
 1189|      1|      dm->addr.is_ip6 = false;
 1190|      1|      memcpy(&dm->addr.ip, &buf[ofs - 4], 4);
 1191|      1|      dm->resolved = true;
 1192|      1|      break;  // Return success
 1193|    306|    } else if (rr.alen == 16 && rr.atype == 28 && rr.aclass == 1) {
  ------------------
  |  Branch (1193:16): [True: 55, False: 251]
  |  Branch (1193:33): [True: 26, False: 29]
  |  Branch (1193:51): [True: 1, False: 25]
  ------------------
 1194|      1|      dm->addr.is_ip6 = true;
 1195|      1|      memcpy(&dm->addr.ip, &buf[ofs - 16], 16);
 1196|      1|      dm->resolved = true;
 1197|      1|      break;  // Return success
 1198|      1|    }
 1199|    307|  }
 1200|     35|  return true;
 1201|    329|}
mg_resolve:
 1318|  5.02k|void mg_resolve(struct mg_connection *c, const char *url) {
 1319|  5.02k|  struct mg_str host = mg_url_host(url);
 1320|  5.02k|  c->rem.port = mg_htons(mg_url_port(url));
  ------------------
  |  | 1059|  5.02k|#define mg_htons(x) mg_ntohs(x)
  ------------------
 1321|  5.02k|  if (mg_aton(host, &c->rem)) {
  ------------------
  |  Branch (1321:7): [True: 5.02k, False: 0]
  ------------------
 1322|       |    // host is an IP address, do not fire name resolution
 1323|  5.02k|    mg_connect_resolved(c);
 1324|  5.02k|  } else {
 1325|       |    // host is not an IP, send DNS resolution request
 1326|      0|    struct mg_dns *dns = c->mgr->use_dns6 ? &c->mgr->dns6 : &c->mgr->dns4;
  ------------------
  |  Branch (1326:26): [True: 0, False: 0]
  ------------------
 1327|      0|    mg_sendnsreq(c, &host, c->mgr->dnstimeout, dns, c->mgr->use_dns6);
 1328|      0|  }
 1329|  5.02k|}
mg_call:
 1340|   817k|void mg_call(struct mg_connection *c, int ev, void *ev_data) {
 1341|       |#if MG_ENABLE_PROFILE
 1342|       |  const char *names[] = {
 1343|       |      "EV_ERROR",    "EV_OPEN",      "EV_POLL",      "EV_RESOLVE",
 1344|       |      "EV_CONNECT",  "EV_ACCEPT",    "EV_TLS_HS",    "EV_READ",
 1345|       |      "EV_WRITE",    "EV_CLOSE",     "EV_HTTP_MSG",  "EV_HTTP_CHUNK",
 1346|       |      "EV_WS_OPEN",  "EV_WS_MSG",    "EV_WS_CTL",    "EV_MQTT_CMD",
 1347|       |      "EV_MQTT_MSG", "EV_MQTT_OPEN", "EV_SNTP_TIME", "EV_USER"};
 1348|       |  if (ev != MG_EV_POLL && ev < (int) (sizeof(names) / sizeof(names[0]))) {
 1349|       |    MG_PROF_ADD(c, names[ev]);
 1350|       |  }
 1351|       |#endif
 1352|       |  // Fire protocol handler first, user handler second. See #2559
 1353|   817k|  if (c->pfn != NULL) c->pfn(c, ev, ev_data);
  ------------------
  |  Branch (1353:7): [True: 807k, False: 10.0k]
  ------------------
 1354|   817k|  if (c->fn != NULL) c->fn(c, ev, ev_data);
  ------------------
  |  Branch (1354:7): [True: 817k, False: 0]
  ------------------
 1355|   817k|}
mg_error:
 1357|  5.44k|void mg_error(struct mg_connection *c, const char *fmt, ...) {
 1358|  5.44k|  char buf[64];
 1359|  5.44k|  va_list ap;
 1360|  5.44k|  va_start(ap, fmt);
 1361|  5.44k|  mg_vsnprintf(buf, sizeof(buf), fmt, &ap);
 1362|  5.44k|  va_end(ap);
 1363|  5.44k|  MG_ERROR(("%lu %ld %s", c->id, c->fd, buf));
  ------------------
  |  |  960|  5.44k|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|  5.44k|  do {                      \
  |  |  |  |  956|  5.44k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.44k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1364|  5.44k|  c->is_closing = 1;             // Set is_closing before sending MG_EV_CALL
 1365|  5.44k|  mg_call(c, MG_EV_ERROR, buf);  // Let user handler override it
 1366|  5.44k|}
mg_vxprintf:
 1508|  19.6M|                   va_list *ap) {
 1509|  19.6M|  size_t i = 0, n = 0;
 1510|   546M|  while (fmt[i] != '\0') {
  ------------------
  |  Branch (1510:10): [True: 526M, False: 19.6M]
  ------------------
 1511|   526M|    if (fmt[i] == '%') {
  ------------------
  |  Branch (1511:9): [True: 56.7M, False: 469M]
  ------------------
 1512|  56.7M|      size_t j, k, x = 0, is_long = 0, w = 0 /* width */, pr = ~0U /* prec */;
 1513|  56.7M|      char pad = ' ', minus = 0, c = fmt[++i];
 1514|  56.7M|      if (c == '#') x++, c = fmt[++i];
  ------------------
  |  Branch (1514:11): [True: 0, False: 56.7M]
  ------------------
 1515|  56.7M|      if (c == '-') minus++, c = fmt[++i];
  ------------------
  |  Branch (1515:11): [True: 53.9k, False: 56.6M]
  ------------------
 1516|  56.7M|      if (c == '0') pad = '0', c = fmt[++i];
  ------------------
  |  Branch (1516:11): [True: 0, False: 56.7M]
  ------------------
 1517|  56.8M|      while (is_digit(c)) w *= 10, w += (size_t) (c - '0'), c = fmt[++i];
  ------------------
  |  Branch (1517:14): [True: 107k, False: 56.7M]
  ------------------
 1518|  56.7M|      if (c == '.') {
  ------------------
  |  Branch (1518:11): [True: 5.17M, False: 51.5M]
  ------------------
 1519|  5.17M|        c = fmt[++i];
 1520|  5.17M|        if (c == '*') {
  ------------------
  |  Branch (1520:13): [True: 5.17M, False: 0]
  ------------------
 1521|  5.17M|          pr = (size_t) va_arg(*ap, int);
 1522|  5.17M|          c = fmt[++i];
 1523|  5.17M|        } else {
 1524|      0|          pr = 0;
 1525|      0|          while (is_digit(c)) pr *= 10, pr += (size_t) (c - '0'), c = fmt[++i];
  ------------------
  |  Branch (1525:18): [True: 0, False: 0]
  ------------------
 1526|      0|        }
 1527|  5.17M|      }
 1528|  56.7M|      while (c == 'h') c = fmt[++i];  // Treat h and hh as int
  ------------------
  |  Branch (1528:14): [True: 0, False: 56.7M]
  ------------------
 1529|  56.7M|      if (c == 'l') {
  ------------------
  |  Branch (1529:11): [True: 13.3M, False: 43.3M]
  ------------------
 1530|  13.3M|        is_long++, c = fmt[++i];
 1531|  13.3M|        if (c == 'l') is_long++, c = fmt[++i];
  ------------------
  |  Branch (1531:13): [True: 4.75M, False: 8.61M]
  ------------------
 1532|  13.3M|      }
 1533|  56.7M|      if (c == 'p') x = 1, is_long = 1;
  ------------------
  |  Branch (1533:11): [True: 0, False: 56.7M]
  ------------------
 1534|  56.7M|      if (c == 'd' || c == 'u' || c == 'x' || c == 'X' || c == 'p' ||
  ------------------
  |  Branch (1534:11): [True: 4.80M, False: 51.9M]
  |  Branch (1534:23): [True: 8.61M, False: 43.3M]
  |  Branch (1534:35): [True: 0, False: 43.3M]
  |  Branch (1534:47): [True: 0, False: 43.3M]
  |  Branch (1534:59): [True: 0, False: 43.3M]
  ------------------
 1535|  56.7M|          c == 'g' || c == 'f') {
  ------------------
  |  Branch (1535:11): [True: 0, False: 43.3M]
  |  Branch (1535:23): [True: 0, False: 43.3M]
  ------------------
 1536|  13.4M|        bool s = (c == 'd'), h = (c == 'x' || c == 'X' || c == 'p');
  ------------------
  |  Branch (1536:35): [True: 0, False: 13.4M]
  |  Branch (1536:47): [True: 0, False: 13.4M]
  |  Branch (1536:59): [True: 0, False: 13.4M]
  ------------------
 1537|  13.4M|        char tmp[40];
 1538|  13.4M|        size_t xl = x ? 2 : 0;
  ------------------
  |  Branch (1538:21): [True: 0, False: 13.4M]
  ------------------
 1539|  13.4M|        if (c == 'g' || c == 'f') {
  ------------------
  |  Branch (1539:13): [True: 0, False: 13.4M]
  |  Branch (1539:25): [True: 0, False: 13.4M]
  ------------------
 1540|      0|          double v = va_arg(*ap, double);
 1541|      0|          if (pr == ~0U) pr = 6;
  ------------------
  |  Branch (1541:15): [True: 0, False: 0]
  ------------------
 1542|      0|          k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr, c == 'g');
 1543|  13.4M|        } else if (is_long == 2) {
  ------------------
  |  Branch (1543:20): [True: 4.75M, False: 8.66M]
  ------------------
 1544|  4.75M|          int64_t v = va_arg(*ap, int64_t);
 1545|  4.75M|          k = mg_lld(tmp, v, s, h);
 1546|  8.66M|        } else if (is_long == 1) {
  ------------------
  |  Branch (1546:20): [True: 8.61M, False: 53.9k]
  ------------------
 1547|  8.61M|          long v = va_arg(*ap, long);
 1548|  8.61M|          k = mg_lld(tmp, s ? (int64_t) v : (int64_t) (unsigned long) v, s, h);
  ------------------
  |  Branch (1548:27): [True: 0, False: 8.61M]
  ------------------
 1549|  8.61M|        } else {
 1550|  53.9k|          int v = va_arg(*ap, int);
 1551|  53.9k|          k = mg_lld(tmp, s ? (int64_t) v : (int64_t) (unsigned) v, s, h);
  ------------------
  |  Branch (1551:27): [True: 53.9k, False: 0]
  ------------------
 1552|  53.9k|        }
 1553|  13.4M|        for (j = 0; j < xl && w > 0; j++) w--;
  ------------------
  |  Branch (1553:21): [True: 0, False: 13.4M]
  |  Branch (1553:31): [True: 0, False: 0]
  ------------------
 1554|  13.4M|        for (j = 0; pad == ' ' && !minus && k < w && j + k < w; j++)
  ------------------
  |  Branch (1554:21): [True: 13.4M, False: 0]
  |  Branch (1554:35): [True: 13.3M, False: 53.9k]
  |  Branch (1554:45): [True: 0, False: 13.3M]
  |  Branch (1554:54): [True: 0, False: 0]
  ------------------
 1555|      0|          n += scpy(out, param, &pad, 1);
 1556|  13.4M|        n += scpy(out, param, (char *) "0x", xl);
 1557|  13.4M|        for (j = 0; pad == '0' && k < w && j + k < w; j++)
  ------------------
  |  Branch (1557:21): [True: 0, False: 13.4M]
  |  Branch (1557:35): [True: 0, False: 0]
  |  Branch (1557:44): [True: 0, False: 0]
  ------------------
 1558|      0|          n += scpy(out, param, &pad, 1);
 1559|  13.4M|        n += scpy(out, param, tmp, k);
 1560|  13.8M|        for (j = 0; pad == ' ' && minus && k < w && j + k < w; j++)
  ------------------
  |  Branch (1560:21): [True: 13.8M, False: 0]
  |  Branch (1560:35): [True: 485k, False: 13.3M]
  |  Branch (1560:44): [True: 485k, False: 0]
  |  Branch (1560:53): [True: 431k, False: 53.9k]
  ------------------
 1561|   431k|          n += scpy(out, param, &pad, 1);
 1562|  43.3M|      } else if (c == 'm' || c == 'M') {
  ------------------
  |  Branch (1562:18): [True: 0, False: 43.3M]
  |  Branch (1562:30): [True: 0, False: 43.3M]
  ------------------
 1563|      0|        mg_pm_t f = va_arg(*ap, mg_pm_t);
 1564|      0|        if (c == 'm') out('"', param);
  ------------------
  |  Branch (1564:13): [True: 0, False: 0]
  ------------------
 1565|      0|        n += f(out, param, ap);
 1566|      0|        if (c == 'm') n += 2, out('"', param);
  ------------------
  |  Branch (1566:13): [True: 0, False: 0]
  ------------------
 1567|  43.3M|      } else if (c == 'c') {
  ------------------
  |  Branch (1567:18): [True: 4.12M, False: 39.1M]
  ------------------
 1568|  4.12M|        int ch = va_arg(*ap, int);
 1569|  4.12M|        out((char) ch, param);
 1570|  4.12M|        n++;
 1571|  39.1M|      } else if (c == 's') {
  ------------------
  |  Branch (1571:18): [True: 39.1M, False: 0]
  ------------------
 1572|  39.1M|        char *p = va_arg(*ap, char *);
 1573|  39.1M|        if (pr == ~0U) pr = p == NULL ? 0 : strlen(p);
  ------------------
  |  Branch (1573:13): [True: 34.0M, False: 5.17M]
  |  Branch (1573:29): [True: 0, False: 34.0M]
  ------------------
 1574|  39.1M|        for (j = 0; !minus && pr < w && j + pr < w; j++)
  ------------------
  |  Branch (1574:21): [True: 39.1M, False: 0]
  |  Branch (1574:31): [True: 0, False: 39.1M]
  |  Branch (1574:41): [True: 0, False: 0]
  ------------------
 1575|      0|          n += scpy(out, param, &pad, 1);
 1576|  39.1M|        n += scpy(out, param, p, pr);
 1577|  39.1M|        for (j = 0; minus && pr < w && j + pr < w; j++)
  ------------------
  |  Branch (1577:21): [True: 0, False: 39.1M]
  |  Branch (1577:30): [True: 0, False: 0]
  |  Branch (1577:40): [True: 0, False: 0]
  ------------------
 1578|      0|          n += scpy(out, param, &pad, 1);
 1579|  39.1M|      } else if (c == '%') {
  ------------------
  |  Branch (1579:18): [True: 0, False: 0]
  ------------------
 1580|      0|        out('%', param);
 1581|      0|        n++;
 1582|      0|      } else {
 1583|      0|        out('%', param);
 1584|      0|        out(c, param);
 1585|      0|        n += 2;
 1586|      0|      }
 1587|  56.7M|      i++;
 1588|   469M|    } else {
 1589|   469M|      out(fmt[i], param), n++, i++;
 1590|   469M|    }
 1591|   526M|  }
 1592|  19.6M|  return n;
 1593|  19.6M|}
mg_fs_open:
 1602|  52.5k|struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) {
 1603|  52.5k|  struct mg_fd *fd = (struct mg_fd *) calloc(1, sizeof(*fd));
 1604|  52.5k|  if (fd != NULL) {
  ------------------
  |  Branch (1604:7): [True: 52.5k, False: 0]
  ------------------
 1605|  52.5k|    fd->fd = fs->op(path, flags);
 1606|  52.5k|    fd->fs = fs;
 1607|  52.5k|    if (fd->fd == NULL) {
  ------------------
  |  Branch (1607:9): [True: 52.5k, False: 0]
  ------------------
 1608|  52.5k|      free(fd);
 1609|  52.5k|      fd = NULL;
 1610|  52.5k|    }
 1611|  52.5k|  }
 1612|  52.5k|  return fd;
 1613|  52.5k|}
mg_fs_close:
 1615|  52.2k|void mg_fs_close(struct mg_fd *fd) {
 1616|  52.2k|  if (fd != NULL) {
  ------------------
  |  Branch (1616:7): [True: 0, False: 52.2k]
  ------------------
 1617|      0|    fd->fs->cl(fd->fd);
 1618|      0|    free(fd);
 1619|      0|  }
 1620|  52.2k|}
_Z12mg_to_size_t6mg_strPm:
 2242|  1.37k|bool mg_to_size_t(struct mg_str str, size_t *val) {
 2243|  1.37k|  size_t i = 0, max = (size_t) -1, max2 = max / 10, result = 0, ndigits = 0;
 2244|  1.37k|  while (i < str.len && (str.buf[i] == ' ' || str.buf[i] == '\t')) i++;
  ------------------
  |  Branch (2244:10): [True: 1.37k, False: 3]
  |  Branch (2244:26): [True: 0, False: 1.37k]
  |  Branch (2244:47): [True: 0, False: 1.37k]
  ------------------
 2245|  1.37k|  if (i < str.len && str.buf[i] == '-') return false;
  ------------------
  |  Branch (2245:7): [True: 1.37k, False: 3]
  |  Branch (2245:22): [True: 5, False: 1.36k]
  ------------------
 2246|  2.50M|  while (i < str.len && str.buf[i] >= '0' && str.buf[i] <= '9') {
  ------------------
  |  Branch (2246:10): [True: 2.50M, False: 1.22k]
  |  Branch (2246:25): [True: 2.50M, False: 108]
  |  Branch (2246:46): [True: 2.50M, False: 19]
  ------------------
 2247|  2.50M|    size_t digit = (size_t) (str.buf[i] - '0');
 2248|  2.50M|    if (result > max2) return false;  // Overflow
  ------------------
  |  Branch (2248:9): [True: 11, False: 2.50M]
  ------------------
 2249|  2.50M|    result *= 10;
 2250|  2.50M|    if (result > max - digit) return false;  // Overflow
  ------------------
  |  Branch (2250:9): [True: 3, False: 2.50M]
  ------------------
 2251|  2.50M|    result += digit;
 2252|  2.50M|    i++, ndigits++;
 2253|  2.50M|  }
 2254|  2.86k|  while (i < str.len && (str.buf[i] == ' ' || str.buf[i] == '\t')) i++;
  ------------------
  |  Branch (2254:10): [True: 1.64k, False: 1.22k]
  |  Branch (2254:26): [True: 1.27k, False: 370]
  |  Branch (2254:47): [True: 243, False: 127]
  ------------------
 2255|  1.35k|  if (ndigits == 0) return false;  // #2322: Content-Length = 1 * DIGIT
  ------------------
  |  Branch (2255:7): [True: 30, False: 1.32k]
  ------------------
 2256|  1.32k|  if (i != str.len) return false;  // Ditto
  ------------------
  |  Branch (2256:7): [True: 100, False: 1.22k]
  ------------------
 2257|  1.22k|  *val = (size_t) result;
 2258|  1.22k|  return true;
 2259|  1.32k|}
mg_http_var:
 2342|  5.02k|struct mg_str mg_http_var(struct mg_str buf, struct mg_str name) {
 2343|  5.02k|  struct mg_str entry, k, v, result = mg_str_n(NULL, 0);
 2344|   200k|  while (mg_span(buf, &entry, &buf, '&')) {
  ------------------
  |  Branch (2344:10): [True: 195k, False: 5.00k]
  ------------------
 2345|   195k|    if (mg_span(entry, &k, &v, '=') && name.len == k.len &&
  ------------------
  |  Branch (2345:9): [True: 194k, False: 1.54k]
  |  Branch (2345:40): [True: 80.8k, False: 113k]
  ------------------
 2346|   195k|        mg_ncasecmp(name.buf, k.buf, k.len) == 0) {
  ------------------
  |  Branch (2346:9): [True: 24, False: 80.8k]
  ------------------
 2347|     24|      result = v;
 2348|     24|      break;
 2349|     24|    }
 2350|   195k|  }
 2351|  5.02k|  return result;
 2352|  5.02k|}
mg_http_get_var:
 2355|  10.0k|                    size_t dst_len) {
 2356|  10.0k|  int len;
 2357|  10.0k|  if (dst != NULL && dst_len > 0) {
  ------------------
  |  Branch (2357:7): [True: 5.02k, False: 5.02k]
  |  Branch (2357:22): [True: 5.02k, False: 0]
  ------------------
 2358|  5.02k|    dst[0] = '\0';  // If destination buffer is valid, always nul-terminate it
 2359|  5.02k|  }
 2360|  10.0k|  if (dst == NULL || dst_len == 0) {
  ------------------
  |  Branch (2360:7): [True: 5.02k, False: 5.02k]
  |  Branch (2360:22): [True: 0, False: 5.02k]
  ------------------
 2361|  5.02k|    len = -2;  // Bad destination
 2362|  5.02k|  } else if (buf->buf == NULL || name == NULL || buf->len == 0) {
  ------------------
  |  Branch (2362:14): [True: 0, False: 5.02k]
  |  Branch (2362:34): [True: 0, False: 5.02k]
  |  Branch (2362:50): [True: 0, False: 5.02k]
  ------------------
 2363|      0|    len = -1;  // Bad source
 2364|  5.02k|  } else {
 2365|  5.02k|    struct mg_str v = mg_http_var(*buf, mg_str(name));
  ------------------
  |  |  859|  5.02k|#define mg_str(s) mg_str_s(s)
  ------------------
 2366|  5.02k|    if (v.buf == NULL) {
  ------------------
  |  Branch (2366:9): [True: 5.00k, False: 24]
  ------------------
 2367|  5.00k|      len = -4;  // Name does not exist
 2368|  5.00k|    } else {
 2369|     24|      len = mg_url_decode(v.buf, v.len, dst, dst_len, 1);
 2370|     24|      if (len < 0) len = -3;  // Failed to decode
  ------------------
  |  Branch (2370:11): [True: 9, False: 15]
  ------------------
 2371|     24|    }
 2372|  5.02k|  }
 2373|  10.0k|  return len;
 2374|  10.0k|}
mg_url_decode:
 2382|   529k|                  int is_form_url_encoded) {
 2383|   529k|  size_t i, j;
 2384|  5.78M|  for (i = j = 0; i < src_len && j + 1 < dst_len; i++, j++) {
  ------------------
  |  Branch (2384:19): [True: 5.34M, False: 434k]
  |  Branch (2384:34): [True: 5.34M, False: 6.62k]
  ------------------
 2385|  5.34M|    if (src[i] == '%') {
  ------------------
  |  Branch (2385:9): [True: 131k, False: 5.20M]
  ------------------
 2386|       |      // Use `i + 2 < src_len`, not `i < src_len - 2`, note small src_len
 2387|   131k|      if (i + 2 < src_len && isx(src[i + 1]) && isx(src[i + 2])) {
  ------------------
  |  Branch (2387:11): [True: 128k, False: 2.75k]
  |  Branch (2387:30): [True: 68.6k, False: 60.2k]
  |  Branch (2387:49): [True: 43.4k, False: 25.2k]
  ------------------
 2388|  43.4k|        mg_str_to_num(mg_str_n(src + i + 1, 2), 16, &dst[j], sizeof(uint8_t));
 2389|  43.4k|        i += 2;
 2390|  88.2k|      } else {
 2391|  88.2k|        return -1;
 2392|  88.2k|      }
 2393|  5.20M|    } else if (is_form_url_encoded && src[i] == '+') {
  ------------------
  |  Branch (2393:16): [True: 388k, False: 4.82M]
  |  Branch (2393:39): [True: 2.02k, False: 386k]
  ------------------
 2394|  2.02k|      dst[j] = ' ';
 2395|  5.20M|    } else {
 2396|  5.20M|      dst[j] = src[i];
 2397|  5.20M|    }
 2398|  5.34M|  }
 2399|   441k|  if (j < dst_len) dst[j] = '\0';  // Null-terminate the destination
  ------------------
  |  Branch (2399:7): [True: 441k, False: 0]
  ------------------
 2400|   441k|  return i >= src_len && j < dst_len ? (int) j : -1;
  ------------------
  |  Branch (2400:10): [True: 434k, False: 6.62k]
  |  Branch (2400:26): [True: 434k, False: 0]
  ------------------
 2401|   529k|}
mg_http_get_request_len:
 2407|   411k|int mg_http_get_request_len(const unsigned char *buf, size_t buf_len) {
 2408|   411k|  size_t i;
 2409|   153M|  for (i = 0; i < buf_len; i++) {
  ------------------
  |  Branch (2409:15): [True: 153M, False: 9.18k]
  ------------------
 2410|   153M|    if (!isok(buf[i])) return -1;
  ------------------
  |  Branch (2410:9): [True: 2.13k, False: 153M]
  ------------------
 2411|   153M|    if ((i > 0 && buf[i] == '\n' && buf[i - 1] == '\n') ||
  ------------------
  |  Branch (2411:10): [True: 153M, False: 405k]
  |  Branch (2411:19): [True: 872k, False: 152M]
  |  Branch (2411:37): [True: 398k, False: 473k]
  ------------------
 2412|   153M|        (i > 3 && buf[i] == '\n' && buf[i - 1] == '\r' && buf[i - 2] == '\n'))
  ------------------
  |  Branch (2412:10): [True: 151M, False: 1.61M]
  |  Branch (2412:19): [True: 279k, False: 151M]
  |  Branch (2412:37): [True: 2.70k, False: 276k]
  |  Branch (2412:59): [True: 1.04k, False: 1.66k]
  ------------------
 2413|   399k|      return (int) i + 1;
 2414|   153M|  }
 2415|  9.18k|  return 0;
 2416|   411k|}
mg_http_get_header:
 2417|  1.24M|struct mg_str *mg_http_get_header(struct mg_http_message *h, const char *name) {
 2418|  1.24M|  size_t i, n = strlen(name), max = sizeof(h->headers) / sizeof(h->headers[0]);
 2419|  1.32M|  for (i = 0; i < max && h->headers[i].name.len > 0; i++) {
  ------------------
  |  Branch (2419:15): [True: 1.32M, False: 1.60k]
  |  Branch (2419:26): [True: 88.4k, False: 1.23M]
  ------------------
 2420|  88.4k|    struct mg_str *k = &h->headers[i].name, *v = &h->headers[i].value;
 2421|  88.4k|    if (n == k->len && mg_ncasecmp(k->buf, name, n) == 0) return v;
  ------------------
  |  Branch (2421:9): [True: 10.0k, False: 78.3k]
  |  Branch (2421:24): [True: 6.62k, False: 3.44k]
  ------------------
 2422|  88.4k|  }
 2423|  1.23M|  return NULL;
 2424|  1.24M|}
mg_http_parse:
 2477|   411k|int mg_http_parse(const char *s, size_t len, struct mg_http_message *hm) {
 2478|   411k|  int is_response, req_len = mg_http_get_request_len((unsigned char *) s, len);
 2479|   411k|  const char *end = s == NULL ? NULL : s + req_len, *qs;  // Cannot add to NULL
  ------------------
  |  Branch (2479:21): [True: 5.02k, False: 406k]
  ------------------
 2480|   411k|  const struct mg_str *cl;
 2481|   411k|  size_t n;
 2482|       |
 2483|   411k|  memset(hm, 0, sizeof(*hm));
 2484|   411k|  if (req_len <= 0) return req_len;
  ------------------
  |  Branch (2484:7): [True: 11.3k, False: 399k]
  ------------------
 2485|       |
 2486|   399k|  hm->message.buf = hm->head.buf = (char *) s;
 2487|   399k|  hm->body.buf = (char *) end;
 2488|   399k|  hm->head.len = (size_t) req_len;
 2489|   399k|  hm->message.len = hm->body.len = (size_t) -1;  // Set body length to infinite
 2490|       |
 2491|       |  // Parse request line
 2492|   399k|  hm->method.buf = (char *) s;
 2493|  5.14M|  while (s < end && (n = clen(s, end)) > 0) s += n, hm->method.len += n;
  ------------------
  |  Branch (2493:10): [True: 5.14M, False: 0]
  |  Branch (2493:21): [True: 4.74M, False: 399k]
  ------------------
 2494|   807k|  while (s < end && s[0] == ' ') s++;  // Skip spaces
  ------------------
  |  Branch (2494:10): [True: 807k, False: 0]
  |  Branch (2494:21): [True: 407k, False: 399k]
  ------------------
 2495|   399k|  hm->uri.buf = (char *) s;
 2496|  23.4M|  while (s < end && (n = clen(s, end)) > 0) s += n, hm->uri.len += n;
  ------------------
  |  Branch (2496:10): [True: 23.4M, False: 0]
  |  Branch (2496:21): [True: 23.0M, False: 399k]
  ------------------
 2497|   411k|  while (s < end && s[0] == ' ') s++;  // Skip spaces
  ------------------
  |  Branch (2497:10): [True: 411k, False: 0]
  |  Branch (2497:21): [True: 11.1k, False: 399k]
  ------------------
 2498|   399k|  if ((s = skiptorn(s, end, &hm->proto)) == NULL) return false;
  ------------------
  |  Branch (2498:7): [True: 279, False: 399k]
  ------------------
 2499|       |
 2500|       |  // If URI contains '?' character, setup query string
 2501|   399k|  if ((qs = (const char *) memchr(hm->uri.buf, '?', hm->uri.len)) != NULL) {
  ------------------
  |  Branch (2501:7): [True: 1.31k, False: 398k]
  ------------------
 2502|  1.31k|    hm->query.buf = (char *) qs + 1;
 2503|  1.31k|    hm->query.len = (size_t) (&hm->uri.buf[hm->uri.len] - (qs + 1));
 2504|  1.31k|    hm->uri.len = (size_t) (qs - hm->uri.buf);
 2505|  1.31k|  }
 2506|       |
 2507|       |  // Sanity check. Allow protocol/reason to be empty
 2508|       |  // Do this check after hm->method.len and hm->uri.len are finalised
 2509|   399k|  if (hm->method.len == 0 || hm->uri.len == 0) return -1;
  ------------------
  |  Branch (2509:7): [True: 265, False: 399k]
  |  Branch (2509:30): [True: 160, False: 399k]
  ------------------
 2510|       |
 2511|   399k|  if (!mg_http_parse_headers(s, end, hm->headers,
  ------------------
  |  Branch (2511:7): [True: 344, False: 398k]
  ------------------
 2512|   399k|                             sizeof(hm->headers) / sizeof(hm->headers[0])))
 2513|    344|    return -1;  // error when parsing
 2514|   398k|  if ((cl = mg_http_get_header(hm, "Content-Length")) != NULL) {
  ------------------
  |  Branch (2514:7): [True: 1.37k, False: 397k]
  ------------------
 2515|  1.37k|    if (mg_to_size_t(*cl, &hm->body.len) == false) return -1;
  ------------------
  |  Branch (2515:9): [True: 149, False: 1.22k]
  ------------------
 2516|  1.22k|    hm->message.len = (size_t) req_len + hm->body.len;
 2517|  1.22k|  }
 2518|       |
 2519|       |  // mg_http_parse() is used to parse both HTTP requests and HTTP
 2520|       |  // responses. If HTTP response does not have Content-Length set, then
 2521|       |  // body is read until socket is closed, i.e. body.len is infinite (~0).
 2522|       |  //
 2523|       |  // For HTTP requests though, according to
 2524|       |  // http://tools.ietf.org/html/rfc7231#section-8.1.3,
 2525|       |  // only POST and PUT methods have defined body semantics.
 2526|       |  // Therefore, if Content-Length is not specified and methods are
 2527|       |  // not one of PUT or POST, set body length to 0.
 2528|       |  //
 2529|       |  // So, if it is HTTP request, and Content-Length is not set,
 2530|       |  // and method is not (PUT or POST) then reset body length to zero.
 2531|   398k|  is_response = mg_ncasecmp(hm->method.buf, "HTTP/", 5) == 0;
 2532|   398k|  if (hm->body.len == (size_t) ~0 && !is_response &&
  ------------------
  |  Branch (2532:7): [True: 397k, False: 1.22k]
  |  Branch (2532:38): [True: 396k, False: 1.31k]
  ------------------
 2533|   398k|      mg_strcasecmp(hm->method, mg_str("PUT")) != 0 &&
  ------------------
  |  |  859|   396k|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (2533:7): [True: 395k, False: 830]
  ------------------
 2534|   398k|      mg_strcasecmp(hm->method, mg_str("POST")) != 0) {
  ------------------
  |  |  859|   395k|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (2534:7): [True: 395k, False: 25]
  ------------------
 2535|   395k|    hm->body.len = 0;
 2536|   395k|    hm->message.len = (size_t) req_len;
 2537|   395k|  }
 2538|       |
 2539|       |  // The 204 (No content) responses also have 0 body length
 2540|   398k|  if (hm->body.len == (size_t) ~0 && is_response &&
  ------------------
  |  Branch (2540:7): [True: 2.16k, False: 396k]
  |  Branch (2540:38): [True: 1.31k, False: 855]
  ------------------
 2541|   398k|      mg_strcasecmp(hm->uri, mg_str("204")) == 0) {
  ------------------
  |  |  859|  1.31k|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (2541:7): [True: 623, False: 689]
  ------------------
 2542|    623|    hm->body.len = 0;
 2543|    623|    hm->message.len = (size_t) req_len;
 2544|    623|  }
 2545|   398k|  if (hm->message.len < (size_t) req_len) return -1;  // Overflow protection
  ------------------
  |  Branch (2545:7): [True: 5, False: 398k]
  ------------------
 2546|       |
 2547|   398k|  return req_len;
 2548|   398k|}
mg_http_reply:
 2649|  53.9k|                   const char *fmt, ...) {
 2650|  53.9k|  va_list ap;
 2651|  53.9k|  size_t len;
 2652|  53.9k|  mg_printf(c, "HTTP/1.1 %d %s\r\n%sContent-Length:            \r\n\r\n", code,
 2653|  53.9k|            mg_http_status_code_str(code), headers == NULL ? "" : headers);
  ------------------
  |  Branch (2653:44): [True: 52.2k, False: 1.69k]
  ------------------
 2654|  53.9k|  len = c->send.len;
 2655|  53.9k|  va_start(ap, fmt);
 2656|  53.9k|  mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
 2657|  53.9k|  va_end(ap);
 2658|  53.9k|  if (c->send.len > 16) {
  ------------------
  |  Branch (2658:7): [True: 53.9k, False: 0]
  ------------------
 2659|  53.9k|    size_t n = mg_snprintf((char *) &c->send.buf[len - 15], 11, "%-10lu",
 2660|  53.9k|                           (unsigned long) (c->send.len - len));
 2661|  53.9k|    c->send.buf[len - 15 + n] = ' ';  // Change ending 0 to space
 2662|  53.9k|  }
 2663|  53.9k|  c->is_resp = 0;
 2664|  53.9k|}
mg_http_serve_file:
 2779|  52.2k|                        const struct mg_http_serve_opts *opts) {
 2780|  52.2k|  char etag[64], tmp[MG_PATH_MAX];
 2781|  52.2k|  struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  ------------------
  |  Branch (2781:22): [True: 52.2k, False: 0]
  ------------------
 2782|  52.2k|  struct mg_fd *fd = NULL;
 2783|  52.2k|  size_t size = 0;
 2784|  52.2k|  time_t mtime = 0;
 2785|  52.2k|  struct mg_str *inm = NULL;
 2786|  52.2k|  struct mg_str mime = guess_content_type(mg_str(path), opts->mime_types);
  ------------------
  |  |  859|  52.2k|#define mg_str(s) mg_str_s(s)
  ------------------
 2787|  52.2k|  bool gzip = false;
 2788|       |
 2789|  52.2k|  if (path != NULL) {
  ------------------
  |  Branch (2789:7): [True: 52.2k, False: 0]
  ------------------
 2790|       |    // If a browser sends us "Accept-Encoding: gzip", try to open .gz first
 2791|  52.2k|    struct mg_str *ae = mg_http_get_header(hm, "Accept-Encoding");
 2792|  52.2k|    if (ae != NULL) {
  ------------------
  |  Branch (2792:9): [True: 2.72k, False: 49.5k]
  ------------------
 2793|  2.72k|      char *ae_ = mg_mprintf("%.*s", ae->len, ae->buf);
 2794|  2.72k|      if (ae_ != NULL && strstr(ae_, "gzip") != NULL) {
  ------------------
  |  Branch (2794:11): [True: 2.14k, False: 575]
  |  Branch (2794:26): [True: 328, False: 1.82k]
  ------------------
 2795|    328|        mg_snprintf(tmp, sizeof(tmp), "%s.gz", path);
 2796|    328|        fd = mg_fs_open(fs, tmp, MG_FS_READ);
 2797|    328|        if (fd != NULL) gzip = true, path = tmp;
  ------------------
  |  Branch (2797:13): [True: 0, False: 328]
  ------------------
 2798|    328|      }
 2799|  2.72k|      free(ae_);
 2800|  2.72k|    }
 2801|       |    // No luck opening .gz? Open what we've told to open
 2802|  52.2k|    if (fd == NULL) fd = mg_fs_open(fs, path, MG_FS_READ);
  ------------------
  |  Branch (2802:9): [True: 52.2k, False: 0]
  ------------------
 2803|  52.2k|  }
 2804|       |
 2805|       |  // Failed to open, and page404 is configured? Open it, then
 2806|  52.2k|  if (fd == NULL && opts->page404 != NULL) {
  ------------------
  |  Branch (2806:7): [True: 52.2k, False: 0]
  |  Branch (2806:21): [True: 0, False: 52.2k]
  ------------------
 2807|      0|    fd = mg_fs_open(fs, opts->page404, MG_FS_READ);
 2808|      0|    path = opts->page404;
 2809|      0|    mime = guess_content_type(mg_str(path), opts->mime_types);
  ------------------
  |  |  859|      0|#define mg_str(s) mg_str_s(s)
  ------------------
 2810|      0|  }
 2811|       |
 2812|  52.2k|  if (fd == NULL || fs->st(path, &size, &mtime) == 0) {
  ------------------
  |  Branch (2812:7): [True: 52.2k, False: 0]
  |  Branch (2812:21): [True: 0, False: 0]
  ------------------
 2813|  52.2k|    mg_http_reply(c, 404, opts->extra_headers, "Not found\n");
 2814|  52.2k|    mg_fs_close(fd);
 2815|       |    // NOTE: mg_http_etag() call should go first!
 2816|  52.2k|  } else if (mg_http_etag(etag, sizeof(etag), size, mtime) != NULL &&
  ------------------
  |  Branch (2816:14): [True: 0, False: 0]
  ------------------
 2817|      0|             (inm = mg_http_get_header(hm, "If-None-Match")) != NULL &&
  ------------------
  |  Branch (2817:14): [True: 0, False: 0]
  ------------------
 2818|      0|             mg_strcasecmp(*inm, mg_str(etag)) == 0) {
  ------------------
  |  |  859|      0|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (2818:14): [True: 0, False: 0]
  ------------------
 2819|      0|    mg_fs_close(fd);
 2820|      0|    mg_http_reply(c, 304, opts->extra_headers, "");
 2821|      0|  } else {
 2822|      0|    int n, status = 200;
 2823|      0|    char range[100];
 2824|      0|    size_t r1 = 0, r2 = 0, cl = size;
 2825|       |
 2826|       |    // Handle Range header
 2827|      0|    struct mg_str *rh = mg_http_get_header(hm, "Range");
 2828|      0|    range[0] = '\0';
 2829|      0|    if (rh != NULL && (n = getrange(rh, &r1, &r2)) > 0) {
  ------------------
  |  Branch (2829:9): [True: 0, False: 0]
  |  Branch (2829:23): [True: 0, False: 0]
  ------------------
 2830|       |      // If range is specified like "400-", set second limit to content len
 2831|      0|      if (n == 1) r2 = cl - 1;
  ------------------
  |  Branch (2831:11): [True: 0, False: 0]
  ------------------
 2832|      0|      if (r1 > r2 || r2 >= cl) {
  ------------------
  |  Branch (2832:11): [True: 0, False: 0]
  |  Branch (2832:22): [True: 0, False: 0]
  ------------------
 2833|      0|        status = 416;
 2834|      0|        cl = 0;
 2835|      0|        mg_snprintf(range, sizeof(range), "Content-Range: bytes */%lld\r\n",
 2836|      0|                    (int64_t) size);
 2837|      0|      } else {
 2838|      0|        status = 206;
 2839|      0|        cl = r2 - r1 + 1;
 2840|      0|        mg_snprintf(range, sizeof(range),
 2841|      0|                    "Content-Range: bytes %llu-%llu/%llu\r\n", (uint64_t) r1,
 2842|      0|                    (uint64_t) (r1 + cl - 1), (uint64_t) size);
 2843|      0|        fs->sk(fd->fd, r1);
 2844|      0|      }
 2845|      0|    }
 2846|      0|    mg_printf(c,
 2847|      0|              "HTTP/1.1 %d %s\r\n"
 2848|      0|              "Content-Type: %.*s\r\n"
 2849|      0|              "Etag: %s\r\n"
 2850|      0|              "Content-Length: %llu\r\n"
 2851|      0|              "%s%s%s\r\n",
 2852|      0|              status, mg_http_status_code_str(status), (int) mime.len, mime.buf,
 2853|      0|              etag, (uint64_t) cl, gzip ? "Content-Encoding: gzip\r\n" : "",
  ------------------
  |  Branch (2853:36): [True: 0, False: 0]
  ------------------
 2854|      0|              range, opts->extra_headers ? opts->extra_headers : "");
  ------------------
  |  Branch (2854:22): [True: 0, False: 0]
  ------------------
 2855|      0|    if (mg_strcasecmp(hm->method, mg_str("HEAD")) == 0) {
  ------------------
  |  |  859|      0|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (2855:9): [True: 0, False: 0]
  ------------------
 2856|      0|      c->is_resp = 0;
 2857|      0|      mg_fs_close(fd);
 2858|      0|    } else {
 2859|       |      // Track to-be-sent content length at the end of c->data, aligned
 2860|      0|      size_t *clp = (size_t *) &c->data[(sizeof(c->data) - sizeof(size_t)) /
 2861|      0|                                        sizeof(size_t) * sizeof(size_t)];
 2862|      0|      c->pfn = static_cb;
 2863|      0|      c->pfn_data = fd;
 2864|      0|      *clp = cl;
 2865|      0|    }
 2866|      0|  }
 2867|  52.2k|}
mg_http_serve_dir:
 3062|   395k|                       const struct mg_http_serve_opts *opts) {
 3063|   395k|  char path[MG_PATH_MAX];
 3064|   395k|  const char *sp = opts->ssi_pattern;
 3065|   395k|  int flags = uri_to_path(c, hm, opts, path, sizeof(path));
 3066|   395k|  if (flags < 0) {
  ------------------
  |  Branch (3066:7): [True: 26.0k, False: 369k]
  ------------------
 3067|       |    // Do nothing: the response has already been sent by uri_to_path()
 3068|   369k|  } else if (flags & MG_FS_DIR) {
  ------------------
  |  Branch (3068:14): [True: 316k, False: 52.2k]
  ------------------
 3069|   316k|#if MG_ENABLE_DIRLIST
 3070|   316k|    listdir(c, hm, opts, path);
 3071|       |#else
 3072|       |    mg_http_reply(c, 403, "", "Forbidden\n");
 3073|       |#endif
 3074|   316k|  } else if (flags && sp != NULL && mg_match(mg_str(path), mg_str(sp), NULL)) {
  ------------------
  |  |  859|      0|#define mg_str(s) mg_str_s(s)
  ------------------
                } else if (flags && sp != NULL && mg_match(mg_str(path), mg_str(sp), NULL)) {
  ------------------
  |  |  859|      0|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (3074:14): [True: 0, False: 52.2k]
  |  Branch (3074:23): [True: 0, False: 0]
  |  Branch (3074:37): [True: 0, False: 0]
  ------------------
 3075|      0|    mg_http_serve_ssi(c, opts->root_dir, path);
 3076|  52.2k|  } else {
 3077|  52.2k|    mg_http_serve_file(c, hm, path, opts);
 3078|  52.2k|  }
 3079|   395k|}
mg_url_encode:
 3086|  4.12M|size_t mg_url_encode(const char *s, size_t sl, char *buf, size_t len) {
 3087|  4.12M|  size_t i, n = 0;
 3088|  43.4M|  for (i = 0; i < sl; i++) {
  ------------------
  |  Branch (3088:15): [True: 39.2M, False: 4.12M]
  ------------------
 3089|  39.2M|    int c = *(unsigned char *) &s[i];
 3090|  39.2M|    if (n + 4 >= len) return 0;
  ------------------
  |  Branch (3090:9): [True: 0, False: 39.2M]
  ------------------
 3091|  39.2M|    if (mg_is_url_safe(c)) {
  ------------------
  |  Branch (3091:9): [True: 39.2M, False: 0]
  ------------------
 3092|  39.2M|      buf[n++] = s[i];
 3093|  39.2M|    } else {
 3094|      0|      mg_snprintf(&buf[n], 4, "%%%M", mg_print_hex, 1, &s[i]);
 3095|      0|      n += 3;
 3096|      0|    }
 3097|  39.2M|  }
 3098|  4.12M|  if (len > 0 && n < len - 1) buf[n] = '\0';  // Null-terminate the destination
  ------------------
  |  Branch (3098:7): [True: 4.12M, False: 0]
  |  Branch (3098:18): [True: 4.12M, False: 0]
  ------------------
 3099|  4.12M|  if (len > 0) buf[len - 1] = '\0';           // Always.
  ------------------
  |  Branch (3099:7): [True: 4.12M, False: 0]
  ------------------
 3100|  4.12M|  return n;
 3101|  4.12M|}
mg_http_status:
 3192|  1.08k|int mg_http_status(const struct mg_http_message *hm) {
 3193|  1.08k|  return atoi(hm->uri.buf);
 3194|  1.08k|}
mg_http_connect:
 3346|  5.02k|                                      mg_event_handler_t fn, void *fn_data) {
 3347|  5.02k|  struct mg_connection *c = mg_connect(mgr, url, fn, fn_data);
 3348|  5.02k|  if (c != NULL) c->pfn = http_cb;
  ------------------
  |  Branch (3348:7): [True: 5.02k, False: 0]
  ------------------
 3349|  5.02k|  return c;
 3350|  5.02k|}
mg_iobuf_resize:
 3371|  58.6k|int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) {
 3372|  58.6k|  int ok = 1;
 3373|  58.6k|  new_size = roundup(new_size, io->align);
 3374|  58.6k|  if (new_size == 0) {
  ------------------
  |  Branch (3374:7): [True: 20.1k, False: 38.5k]
  ------------------
 3375|  20.1k|    mg_bzero(io->buf, io->size);
 3376|  20.1k|    free(io->buf);
 3377|  20.1k|    io->buf = NULL;
 3378|  20.1k|    io->len = io->size = 0;
 3379|  38.5k|  } else if (new_size != io->size) {
  ------------------
  |  Branch (3379:14): [True: 38.5k, False: 0]
  ------------------
 3380|       |    // NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the
 3381|       |    // porting to some obscure platforms like FreeRTOS
 3382|  38.5k|    void *p = calloc(1, new_size);
 3383|  38.5k|    if (p != NULL) {
  ------------------
  |  Branch (3383:9): [True: 38.5k, False: 0]
  ------------------
 3384|  38.5k|      size_t len = new_size < io->len ? new_size : io->len;
  ------------------
  |  Branch (3384:20): [True: 0, False: 38.5k]
  ------------------
 3385|  38.5k|      if (len > 0 && io->buf != NULL) memmove(p, io->buf, len);
  ------------------
  |  Branch (3385:11): [True: 29.2k, False: 9.26k]
  |  Branch (3385:22): [True: 29.2k, False: 0]
  ------------------
 3386|  38.5k|      mg_bzero(io->buf, io->size);
 3387|  38.5k|      free(io->buf);
 3388|  38.5k|      io->buf = (unsigned char *) p;
 3389|  38.5k|      io->size = new_size;
 3390|  38.5k|    } else {
 3391|      0|      ok = 0;
 3392|      0|      MG_ERROR(("%lld->%lld", (uint64_t) io->size, (uint64_t) new_size));
  ------------------
  |  |  960|      0|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3393|      0|    }
 3394|  38.5k|  }
 3395|  58.6k|  return ok;
 3396|  58.6k|}
mg_iobuf_add:
 3406|  5.02k|                    size_t len) {
 3407|  5.02k|  size_t new_size = roundup(io->len + len, io->align);
 3408|  5.02k|  mg_iobuf_resize(io, new_size);      // Attempt to resize
 3409|  5.02k|  if (new_size != io->size) len = 0;  // Resize failure, append nothing
  ------------------
  |  Branch (3409:7): [True: 0, False: 5.02k]
  ------------------
 3410|  5.02k|  if (ofs < io->len) memmove(io->buf + ofs + len, io->buf + ofs, io->len - ofs);
  ------------------
  |  Branch (3410:7): [True: 0, False: 5.02k]
  ------------------
 3411|  5.02k|  if (buf != NULL) memmove(io->buf + ofs, buf, len);
  ------------------
  |  Branch (3411:7): [True: 5.02k, False: 0]
  ------------------
 3412|  5.02k|  if (ofs > io->len) io->len += ofs - io->len;
  ------------------
  |  Branch (3412:7): [True: 0, False: 5.02k]
  ------------------
 3413|  5.02k|  io->len += len;
 3414|  5.02k|  return len;
 3415|  5.02k|}
mg_iobuf_del:
 3417|  1.86k|size_t mg_iobuf_del(struct mg_iobuf *io, size_t ofs, size_t len) {
 3418|  1.86k|  if (ofs > io->len) ofs = io->len;
  ------------------
  |  Branch (3418:7): [True: 0, False: 1.86k]
  ------------------
 3419|  1.86k|  if (ofs + len > io->len) len = io->len - ofs;
  ------------------
  |  Branch (3419:7): [True: 33, False: 1.83k]
  ------------------
 3420|  1.86k|  if (io->buf) memmove(io->buf + ofs, io->buf + ofs + len, io->len - ofs - len);
  ------------------
  |  Branch (3420:7): [True: 1.86k, False: 0]
  ------------------
 3421|  1.86k|  if (io->buf) mg_bzero(io->buf + io->len - len, len);
  ------------------
  |  Branch (3421:7): [True: 1.86k, False: 0]
  ------------------
 3422|  1.86k|  io->len -= len;
 3423|  1.86k|  return len;
 3424|  1.86k|}
mg_iobuf_free:
 3426|  20.1k|void mg_iobuf_free(struct mg_iobuf *io) {
 3427|  20.1k|  mg_iobuf_resize(io, 0);
 3428|  20.1k|}
mg_json_get:
 3558|  15.0k|int mg_json_get(struct mg_str json, const char *path, int *toklen) {
 3559|  15.0k|  const char *s = json.buf;
 3560|  15.0k|  int len = (int) json.len;
 3561|  15.0k|  enum { S_VALUE, S_KEY, S_COLON, S_COMMA_OR_EOO } expecting = S_VALUE;
 3562|  15.0k|  unsigned char nesting[MG_JSON_MAX_DEPTH];
 3563|  15.0k|  int i = 0;             // Current offset in `s`
 3564|  15.0k|  int j = 0;             // Offset in `s` we're looking for (return value)
 3565|  15.0k|  int depth = 0;         // Current depth (nesting level)
 3566|  15.0k|  int ed = 0;            // Expected depth
 3567|  15.0k|  int pos = 1;           // Current position in `path`
 3568|  15.0k|  int ci = -1, ei = -1;  // Current and expected index in array
 3569|       |
 3570|  15.0k|  if (toklen) *toklen = 0;
  ------------------
  |  Branch (3570:7): [True: 15.0k, False: 0]
  ------------------
 3571|  15.0k|  if (path[0] != '$') return MG_JSON_INVALID;
  ------------------
  |  Branch (3571:7): [True: 0, False: 15.0k]
  ------------------
 3572|       |
 3573|  15.0k|#define MG_CHECKRET(x)                                  \
 3574|  15.0k|  do {                                                  \
 3575|  15.0k|    if (depth == ed && path[pos] == '\0' && ci == ei) { \
 3576|  15.0k|      if (toklen) *toklen = i - j + 1;                  \
 3577|  15.0k|      return j;                                         \
 3578|  15.0k|    }                                                   \
 3579|  15.0k|  } while (0)
 3580|       |
 3581|       |// In the ascii table, the distance between `[` and `]` is 2.
 3582|       |// Ditto for `{` and `}`. Hence +2 in the code below.
 3583|  15.0k|#define MG_EOO(x)                                            \
 3584|  15.0k|  do {                                                       \
 3585|  15.0k|    if (depth == ed && ci != ei) return MG_JSON_NOT_FOUND;   \
 3586|  15.0k|    if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
 3587|  15.0k|    depth--;                                                 \
 3588|  15.0k|    MG_CHECKRET(x);                                          \
 3589|  15.0k|  } while (0)
 3590|       |
 3591|  1.20M|  for (i = 0; i < len; i++) {
  ------------------
  |  Branch (3591:15): [True: 1.20M, False: 1.21k]
  ------------------
 3592|  1.20M|    unsigned char c = ((unsigned char *) s)[i];
 3593|  1.20M|    if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
  ------------------
  |  Branch (3593:9): [True: 2.33k, False: 1.20M]
  |  Branch (3593:21): [True: 397, False: 1.20M]
  |  Branch (3593:34): [True: 1.15k, False: 1.20M]
  |  Branch (3593:47): [True: 590, False: 1.20M]
  ------------------
 3594|  1.20M|    switch (expecting) {
  ------------------
  |  Branch (3594:13): [True: 0, False: 1.20M]
  ------------------
 3595|   575k|      case S_VALUE:
  ------------------
  |  Branch (3595:7): [True: 575k, False: 625k]
  ------------------
 3596|       |        // p("V %s [%.*s] %d %d %d %d\n", path, pos, path, depth, ed, ci, ei);
 3597|   575k|        if (depth == ed) j = i;
  ------------------
  |  Branch (3597:13): [True: 18.9k, False: 556k]
  ------------------
 3598|   575k|        if (c == '{') {
  ------------------
  |  Branch (3598:13): [True: 19.6k, False: 555k]
  ------------------
 3599|  19.6k|          if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
  ------------------
  |  Branch (3599:15): [True: 8, False: 19.6k]
  ------------------
 3600|  19.6k|          if (depth == ed && path[pos] == '.' && ci == ei) {
  ------------------
  |  Branch (3600:15): [True: 1.52k, False: 18.1k]
  |  Branch (3600:30): [True: 336, False: 1.18k]
  |  Branch (3600:50): [True: 336, False: 0]
  ------------------
 3601|       |            // If we start the object, reset array indices
 3602|    336|            ed++, pos++, ci = ei = -1;
 3603|    336|          }
 3604|  19.6k|          nesting[depth++] = c;
 3605|  19.6k|          expecting = S_KEY;
 3606|  19.6k|          break;
 3607|   555k|        } else if (c == '[') {
  ------------------
  |  Branch (3607:20): [True: 13.5k, False: 542k]
  ------------------
 3608|  13.5k|          if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
  ------------------
  |  Branch (3608:15): [True: 11, False: 13.5k]
  ------------------
 3609|  13.5k|          if (depth == ed && path[pos] == '[' && ei == ci) {
  ------------------
  |  Branch (3609:15): [True: 2.81k, False: 10.7k]
  |  Branch (3609:30): [True: 374, False: 2.44k]
  |  Branch (3609:50): [True: 374, False: 0]
  ------------------
 3610|    374|            ed++, pos++, ci = 0;
 3611|    748|            for (ei = 0; path[pos] != ']' && path[pos] != '\0'; pos++) {
  ------------------
  |  Branch (3611:26): [True: 374, False: 374]
  |  Branch (3611:46): [True: 374, False: 0]
  ------------------
 3612|    374|              ei *= 10;
 3613|    374|              ei += path[pos] - '0';
 3614|    374|            }
 3615|    374|            if (path[pos] != 0) pos++;
  ------------------
  |  Branch (3615:17): [True: 374, False: 0]
  ------------------
 3616|    374|          }
 3617|  13.5k|          nesting[depth++] = c;
 3618|  13.5k|          break;
 3619|   542k|        } else if (c == ']' && depth > 0) {  // Empty array
  ------------------
  |  Branch (3619:20): [True: 5.27k, False: 536k]
  |  Branch (3619:32): [True: 5.05k, False: 219]
  ------------------
 3620|  5.05k|          MG_EOO(']');
  ------------------
  |  | 3584|  5.05k|  do {                                                       \
  |  | 3585|  5.05k|    if (depth == ed && ci != ei) return MG_JSON_NOT_FOUND;   \
  |  |  ------------------
  |  |  |  Branch (3585:9): [True: 3, False: 5.05k]
  |  |  |  Branch (3585:24): [True: 0, False: 3]
  |  |  ------------------
  |  | 3586|  5.05k|    if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
  |  |  ------------------
  |  |  |  Branch (3586:9): [True: 5, False: 5.05k]
  |  |  ------------------
  |  | 3587|  5.05k|    depth--;                                                 \
  |  | 3588|  5.05k|    MG_CHECKRET(x);                                          \
  |  |  ------------------
  |  |  |  | 3574|  5.05k|  do {                                                  \
  |  |  |  | 3575|  5.05k|    if (depth == ed && path[pos] == '\0' && ci == ei) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (3575:9): [True: 883, False: 4.16k]
  |  |  |  |  |  Branch (3575:24): [True: 28, False: 855]
  |  |  |  |  |  Branch (3575:45): [True: 28, False: 0]
  |  |  |  |  ------------------
  |  |  |  | 3576|     28|      if (toklen) *toklen = i - j + 1;                  \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (3576:11): [True: 28, False: 0]
  |  |  |  |  ------------------
  |  |  |  | 3577|     28|      return j;                                         \
  |  |  |  | 3578|     28|    }                                                   \
  |  |  |  | 3579|  5.05k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (3579:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 3589|  5.05k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (3589:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3621|   536k|        } else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) {
  ------------------
  |  Branch (3621:20): [True: 2.36k, False: 534k]
  |  Branch (3621:32): [True: 2.34k, False: 26]
  |  Branch (3621:47): [True: 1.86k, False: 476]
  ------------------
 3622|  1.86k|          i += 3;
 3623|   535k|        } else if (c == 'n' && i + 3 < len && memcmp(&s[i], "null", 4) == 0) {
  ------------------
  |  Branch (3623:20): [True: 28.7k, False: 506k]
  |  Branch (3623:32): [True: 28.7k, False: 30]
  |  Branch (3623:47): [True: 28.5k, False: 135]
  ------------------
 3624|  28.5k|          i += 3;
 3625|   506k|        } else if (c == 'f' && i + 4 < len && memcmp(&s[i], "false", 5) == 0) {
  ------------------
  |  Branch (3625:20): [True: 10.1k, False: 496k]
  |  Branch (3625:32): [True: 10.1k, False: 35]
  |  Branch (3625:47): [True: 9.96k, False: 152]
  ------------------
 3626|  9.96k|          i += 4;
 3627|   496k|        } else if (c == '-' || ((c >= '0' && c <= '9'))) {
  ------------------
  |  Branch (3627:20): [True: 226k, False: 270k]
  |  Branch (3627:34): [True: 265k, False: 5.24k]
  |  Branch (3627:46): [True: 258k, False: 7.09k]
  ------------------
 3628|   484k|          int numlen = 0;
 3629|   484k|          mg_atod(&s[i], len - i, &numlen);
 3630|   484k|          i += numlen - 1;
 3631|   484k|        } else if (c == '"') {
  ------------------
  |  Branch (3631:20): [True: 2.12k, False: 10.2k]
  ------------------
 3632|  2.12k|          int n = mg_pass_string(&s[i + 1], len - i - 1);
 3633|  2.12k|          if (n < 0) return n;
  ------------------
  |  Branch (3633:15): [True: 336, False: 1.79k]
  ------------------
 3634|  1.79k|          i += n + 1;
 3635|  10.2k|        } else {
 3636|  10.2k|          return MG_JSON_INVALID;
 3637|  10.2k|        }
 3638|   531k|        MG_CHECKRET('V');
  ------------------
  |  | 3574|   531k|  do {                                                  \
  |  | 3575|   531k|    if (depth == ed && path[pos] == '\0' && ci == ei) { \
  |  |  ------------------
  |  |  |  Branch (3575:9): [True: 5.10k, False: 526k]
  |  |  |  Branch (3575:24): [True: 968, False: 4.13k]
  |  |  |  Branch (3575:45): [True: 968, False: 0]
  |  |  ------------------
  |  | 3576|    968|      if (toklen) *toklen = i - j + 1;                  \
  |  |  ------------------
  |  |  |  Branch (3576:11): [True: 968, False: 0]
  |  |  ------------------
  |  | 3577|    968|      return j;                                         \
  |  | 3578|    968|    }                                                   \
  |  | 3579|   531k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (3579:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3639|   530k|        if (depth == ed && ei >= 0) ci++;
  ------------------
  |  Branch (3639:13): [True: 4.13k, False: 526k]
  |  Branch (3639:28): [True: 0, False: 4.13k]
  ------------------
 3640|   530k|        expecting = S_COMMA_OR_EOO;
 3641|   530k|        break;
 3642|       |
 3643|  45.2k|      case S_KEY:
  ------------------
  |  Branch (3643:7): [True: 45.2k, False: 1.15M]
  ------------------
 3644|  45.2k|        if (c == '"') {
  ------------------
  |  Branch (3644:13): [True: 28.0k, False: 17.2k]
  ------------------
 3645|  28.0k|          int n = mg_pass_string(&s[i + 1], len - i - 1);
 3646|  28.0k|          if (n < 0) return n;
  ------------------
  |  Branch (3646:15): [True: 297, False: 27.7k]
  ------------------
 3647|  27.7k|          if (i + 1 + n >= len) return MG_JSON_NOT_FOUND;
  ------------------
  |  Branch (3647:15): [True: 0, False: 27.7k]
  ------------------
 3648|  27.7k|          if (depth < ed) return MG_JSON_NOT_FOUND;
  ------------------
  |  Branch (3648:15): [True: 1, False: 27.7k]
  ------------------
 3649|  27.7k|          if (depth == ed && path[pos - 1] != '.') return MG_JSON_NOT_FOUND;
  ------------------
  |  Branch (3649:15): [True: 3.67k, False: 24.0k]
  |  Branch (3649:30): [True: 1, False: 3.66k]
  ------------------
 3650|       |          // printf("K %s [%.*s] [%.*s] %d %d %d %d %d\n", path, pos, path, n,
 3651|       |          //        &s[i + 1], n, depth, ed, ci, ei);
 3652|       |          //  NOTE(cpq): in the check sequence below is important.
 3653|       |          //  strncmp() must go first: it fails fast if the remaining length
 3654|       |          //  of the path is smaller than `n`.
 3655|  27.7k|          if (depth == ed && path[pos - 1] == '.' &&
  ------------------
  |  Branch (3655:15): [True: 3.66k, False: 24.0k]
  |  Branch (3655:30): [True: 3.66k, False: 0]
  ------------------
 3656|  27.7k|              strncmp(&s[i + 1], &path[pos], (size_t) n) == 0 &&
  ------------------
  |  Branch (3656:15): [True: 2.31k, False: 1.35k]
  ------------------
 3657|  27.7k|              (path[pos + n] == '\0' || path[pos + n] == '.' ||
  ------------------
  |  Branch (3657:16): [True: 5, False: 2.30k]
  |  Branch (3657:41): [True: 6, False: 2.30k]
  ------------------
 3658|  2.31k|               path[pos + n] == '[')) {
  ------------------
  |  Branch (3658:16): [True: 0, False: 2.30k]
  ------------------
 3659|     11|            pos += n;
 3660|     11|          }
 3661|  27.7k|          i += n + 1;
 3662|  27.7k|          expecting = S_COLON;
 3663|  27.7k|        } else if (c == '}') {  // Empty object
  ------------------
  |  Branch (3663:20): [True: 17.0k, False: 185]
  ------------------
 3664|  17.0k|          MG_EOO('}');
  ------------------
  |  | 3584|  17.0k|  do {                                                       \
  |  | 3585|  17.0k|    if (depth == ed && ci != ei) return MG_JSON_NOT_FOUND;   \
  |  |  ------------------
  |  |  |  Branch (3585:9): [True: 13, False: 17.0k]
  |  |  |  Branch (3585:24): [True: 0, False: 13]
  |  |  ------------------
  |  | 3586|  17.0k|    if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
  |  |  ------------------
  |  |  |  Branch (3586:9): [True: 0, False: 17.0k]
  |  |  ------------------
  |  | 3587|  17.0k|    depth--;                                                 \
  |  | 3588|  17.0k|    MG_CHECKRET(x);                                          \
  |  |  ------------------
  |  |  |  | 3574|  17.0k|  do {                                                  \
  |  |  |  | 3575|  17.0k|    if (depth == ed && path[pos] == '\0' && ci == ei) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (3575:9): [True: 520, False: 16.5k]
  |  |  |  |  |  Branch (3575:24): [True: 18, False: 502]
  |  |  |  |  |  Branch (3575:45): [True: 18, False: 0]
  |  |  |  |  ------------------
  |  |  |  | 3576|     18|      if (toklen) *toklen = i - j + 1;                  \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (3576:11): [True: 18, False: 0]
  |  |  |  |  ------------------
  |  |  |  | 3577|     18|      return j;                                         \
  |  |  |  | 3578|     18|    }                                                   \
  |  |  |  | 3579|  17.0k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (3579:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 3589|  17.0k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (3589:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3665|  17.0k|          expecting = S_COMMA_OR_EOO;
 3666|  17.0k|          if (depth == ed && ei >= 0) ci++;
  ------------------
  |  Branch (3666:15): [True: 502, False: 16.5k]
  |  Branch (3666:30): [True: 0, False: 502]
  ------------------
 3667|  17.0k|        } else {
 3668|    185|          return MG_JSON_INVALID;
 3669|    185|        }
 3670|  44.7k|        break;
 3671|       |
 3672|  44.7k|      case S_COLON:
  ------------------
  |  Branch (3672:7): [True: 27.5k, False: 1.17M]
  ------------------
 3673|  27.5k|        if (c == ':') {
  ------------------
  |  Branch (3673:13): [True: 27.4k, False: 107]
  ------------------
 3674|  27.4k|          expecting = S_VALUE;
 3675|  27.4k|        } else {
 3676|    107|          return MG_JSON_INVALID;
 3677|    107|        }
 3678|  27.4k|        break;
 3679|       |
 3680|   552k|      case S_COMMA_OR_EOO:
  ------------------
  |  Branch (3680:7): [True: 552k, False: 647k]
  ------------------
 3681|   552k|        if (depth <= 0) {
  ------------------
  |  Branch (3681:13): [True: 1.41k, False: 551k]
  ------------------
 3682|  1.41k|          return MG_JSON_INVALID;
 3683|   551k|        } else if (c == ',') {
  ------------------
  |  Branch (3683:20): [True: 545k, False: 6.15k]
  ------------------
 3684|   545k|          expecting = (nesting[depth - 1] == '{') ? S_KEY : S_VALUE;
  ------------------
  |  Branch (3684:23): [True: 25.6k, False: 519k]
  ------------------
 3685|   545k|        } else if (c == ']' || c == '}') {
  ------------------
  |  Branch (3685:20): [True: 4.83k, False: 1.31k]
  |  Branch (3685:32): [True: 1.10k, False: 206]
  ------------------
 3686|  5.94k|          if (depth == ed && c == '}' && path[pos - 1] == '.')
  ------------------
  |  Branch (3686:15): [True: 9, False: 5.93k]
  |  Branch (3686:30): [True: 8, False: 1]
  |  Branch (3686:42): [True: 7, False: 1]
  ------------------
 3687|      7|            return MG_JSON_NOT_FOUND;
 3688|  5.93k|          if (depth == ed && c == ']' && path[pos - 1] == ',')
  ------------------
  |  Branch (3688:15): [True: 2, False: 5.93k]
  |  Branch (3688:30): [True: 1, False: 1]
  |  Branch (3688:42): [True: 0, False: 1]
  ------------------
 3689|      0|            return MG_JSON_NOT_FOUND;
 3690|  5.93k|          MG_EOO('O');
  ------------------
  |  | 3584|  5.93k|  do {                                                       \
  |  | 3585|  5.93k|    if (depth == ed && ci != ei) return MG_JSON_NOT_FOUND;   \
  |  |  ------------------
  |  |  |  Branch (3585:9): [True: 2, False: 5.93k]
  |  |  |  Branch (3585:24): [True: 0, False: 2]
  |  |  ------------------
  |  | 3586|  5.93k|    if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
  |  |  ------------------
  |  |  |  Branch (3586:9): [True: 13, False: 5.92k]
  |  |  ------------------
  |  | 3587|  5.93k|    depth--;                                                 \
  |  | 3588|  5.92k|    MG_CHECKRET(x);                                          \
  |  |  ------------------
  |  |  |  | 3574|  5.92k|  do {                                                  \
  |  |  |  | 3575|  5.92k|    if (depth == ed && path[pos] == '\0' && ci == ei) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (3575:9): [True: 679, False: 5.24k]
  |  |  |  |  |  Branch (3575:24): [True: 52, False: 627]
  |  |  |  |  |  Branch (3575:45): [True: 52, False: 0]
  |  |  |  |  ------------------
  |  |  |  | 3576|     52|      if (toklen) *toklen = i - j + 1;                  \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (3576:11): [True: 52, False: 0]
  |  |  |  |  ------------------
  |  |  |  | 3577|     52|      return j;                                         \
  |  |  |  | 3578|     52|    }                                                   \
  |  |  |  | 3579|  5.92k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (3579:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  | 3589|  5.92k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (3589:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3691|  5.87k|          if (depth == ed && ei >= 0) ci++;
  ------------------
  |  Branch (3691:15): [True: 627, False: 5.24k]
  |  Branch (3691:30): [True: 0, False: 627]
  ------------------
 3692|  5.87k|        } else {
 3693|    206|          return MG_JSON_INVALID;
 3694|    206|        }
 3695|   550k|        break;
 3696|  1.20M|    }
 3697|  1.20M|  }
 3698|  1.21k|  return MG_JSON_NOT_FOUND;
 3699|  15.0k|}
mg_hexdump:
 3855|  1.68k|void mg_hexdump(const void *buf, size_t len) {
 3856|  1.68k|  const unsigned char *p = (const unsigned char *) buf;
 3857|  1.68k|  unsigned char ascii[16], alen = 0;
 3858|  1.68k|  size_t i;
 3859|  22.5k|  for (i = 0; i < len; i++) {
  ------------------
  |  Branch (3859:15): [True: 20.8k, False: 1.68k]
  ------------------
 3860|  20.8k|    if ((i % 16) == 0) {
  ------------------
  |  Branch (3860:9): [True: 1.68k, False: 19.1k]
  ------------------
 3861|       |      // Print buffered ascii chars
 3862|  1.68k|      if (i > 0) logs("  ", 2), logs((char *) ascii, 16), logc('\n'), alen = 0;
  ------------------
  |  Branch (3862:11): [True: 0, False: 1.68k]
  ------------------
 3863|       |      // Print hex address, then \t
 3864|  1.68k|      logc(nibble((i >> 12) & 15)), logc(nibble((i >> 8) & 15)),
 3865|  1.68k|          logc(nibble((i >> 4) & 15)), logc('0'), logs("   ", 3);
 3866|  1.68k|    }
 3867|  20.8k|    logc(nibble(p[i] >> 4)), logc(nibble(p[i] & 15));  // Two nibbles, e.g. c5
 3868|  20.8k|    logc(' ');                                         // Space after hex number
 3869|  20.8k|    ascii[alen++] = ISPRINT(p[i]) ? p[i] : '.';        // Add to the ascii buf
  ------------------
  |  | 3854|  20.8k|#define ISPRINT(x) ((x) >= ' ' && (x) <= '~')
  |  |  ------------------
  |  |  |  Branch (3854:21): [True: 14.4k, False: 6.38k]
  |  |  |  Branch (3854:35): [True: 10.2k, False: 4.20k]
  |  |  ------------------
  ------------------
 3870|  20.8k|  }
 3871|  7.74k|  while (alen < 16) logs("   ", 3), ascii[alen++] = ' ';
  ------------------
  |  Branch (3871:10): [True: 6.06k, False: 1.68k]
  ------------------
 3872|  1.68k|  logs("  ", 2), logs((char *) ascii, 16), logc('\n');
 3873|  1.68k|}
mg_mqtt_parse:
 4448|  20.1k|                  struct mg_mqtt_message *m) {
 4449|  20.1k|  uint8_t lc = 0, *p, *end;
 4450|  20.1k|  uint32_t n = 0, len_len = 0;
 4451|       |
 4452|  20.1k|  memset(m, 0, sizeof(*m));
 4453|  20.1k|  m->dgram.buf = (char *) buf;
 4454|  20.1k|  if (len < 2) return MQTT_INCOMPLETE;
  ------------------
  |  Branch (4454:7): [True: 10.2k, False: 9.84k]
  ------------------
 4455|  9.84k|  m->cmd = (uint8_t) (buf[0] >> 4);
 4456|  9.84k|  m->qos = (buf[0] >> 1) & 3;
 4457|       |
 4458|  9.84k|  n = len_len = 0;
 4459|  9.84k|  p = (uint8_t *) buf + 1;
 4460|  11.6k|  while ((size_t) (p - buf) < len) {
  ------------------
  |  Branch (4460:10): [True: 11.5k, False: 108]
  ------------------
 4461|  11.5k|    lc = *((uint8_t *) p++);
 4462|  11.5k|    n += (uint32_t) ((lc & 0x7f) << 7 * len_len);
 4463|  11.5k|    len_len++;
 4464|  11.5k|    if (!(lc & 0x80)) break;
  ------------------
  |  Branch (4464:9): [True: 9.48k, False: 2.01k]
  ------------------
 4465|  2.01k|    if (len_len >= 4) return MQTT_MALFORMED;
  ------------------
  |  Branch (4465:9): [True: 244, False: 1.76k]
  ------------------
 4466|  2.01k|  }
 4467|  9.59k|  end = p + n;
 4468|  9.59k|  if ((lc & 0x80) || (end > buf + len)) return MQTT_INCOMPLETE;
  ------------------
  |  Branch (4468:7): [True: 108, False: 9.48k]
  |  Branch (4468:22): [True: 4.71k, False: 4.77k]
  ------------------
 4469|  4.77k|  m->dgram.len = (size_t) (end - buf);
 4470|       |
 4471|  4.77k|  switch (m->cmd) {
 4472|  1.41k|    case MQTT_CMD_CONNACK:
  ------------------
  |  | 2384|  1.41k|#define MQTT_CMD_CONNACK 2
  ------------------
  |  Branch (4472:5): [True: 1.41k, False: 3.35k]
  ------------------
 4473|  1.41k|      if (end - p < 2) return MQTT_MALFORMED;
  ------------------
  |  Branch (4473:11): [True: 36, False: 1.37k]
  ------------------
 4474|  1.37k|      m->ack = p[1];
 4475|  1.37k|      break;
 4476|    390|    case MQTT_CMD_PUBACK:
  ------------------
  |  | 2386|    390|#define MQTT_CMD_PUBACK 4
  ------------------
  |  Branch (4476:5): [True: 390, False: 4.38k]
  ------------------
 4477|  1.00k|    case MQTT_CMD_PUBREC:
  ------------------
  |  | 2387|  1.00k|#define MQTT_CMD_PUBREC 5
  ------------------
  |  Branch (4477:5): [True: 616, False: 4.15k]
  ------------------
 4478|  1.38k|    case MQTT_CMD_PUBREL:
  ------------------
  |  | 2388|  1.38k|#define MQTT_CMD_PUBREL 6
  ------------------
  |  Branch (4478:5): [True: 376, False: 4.39k]
  ------------------
 4479|  2.16k|    case MQTT_CMD_PUBCOMP:
  ------------------
  |  | 2389|  2.16k|#define MQTT_CMD_PUBCOMP 7
  ------------------
  |  Branch (4479:5): [True: 780, False: 3.99k]
  ------------------
 4480|  2.18k|    case MQTT_CMD_SUBSCRIBE:
  ------------------
  |  | 2390|  2.18k|#define MQTT_CMD_SUBSCRIBE 8
  ------------------
  |  Branch (4480:5): [True: 20, False: 4.75k]
  ------------------
 4481|  2.21k|    case MQTT_CMD_SUBACK:
  ------------------
  |  | 2391|  2.21k|#define MQTT_CMD_SUBACK 9
  ------------------
  |  Branch (4481:5): [True: 28, False: 4.74k]
  ------------------
 4482|  2.26k|    case MQTT_CMD_UNSUBSCRIBE:
  ------------------
  |  | 2392|  2.26k|#define MQTT_CMD_UNSUBSCRIBE 10
  ------------------
  |  Branch (4482:5): [True: 54, False: 4.71k]
  ------------------
 4483|  2.27k|    case MQTT_CMD_UNSUBACK:
  ------------------
  |  | 2393|  2.27k|#define MQTT_CMD_UNSUBACK 11
  ------------------
  |  Branch (4483:5): [True: 14, False: 4.75k]
  ------------------
 4484|  2.27k|      if (p + 2 > end) return MQTT_MALFORMED;
  ------------------
  |  Branch (4484:11): [True: 90, False: 2.18k]
  ------------------
 4485|  2.18k|      m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
 4486|  2.18k|      p += 2;
 4487|  2.18k|      break;
 4488|    752|    case MQTT_CMD_PUBLISH: {
  ------------------
  |  | 2385|    752|#define MQTT_CMD_PUBLISH 3
  ------------------
  |  Branch (4488:5): [True: 752, False: 4.01k]
  ------------------
 4489|    752|      if (p + 2 > end) return MQTT_MALFORMED;
  ------------------
  |  Branch (4489:11): [True: 24, False: 728]
  ------------------
 4490|    728|      m->topic.len = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
 4491|    728|      m->topic.buf = (char *) p + 2;
 4492|    728|      p += 2 + m->topic.len;
 4493|    728|      if (p > end) return MQTT_MALFORMED;
  ------------------
  |  Branch (4493:11): [True: 664, False: 64]
  ------------------
 4494|     64|      if (m->qos > 0) {
  ------------------
  |  Branch (4494:11): [True: 26, False: 38]
  ------------------
 4495|     26|        if (p + 2 > end) return MQTT_MALFORMED;
  ------------------
  |  Branch (4495:13): [True: 6, False: 20]
  ------------------
 4496|     20|        m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
 4497|     20|        p += 2;
 4498|     20|      }
 4499|     58|      if (p > end) return MQTT_MALFORMED;
  ------------------
  |  Branch (4499:11): [True: 0, False: 58]
  ------------------
 4500|     58|      if (version == 5 && p + 2 < end) {
  ------------------
  |  Branch (4500:11): [True: 29, False: 29]
  |  Branch (4500:27): [True: 24, False: 5]
  ------------------
 4501|     24|        len_len =
 4502|     24|            (uint32_t) decode_varint(p, (size_t) (end - p), &m->props_size);
 4503|     24|        if (!len_len) return MQTT_MALFORMED;
  ------------------
  |  Branch (4503:13): [True: 4, False: 20]
  ------------------
 4504|     20|        m->props_start = (size_t) (p + len_len - buf);
 4505|     20|        p += len_len + m->props_size;
 4506|     20|      }
 4507|     54|      if (p > end) return MQTT_MALFORMED;
  ------------------
  |  Branch (4507:11): [True: 6, False: 48]
  ------------------
 4508|     48|      m->data.buf = (char *) p;
 4509|     48|      m->data.len = (size_t) (end - p);
 4510|     48|      break;
 4511|     54|    }
 4512|    328|    default:
  ------------------
  |  Branch (4512:5): [True: 328, False: 4.44k]
  ------------------
 4513|    328|      break;
 4514|  4.77k|  }
 4515|  3.94k|  return MQTT_OK;
 4516|  4.77k|}
mg_vprintf:
 4641|  5.46M|size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list *ap) {
 4642|  5.46M|  size_t old = c->send.len;
 4643|  5.46M|  mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
 4644|  5.46M|  return c->send.len - old;
 4645|  5.46M|}
mg_printf:
 4647|  5.46M|size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
 4648|  5.46M|  size_t len = 0;
 4649|  5.46M|  va_list ap;
 4650|  5.46M|  va_start(ap, fmt);
 4651|  5.46M|  len = mg_vprintf(c, fmt, &ap);
 4652|  5.46M|  va_end(ap);
 4653|  5.46M|  return len;
 4654|  5.46M|}
mg_aton:
 4752|  5.02k|bool mg_aton(struct mg_str str, struct mg_addr *addr) {
 4753|       |  // MG_INFO(("[%.*s]", (int) str.len, str.buf));
 4754|  5.02k|  return mg_atone(str, addr) || mg_atonl(str, addr) || mg_aton4(str, addr) ||
  ------------------
  |  Branch (4754:10): [True: 0, False: 5.02k]
  |  Branch (4754:33): [True: 5.02k, False: 0]
  |  Branch (4754:56): [True: 0, False: 0]
  ------------------
 4755|  5.02k|         mg_aton6(str, addr);
  ------------------
  |  Branch (4755:10): [True: 0, False: 0]
  ------------------
 4756|  5.02k|}
mg_alloc_conn:
 4758|  5.02k|struct mg_connection *mg_alloc_conn(struct mg_mgr *mgr) {
 4759|  5.02k|  struct mg_connection *c =
 4760|  5.02k|      (struct mg_connection *) calloc(1, sizeof(*c) + mgr->extraconnsize);
 4761|  5.02k|  if (c != NULL) {
  ------------------
  |  Branch (4761:7): [True: 5.02k, False: 0]
  ------------------
 4762|  5.02k|    c->mgr = mgr;
 4763|  5.02k|    c->send.align = c->recv.align = c->rtls.align = MG_IO_SIZE;
  ------------------
  |  |    5|  5.02k|#define MG_IO_SIZE (32 * 1024 * 1024)  // Big IO size for fast resizes
  ------------------
 4764|  5.02k|    c->id = ++mgr->nextid;
 4765|  5.02k|    MG_PROF_INIT(c);
 4766|  5.02k|  }
 4767|  5.02k|  return c;
 4768|  5.02k|}
mg_close_conn:
 4770|  5.02k|void mg_close_conn(struct mg_connection *c) {
 4771|  5.02k|  mg_resolve_cancel(c);  // Close any pending DNS query
 4772|  5.02k|  LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
  ------------------
  |  | 1121|  5.02k|  do {                                     \
  |  | 1122|  5.02k|    type_ **h = head_;                     \
  |  | 1123|  5.02k|    while (*h != (elem_)) h = &(*h)->next; \
  |  |  ------------------
  |  |  |  Branch (1123:12): [True: 0, False: 5.02k]
  |  |  ------------------
  |  | 1124|  5.02k|    *h = (elem_)->next;                    \
  |  | 1125|  5.02k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (1125:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 4773|  5.02k|  if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
  ------------------
  |  Branch (4773:7): [True: 0, False: 5.02k]
  ------------------
 4774|  5.02k|  if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
  ------------------
  |  Branch (4774:7): [True: 0, False: 5.02k]
  ------------------
 4775|       |  // Order of operations is important. `MG_EV_CLOSE` event must be fired
 4776|       |  // before we deallocate received data, see #1331
 4777|  5.02k|  mg_call(c, MG_EV_CLOSE, NULL);
 4778|  5.02k|  MG_DEBUG(("%lu %ld closed", c->id, c->fd));
  ------------------
  |  |  962|  5.02k|#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  |  |  ------------------
  |  |  |  |  955|  5.02k|  do {                      \
  |  |  |  |  956|  5.02k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.02k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4779|  5.02k|  MG_PROF_DUMP(c);
 4780|  5.02k|  MG_PROF_FREE(c);
 4781|       |
 4782|  5.02k|  mg_tls_free(c);
 4783|  5.02k|  mg_iobuf_free(&c->recv);
 4784|  5.02k|  mg_iobuf_free(&c->send);
 4785|  5.02k|  mg_iobuf_free(&c->rtls);
 4786|  5.02k|  mg_bzero((unsigned char *) c, sizeof(*c));
 4787|  5.02k|  free(c);
 4788|  5.02k|}
mg_connect:
 4791|  5.02k|                                 mg_event_handler_t fn, void *fn_data) {
 4792|  5.02k|  struct mg_connection *c = NULL;
 4793|  5.02k|  if (url == NULL || url[0] == '\0') {
  ------------------
  |  Branch (4793:7): [True: 0, False: 5.02k]
  |  Branch (4793:22): [True: 0, False: 5.02k]
  ------------------
 4794|      0|    MG_ERROR(("null url"));
  ------------------
  |  |  960|      0|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4795|  5.02k|  } else if ((c = mg_alloc_conn(mgr)) == NULL) {
  ------------------
  |  Branch (4795:14): [True: 0, False: 5.02k]
  ------------------
 4796|      0|    MG_ERROR(("OOM"));
  ------------------
  |  |  960|      0|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4797|  5.02k|  } else {
 4798|  5.02k|    LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
  ------------------
  |  | 1108|  5.02k|  do {                                     \
  |  | 1109|  5.02k|    (elem_)->next = (*head_);              \
  |  | 1110|  5.02k|    *(head_) = (elem_);                    \
  |  | 1111|  5.02k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (1111:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 4799|  5.02k|    c->is_udp = (strncmp(url, "udp:", 4) == 0);
 4800|  5.02k|    c->fd = (void *) (size_t) MG_INVALID_SOCKET;
  ------------------
  |  |  793|  5.02k|#define MG_INVALID_SOCKET (-1)
  ------------------
 4801|  5.02k|    c->fn = fn;
 4802|  5.02k|    c->is_client = true;
 4803|  5.02k|    c->fn_data = fn_data;
 4804|  5.02k|    MG_DEBUG(("%lu %ld %s", c->id, c->fd, url));
  ------------------
  |  |  962|  5.02k|#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  |  |  ------------------
  |  |  |  |  955|  5.02k|  do {                      \
  |  |  |  |  956|  5.02k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.02k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4805|  5.02k|    mg_call(c, MG_EV_OPEN, (void *) url);
 4806|  5.02k|    mg_resolve(c, url);
 4807|  5.02k|  }
 4808|  5.02k|  return c;
 4809|  5.02k|}
mg_mgr_free:
 4866|  5.02k|void mg_mgr_free(struct mg_mgr *mgr) {
 4867|  5.02k|  struct mg_connection *c;
 4868|  5.02k|  struct mg_timer *tmp, *t = mgr->timers;
 4869|  5.02k|  while (t != NULL) tmp = t->next, free(t), t = tmp;
  ------------------
  |  Branch (4869:10): [True: 0, False: 5.02k]
  ------------------
 4870|  5.02k|  mgr->timers = NULL;  // Important. Next call to poll won't touch timers
 4871|  10.0k|  for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1;
  ------------------
  |  Branch (4871:24): [True: 5.02k, False: 5.02k]
  ------------------
 4872|  5.02k|  mg_mgr_poll(mgr, 0);
 4873|       |#if MG_ENABLE_FREERTOS_TCP
 4874|       |  FreeRTOS_DeleteSocketSet(mgr->ss);
 4875|       |#endif
 4876|  5.02k|  MG_DEBUG(("All connections closed"));
  ------------------
  |  |  962|  5.02k|#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  |  |  ------------------
  |  |  |  |  955|  5.02k|  do {                      \
  |  |  |  |  956|  5.02k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.02k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4877|  5.02k|#if MG_ENABLE_EPOLL
 4878|  5.02k|  if (mgr->epoll_fd >= 0) close(mgr->epoll_fd), mgr->epoll_fd = -1;
  ------------------
  |  Branch (4878:7): [True: 5.02k, False: 0]
  ------------------
 4879|  5.02k|#endif
 4880|  5.02k|  mg_tls_ctx_free(mgr);
 4881|  5.02k|}
mg_mgr_init:
 4883|  5.02k|void mg_mgr_init(struct mg_mgr *mgr) {
 4884|  5.02k|  memset(mgr, 0, sizeof(*mgr));
 4885|  5.02k|#if MG_ENABLE_EPOLL
 4886|  5.02k|  if ((mgr->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
  ------------------
  |  Branch (4886:7): [True: 0, False: 5.02k]
  ------------------
 4887|  5.02k|    MG_ERROR(("epoll_create1 errno %d", errno));
  ------------------
  |  |  960|      0|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4888|       |#else
 4889|       |  mgr->epoll_fd = -1;
 4890|       |#endif
 4891|       |#if MG_ARCH == MG_ARCH_WIN32 && MG_ENABLE_WINSOCK
 4892|       |  // clang-format off
 4893|       |  { WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); }
 4894|       |  // clang-format on
 4895|       |#elif MG_ENABLE_FREERTOS_TCP
 4896|       |  mgr->ss = FreeRTOS_CreateSocketSet();
 4897|       |#elif defined(__unix) || defined(__unix__) || defined(__APPLE__)
 4898|       |  // Ignore SIGPIPE signal, so if client cancels the request, it
 4899|       |  // won't kill the whole process.
 4900|  5.02k|  signal(SIGPIPE, SIG_IGN);
 4901|       |#elif MG_ENABLE_TCPIP_DRIVER_INIT && defined(MG_TCPIP_DRIVER_INIT)
 4902|       |  MG_TCPIP_DRIVER_INIT(mgr);
 4903|       |#endif
 4904|  5.02k|  mgr->pipe = MG_INVALID_SOCKET;
  ------------------
  |  |  793|  5.02k|#define MG_INVALID_SOCKET (-1)
  ------------------
 4905|  5.02k|  mgr->dnstimeout = 3000;
 4906|  5.02k|  mgr->dns4.url = "udp://8.8.8.8:53";
 4907|  5.02k|  mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
 4908|  5.02k|  mg_tls_ctx_init(mgr);
 4909|  5.02k|}
mg_tcpip_init:
 5909|  5.02k|void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
 5910|       |  // If MAC address is not set, make a random one
 5911|  5.02k|  if (ifp->mac[0] == 0 && ifp->mac[1] == 0 && ifp->mac[2] == 0 &&
  ------------------
  |  Branch (5911:7): [True: 5.02k, False: 0]
  |  Branch (5911:27): [True: 5.02k, False: 0]
  |  Branch (5911:47): [True: 5.02k, False: 0]
  ------------------
 5912|  5.02k|      ifp->mac[3] == 0 && ifp->mac[4] == 0 && ifp->mac[5] == 0) {
  ------------------
  |  Branch (5912:7): [True: 5.02k, False: 0]
  |  Branch (5912:27): [True: 5.02k, False: 0]
  |  Branch (5912:47): [True: 5.02k, False: 0]
  ------------------
 5913|  5.02k|    ifp->mac[0] = 0x02;  // Locally administered, unicast
 5914|  5.02k|    mg_random(&ifp->mac[1], sizeof(ifp->mac) - 1);
 5915|  5.02k|    MG_INFO(("MAC not set. Generated random: %M", mg_print_mac, ifp->mac));
  ------------------
  |  |  961|  5.02k|#define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
  |  |  ------------------
  |  |  |  |  955|  5.02k|  do {                      \
  |  |  |  |  956|  5.02k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.02k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5916|  5.02k|  }
 5917|       |
 5918|  5.02k|  if (ifp->driver->init && !ifp->driver->init(ifp)) {
  ------------------
  |  Branch (5918:7): [True: 5.02k, False: 0]
  |  Branch (5918:28): [True: 0, False: 5.02k]
  ------------------
 5919|      0|    MG_ERROR(("driver init failed"));
  ------------------
  |  |  960|      0|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5920|  5.02k|  } else {
 5921|  5.02k|    size_t framesize = 1540;
 5922|  5.02k|    ifp->tx.buf = (char *) calloc(1, framesize), ifp->tx.len = framesize;
 5923|  5.02k|    if (ifp->recv_queue.size == 0)
  ------------------
  |  Branch (5923:9): [True: 5.02k, False: 0]
  ------------------
 5924|  5.02k|      ifp->recv_queue.size = ifp->driver->rx ? framesize : 8192;
  ------------------
  |  Branch (5924:30): [True: 5.02k, False: 0]
  ------------------
 5925|  5.02k|    ifp->recv_queue.buf = (char *) calloc(1, ifp->recv_queue.size);
 5926|  5.02k|    ifp->timer_1000ms = mg_millis();
 5927|  5.02k|    mgr->priv = ifp;
 5928|  5.02k|    ifp->mgr = mgr;
 5929|  5.02k|    ifp->mtu = MG_TCPIP_MTU_DEFAULT;
  ------------------
  |  | 2713|  5.02k|#define MG_TCPIP_MTU_DEFAULT 1500
  ------------------
 5930|  5.02k|    mgr->extraconnsize = sizeof(struct connstate);
 5931|  5.02k|    if (ifp->ip == 0) ifp->enable_dhcp_client = true;
  ------------------
  |  Branch (5931:9): [True: 0, False: 5.02k]
  ------------------
 5932|  5.02k|    memset(ifp->gwmac, 255, sizeof(ifp->gwmac));  // Set to broadcast
 5933|  5.02k|    mg_random(&ifp->eport, sizeof(ifp->eport));   // Random from 0 to 65535
 5934|  5.02k|    ifp->eport |= MG_EPHEMERAL_PORT_BASE;         // Random from
  ------------------
  |  | 4917|  5.02k|#define MG_EPHEMERAL_PORT_BASE 32768
  ------------------
 5935|       |                                           // MG_EPHEMERAL_PORT_BASE to 65535
 5936|  5.02k|    if (ifp->tx.buf == NULL || ifp->recv_queue.buf == NULL) MG_ERROR(("OOM"));
  ------------------
  |  |  960|      0|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (5936:9): [True: 0, False: 5.02k]
  |  Branch (5936:32): [True: 0, False: 5.02k]
  ------------------
 5937|  5.02k|  }
 5938|  5.02k|}
mg_tcpip_free:
 5940|  5.02k|void mg_tcpip_free(struct mg_tcpip_if *ifp) {
 5941|  5.02k|  free(ifp->recv_queue.buf);
 5942|  5.02k|  free(ifp->tx.buf);
 5943|  5.02k|}
mg_connect_resolved:
 5955|  5.02k|void mg_connect_resolved(struct mg_connection *c) {
 5956|  5.02k|  struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
 5957|  5.02k|  uint32_t rem_ip;
 5958|  5.02k|  memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
 5959|  5.02k|  c->is_resolving = 0;
 5960|  5.02k|  if (ifp->eport < MG_EPHEMERAL_PORT_BASE) ifp->eport = MG_EPHEMERAL_PORT_BASE;
  ------------------
  |  | 4917|  5.02k|#define MG_EPHEMERAL_PORT_BASE 32768
  ------------------
                if (ifp->eport < MG_EPHEMERAL_PORT_BASE) ifp->eport = MG_EPHEMERAL_PORT_BASE;
  ------------------
  |  | 4917|      0|#define MG_EPHEMERAL_PORT_BASE 32768
  ------------------
  |  Branch (5960:7): [True: 0, False: 5.02k]
  ------------------
 5961|  5.02k|  memcpy(c->loc.ip, &ifp->ip, sizeof(uint32_t));
 5962|  5.02k|  c->loc.port = mg_htons(ifp->eport++);
  ------------------
  |  | 1059|  5.02k|#define mg_htons(x) mg_ntohs(x)
  ------------------
 5963|  5.02k|  MG_DEBUG(("%lu %M -> %M", c->id, mg_print_ip_port, &c->loc, mg_print_ip_port,
  ------------------
  |  |  962|  5.02k|#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  |  |  ------------------
  |  |  |  |  955|  5.02k|  do {                      \
  |  |  |  |  956|  5.02k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.02k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5964|  5.02k|            &c->rem));
 5965|  5.02k|  mg_call(c, MG_EV_RESOLVE, NULL);
 5966|  5.02k|  if (c->is_udp && (rem_ip == 0xffffffff || rem_ip == (ifp->ip | ~ifp->mask))) {
  ------------------
  |  Branch (5966:7): [True: 0, False: 5.02k]
  |  Branch (5966:21): [True: 0, False: 0]
  |  Branch (5966:45): [True: 0, False: 0]
  ------------------
 5967|      0|    struct connstate *s = (struct connstate *) (c + 1);
 5968|      0|    memset(s->mac, 0xFF, sizeof(s->mac));  // global or local broadcast
 5969|  5.02k|  } else if (ifp->ip && ((rem_ip & ifp->mask) == (ifp->ip & ifp->mask))) {
  ------------------
  |  Branch (5969:14): [True: 5.02k, False: 0]
  |  Branch (5969:25): [True: 0, False: 5.02k]
  ------------------
 5970|       |    // If we're in the same LAN, fire an ARP lookup.
 5971|      0|    MG_DEBUG(("%lu ARP lookup...", c->id));
  ------------------
  |  |  962|      0|#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5972|      0|    arp_ask(ifp, rem_ip);
 5973|      0|    settmout(c, MIP_TTYPE_ARP);
  ------------------
  |  | 4939|      0|#define MIP_TTYPE_ARP 2        // ARP resolve sent, waiting for response
  ------------------
 5974|      0|    c->is_arplooking = 1;
 5975|      0|    c->is_connecting = 1;
 5976|  5.02k|  } else if ((*((uint8_t *) &rem_ip) & 0xE0) == 0xE0) {
  ------------------
  |  Branch (5976:14): [True: 0, False: 5.02k]
  ------------------
 5977|      0|    struct connstate *s = (struct connstate *) (c + 1);  // 224 to 239, E0 to EF
 5978|      0|    uint8_t mcastp[3] = {0x01, 0x00, 0x5E};              // multicast group
 5979|      0|    memcpy(s->mac, mcastp, 3);
 5980|      0|    memcpy(s->mac + 3, ((uint8_t *) &rem_ip) + 1, 3);  // 23 LSb
 5981|      0|    s->mac[3] &= 0x7F;
 5982|  5.02k|  } else {
 5983|  5.02k|    struct connstate *s = (struct connstate *) (c + 1);
 5984|  5.02k|    memcpy(s->mac, ifp->gwmac, sizeof(ifp->gwmac));
 5985|  5.02k|    if (c->is_udp) {
  ------------------
  |  Branch (5985:9): [True: 0, False: 5.02k]
  ------------------
 5986|      0|      mg_call(c, MG_EV_CONNECT, NULL);
 5987|  5.02k|    } else {
 5988|  5.02k|      send_syn(c);
 5989|  5.02k|      settmout(c, MIP_TTYPE_SYN);
  ------------------
  |  | 4940|  5.02k|#define MIP_TTYPE_SYN 3        // SYN sent, waiting for response
  ------------------
 5990|  5.02k|      c->is_connecting = 1;
 5991|  5.02k|    }
 5992|  5.02k|  }
 5993|  5.02k|}
mg_mgr_poll:
 6036|  5.02k|void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
 6037|  5.02k|  struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) mgr->priv;
 6038|  5.02k|  struct mg_connection *c, *tmp;
 6039|  5.02k|  uint64_t now = mg_millis();
 6040|  5.02k|  mg_timer_poll(&mgr->timers, now);
 6041|  5.02k|  if (ifp == NULL || ifp->driver == NULL) return;
  ------------------
  |  Branch (6041:7): [True: 0, False: 5.02k]
  |  Branch (6041:22): [True: 0, False: 5.02k]
  ------------------
 6042|  5.02k|  mg_tcpip_poll(ifp, now);
 6043|  10.0k|  for (c = mgr->conns; c != NULL; c = tmp) {
  ------------------
  |  Branch (6043:24): [True: 5.02k, False: 5.02k]
  ------------------
 6044|  5.02k|    tmp = c->next;
 6045|  5.02k|    struct connstate *s = (struct connstate *) (c + 1);
 6046|  5.02k|    mg_call(c, MG_EV_POLL, &now);
 6047|  5.02k|    MG_VERBOSE(("%lu .. %c%c%c%c%c", c->id, c->is_tls ? 'T' : 't',
  ------------------
  |  |  963|  5.02k|#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  |  |  ------------------
  |  |  |  |  955|  5.02k|  do {                      \
  |  |  |  |  956|  5.02k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  |  Branch (956:19): [True: 0, False: 0]
  |  |  |  |  |  Branch (956:19): [True: 0, False: 0]
  |  |  |  |  |  Branch (956:19): [True: 0, False: 0]
  |  |  |  |  |  Branch (956:19): [True: 0, False: 0]
  |  |  |  |  |  Branch (956:19): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.02k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 6048|  5.02k|                c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
 6049|  5.02k|                c->is_resolving ? 'R' : 'r', c->is_closing ? 'C' : 'c'));
 6050|  5.02k|    if (c->is_tls && mg_tls_pending(c) > 0)
  ------------------
  |  Branch (6050:9): [True: 0, False: 5.02k]
  |  Branch (6050:22): [True: 0, False: 0]
  ------------------
 6051|      0|      handle_tls_recv(c, (struct mg_iobuf *) &c->rtls);
 6052|  5.02k|    if (can_write(c)) write_conn(c);
  ------------------
  |  Branch (6052:9): [True: 0, False: 5.02k]
  ------------------
 6053|  5.02k|    if (c->is_draining && c->send.len == 0 && s->ttype != MIP_TTYPE_FIN)
  ------------------
  |  | 4941|  1.37k|#define MIP_TTYPE_FIN 4  // FIN sent, waiting until terminating the connection
  ------------------
  |  Branch (6053:9): [True: 1.68k, False: 3.34k]
  |  Branch (6053:27): [True: 1.37k, False: 302]
  |  Branch (6053:47): [True: 1.37k, False: 0]
  ------------------
 6054|  1.37k|      init_closure(c);
 6055|  5.02k|    if (c->is_closing) close_conn(c);
  ------------------
  |  Branch (6055:9): [True: 5.02k, False: 0]
  ------------------
 6056|  5.02k|  }
 6057|  5.02k|  (void) ms;
 6058|  5.02k|}
mg_pfn_iobuf:
 6425|   991M|void mg_pfn_iobuf(char ch, void *param) {
 6426|   991M|  mg_pfn_iobuf_private(ch, param, true);
 6427|   991M|}
mg_vsnprintf:
 6429|  14.0M|size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
 6430|  14.0M|  struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0};
 6431|  14.0M|  size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap);
 6432|  14.0M|  if (n < len) buf[n] = '\0';
  ------------------
  |  Branch (6432:7): [True: 14.0M, False: 422]
  ------------------
 6433|  14.0M|  return n;
 6434|  14.0M|}
mg_snprintf:
 6436|  14.0M|size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
 6437|  14.0M|  va_list ap;
 6438|  14.0M|  size_t n;
 6439|  14.0M|  va_start(ap, fmt);
 6440|  14.0M|  n = mg_vsnprintf(buf, len, fmt, &ap);
 6441|  14.0M|  va_end(ap);
 6442|  14.0M|  return n;
 6443|  14.0M|}
mg_vmprintf:
 6445|  2.72k|char *mg_vmprintf(const char *fmt, va_list *ap) {
 6446|  2.72k|  struct mg_iobuf io = {0, 0, 0, 256};
 6447|  2.72k|  mg_vxprintf(mg_pfn_iobuf, &io, fmt, ap);
 6448|  2.72k|  return (char *) io.buf;
 6449|  2.72k|}
mg_mprintf:
 6451|  2.72k|char *mg_mprintf(const char *fmt, ...) {
 6452|  2.72k|  char *s;
 6453|  2.72k|  va_list ap;
 6454|  2.72k|  va_start(ap, fmt);
 6455|  2.72k|  s = mg_vmprintf(fmt, &ap);
 6456|  2.72k|  va_end(ap);
 6457|  2.72k|  return s;
 6458|  2.72k|}
mg_pfn_stdout:
 6460|   124k|void mg_pfn_stdout(char c, void *param) {
 6461|   124k|  putchar(c);
 6462|   124k|  (void) param;
 6463|   124k|}
mg_sntp_parse:
 7172|  10.0k|int64_t mg_sntp_parse(const unsigned char *buf, size_t len) {
 7173|  10.0k|  int64_t epoch_milliseconds = -1;
 7174|  10.0k|  int mode = len > 0 ? buf[0] & 7 : 0;
  ------------------
  |  Branch (7174:14): [True: 5.02k, False: 5.02k]
  ------------------
 7175|  10.0k|  int version = len > 0 ? (buf[0] >> 3) & 7 : 0;
  ------------------
  |  Branch (7175:17): [True: 5.02k, False: 5.02k]
  ------------------
 7176|  10.0k|  if (len < 48) {
  ------------------
  |  Branch (7176:7): [True: 7.99k, False: 2.06k]
  ------------------
 7177|  7.99k|    MG_ERROR(("%s", "corrupt packet"));
  ------------------
  |  |  960|  7.99k|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|  7.99k|  do {                      \
  |  |  |  |  956|  7.99k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  7.99k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 7178|  7.99k|  } else if (mode != 4 && mode != 5) {
  ------------------
  |  Branch (7178:14): [True: 1.77k, False: 282]
  |  Branch (7178:27): [True: 1.46k, False: 313]
  ------------------
 7179|  1.46k|    MG_ERROR(("%s", "not a server reply"));
  ------------------
  |  |  960|  1.46k|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|  1.46k|  do {                      \
  |  |  |  |  956|  1.46k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  1.46k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 7180|  1.46k|  } else if (buf[1] == 0) {
  ------------------
  |  Branch (7180:14): [True: 6, False: 589]
  ------------------
 7181|      6|    MG_ERROR(("%s", "server sent a kiss of death"));
  ------------------
  |  |  960|      6|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|      6|  do {                      \
  |  |  |  |  956|      6|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      6|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 7182|    589|  } else if (version == 4 || version == 3) {
  ------------------
  |  Branch (7182:14): [True: 125, False: 464]
  |  Branch (7182:30): [True: 70, False: 394]
  ------------------
 7183|       |    // int64_t ref = gettimestamp((uint32_t *) &buf[16]);
 7184|    195|    int64_t origin_time = gettimestamp((uint32_t *) &buf[24]);
 7185|    195|    int64_t receive_time = gettimestamp((uint32_t *) &buf[32]);
 7186|    195|    int64_t transmit_time = gettimestamp((uint32_t *) &buf[40]);
 7187|    195|    int64_t now = (int64_t) mg_millis();
 7188|    195|    int64_t latency = (now - origin_time) - (transmit_time - receive_time);
 7189|    195|    epoch_milliseconds = transmit_time + latency / 2;
 7190|    195|    s_boot_timestamp = (uint64_t) (epoch_milliseconds - now);
 7191|    394|  } else {
 7192|    394|    MG_ERROR(("unexpected version: %d", version));
  ------------------
  |  |  960|    394|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|    394|  do {                      \
  |  |  |  |  956|    394|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|    394|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 7193|    394|  }
 7194|  10.0k|  return epoch_milliseconds;
 7195|  10.0k|}
mg_str_s:
 8077|  2.92M|struct mg_str mg_str_s(const char *s) {
 8078|  2.92M|  struct mg_str str = {(char *) s, s == NULL ? 0 : strlen(s)};
  ------------------
  |  Branch (8078:36): [True: 52.2k, False: 2.87M]
  ------------------
 8079|  2.92M|  return str;
 8080|  2.92M|}
mg_str_n:
 8082|  7.27M|struct mg_str mg_str_n(const char *s, size_t n) {
 8083|  7.27M|  struct mg_str str = {(char *) s, n};
 8084|  7.27M|  return str;
 8085|  7.27M|}
mg_strcmp:
 8114|  2.27M|int mg_strcmp(const struct mg_str str1, const struct mg_str str2) {
 8115|  2.27M|  size_t i = 0;
 8116|  3.00M|  while (i < str1.len && i < str2.len) {
  ------------------
  |  Branch (8116:10): [True: 2.32M, False: 681k]
  |  Branch (8116:26): [True: 2.15M, False: 161k]
  ------------------
 8117|  2.15M|    int c1 = str1.buf[i];
 8118|  2.15M|    int c2 = str2.buf[i];
 8119|  2.15M|    if (c1 < c2) return -1;
  ------------------
  |  Branch (8119:9): [True: 1.35M, False: 800k]
  ------------------
 8120|   800k|    if (c1 > c2) return 1;
  ------------------
  |  Branch (8120:9): [True: 77.2k, False: 723k]
  ------------------
 8121|   723k|    i++;
 8122|   723k|  }
 8123|   843k|  if (i < str1.len) return 1;
  ------------------
  |  Branch (8123:7): [True: 161k, False: 681k]
  ------------------
 8124|   681k|  if (i < str2.len) return -1;
  ------------------
  |  Branch (8124:7): [True: 132k, False: 549k]
  ------------------
 8125|   549k|  return 0;
 8126|   681k|}
mg_strcasecmp:
 8128|  1.58M|int mg_strcasecmp(const struct mg_str str1, const struct mg_str str2) {
 8129|  1.58M|  size_t i = 0;
 8130|  1.66M|  while (i < str1.len && i < str2.len) {
  ------------------
  |  Branch (8130:10): [True: 1.65M, False: 11.9k]
  |  Branch (8130:26): [True: 1.64M, False: 2.30k]
  ------------------
 8131|  1.64M|    int c1 = mg_tolc(str1.buf[i]);
 8132|  1.64M|    int c2 = mg_tolc(str2.buf[i]);
 8133|  1.64M|    if (c1 < c2) return -1;
  ------------------
  |  Branch (8133:9): [True: 1.56M, False: 85.8k]
  ------------------
 8134|  85.8k|    if (c1 > c2) return 1;
  ------------------
  |  Branch (8134:9): [True: 8.61k, False: 77.2k]
  ------------------
 8135|  77.2k|    i++;
 8136|  77.2k|  }
 8137|  14.2k|  if (i < str1.len) return 1;
  ------------------
  |  Branch (8137:7): [True: 2.30k, False: 11.9k]
  ------------------
 8138|  11.9k|  if (i < str2.len) return -1;
  ------------------
  |  Branch (8138:7): [True: 3.85k, False: 8.07k]
  ------------------
 8139|  8.07k|  return 0;
 8140|  11.9k|}
mg_match:
 8142|  5.02k|bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
 8143|  5.02k|  size_t i = 0, j = 0, ni = 0, nj = 0;
 8144|  5.02k|  if (caps) caps->buf = NULL, caps->len = 0;
  ------------------
  |  Branch (8144:7): [True: 0, False: 5.02k]
  ------------------
 8145|   156M|  while (i < p.len || j < s.len) {
  ------------------
  |  Branch (8145:10): [True: 156M, False: 5.05k]
  |  Branch (8145:23): [True: 28, False: 5.02k]
  ------------------
 8146|   156M|    if (i < p.len && j < s.len &&
  ------------------
  |  Branch (8146:9): [True: 156M, False: 28]
  |  Branch (8146:22): [True: 156M, False: 26]
  ------------------
 8147|   156M|        (p.buf[i] == '?' ||
  ------------------
  |  Branch (8147:10): [True: 91.5k, False: 156M]
  ------------------
 8148|   156M|         (p.buf[i] != '*' && p.buf[i] != '#' && s.buf[j] == p.buf[i]))) {
  ------------------
  |  Branch (8148:11): [True: 156M, False: 172k]
  |  Branch (8148:30): [True: 156M, False: 55.4k]
  |  Branch (8148:49): [True: 156M, False: 113k]
  ------------------
 8149|   156M|      if (caps == NULL) {
  ------------------
  |  Branch (8149:11): [True: 156M, False: 0]
  ------------------
 8150|   156M|      } else if (p.buf[i] == '?') {
  ------------------
  |  Branch (8150:18): [True: 0, False: 0]
  ------------------
 8151|      0|        caps->buf = &s.buf[j], caps->len = 1;     // Finalize `?` cap
 8152|      0|        caps++, caps->buf = NULL, caps->len = 0;  // Init next cap
 8153|      0|      } else if (caps->buf != NULL && caps->len == 0) {
  ------------------
  |  Branch (8153:18): [True: 0, False: 0]
  |  Branch (8153:39): [True: 0, False: 0]
  ------------------
 8154|      0|        caps->len = (size_t) (&s.buf[j] - caps->buf);  // Finalize current cap
 8155|      0|        caps++, caps->len = 0, caps->buf = NULL;       // Init next cap
 8156|      0|      }
 8157|   156M|      i++, j++;
 8158|   156M|    } else if (i < p.len && (p.buf[i] == '*' || p.buf[i] == '#')) {
  ------------------
  |  Branch (8158:16): [True: 341k, False: 28]
  |  Branch (8158:30): [True: 172k, False: 169k]
  |  Branch (8158:49): [True: 55.4k, False: 113k]
  ------------------
 8159|   227k|      if (caps && !caps->buf) caps->len = 0, caps->buf = &s.buf[j];  // Init cap
  ------------------
  |  Branch (8159:11): [True: 0, False: 227k]
  |  Branch (8159:19): [True: 0, False: 0]
  ------------------
 8160|   227k|      ni = i++, nj = j + 1;
 8161|   227k|    } else if (nj > 0 && nj <= s.len && (p.buf[ni] == '#' || s.buf[j] != '/')) {
  ------------------
  |  Branch (8161:16): [True: 113k, False: 0]
  |  Branch (8161:26): [True: 113k, False: 0]
  |  Branch (8161:42): [True: 27.7k, False: 86.2k]
  |  Branch (8161:62): [True: 86.2k, False: 0]
  ------------------
 8162|   113k|      i = ni, j = nj;
 8163|   113k|      if (caps && caps->buf == NULL && caps->len == 0) {
  ------------------
  |  Branch (8163:11): [True: 0, False: 113k]
  |  Branch (8163:19): [True: 0, False: 0]
  |  Branch (8163:40): [True: 0, False: 0]
  ------------------
 8164|      0|        caps--, caps->len = 0;  // Restart previous cap
 8165|      0|      }
 8166|   113k|    } else {
 8167|      0|      return false;
 8168|      0|    }
 8169|   156M|  }
 8170|  5.02k|  if (caps && caps->buf && caps->len == 0) {
  ------------------
  |  Branch (8170:7): [True: 0, False: 5.02k]
  |  Branch (8170:15): [True: 0, False: 0]
  |  Branch (8170:28): [True: 0, False: 0]
  ------------------
 8171|      0|    caps->len = (size_t) (&s.buf[j] - caps->buf);
 8172|      0|  }
 8173|  5.02k|  return true;
 8174|  5.02k|}
mg_span:
 8176|  3.50M|bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char sep) {
 8177|  3.50M|  if (s.len == 0 || s.buf == NULL) {
  ------------------
  |  Branch (8177:7): [True: 459k, False: 3.04M]
  |  Branch (8177:21): [True: 0, False: 3.04M]
  ------------------
 8178|   459k|    return false;  // Empty string, nothing to span - fail
 8179|  3.04M|  } else {
 8180|  3.04M|    size_t len = 0;
 8181|   430M|    while (len < s.len && s.buf[len] != sep) len++;  // Find separator
  ------------------
  |  Branch (8181:12): [True: 429M, False: 980k]
  |  Branch (8181:27): [True: 427M, False: 2.06M]
  ------------------
 8182|  3.04M|    if (a) *a = mg_str_n(s.buf, len);                // Init a
  ------------------
  |  Branch (8182:9): [True: 3.04M, False: 0]
  ------------------
 8183|  3.04M|    if (b) *b = mg_str_n(s.buf + len, s.len - len);  // Init b
  ------------------
  |  Branch (8183:9): [True: 3.04M, False: 0]
  ------------------
 8184|  3.04M|    if (b && len < s.len) b->buf++, b->len--;        // Skip separator
  ------------------
  |  Branch (8184:9): [True: 3.04M, False: 0]
  |  Branch (8184:14): [True: 2.06M, False: 980k]
  ------------------
 8185|  3.04M|    return true;
 8186|  3.04M|  }
 8187|  3.50M|}
mg_str_to_num:
 8189|  46.7k|bool mg_str_to_num(struct mg_str str, int base, void *val, size_t val_len) {
 8190|  46.7k|  size_t i = 0, ndigits = 0;
 8191|  46.7k|  uint64_t max = val_len == sizeof(uint8_t)    ? 0xFF
  ------------------
  |  Branch (8191:18): [True: 43.4k, False: 3.35k]
  ------------------
 8192|  46.7k|                 : val_len == sizeof(uint16_t) ? 0xFFFF
  ------------------
  |  Branch (8192:20): [True: 0, False: 3.35k]
  ------------------
 8193|  3.35k|                 : val_len == sizeof(uint32_t) ? 0xFFFFFFFF
  ------------------
  |  Branch (8193:20): [True: 3.35k, False: 0]
  ------------------
 8194|  3.35k|                                               : (uint64_t) ~0;
 8195|  46.7k|  uint64_t result = 0;
 8196|  46.7k|  if (max == (uint64_t) ~0 && val_len != sizeof(uint64_t)) return false;
  ------------------
  |  Branch (8196:7): [True: 0, False: 46.7k]
  |  Branch (8196:31): [True: 0, False: 0]
  ------------------
 8197|  46.7k|  if (base == 0 && str.len >= 2) {
  ------------------
  |  Branch (8197:7): [True: 0, False: 46.7k]
  |  Branch (8197:20): [True: 0, False: 0]
  ------------------
 8198|      0|    if (str.buf[i] == '0') {
  ------------------
  |  Branch (8198:9): [True: 0, False: 0]
  ------------------
 8199|      0|      i++;
 8200|      0|      base = str.buf[i] == 'b' ? 2 : str.buf[i] == 'x' ? 16 : 10;
  ------------------
  |  Branch (8200:14): [True: 0, False: 0]
  |  Branch (8200:38): [True: 0, False: 0]
  ------------------
 8201|      0|      if (base != 10) ++i;
  ------------------
  |  Branch (8201:11): [True: 0, False: 0]
  ------------------
 8202|      0|    } else {
 8203|      0|      base = 10;
 8204|      0|    }
 8205|      0|  }
 8206|  46.7k|  switch (base) {
 8207|      0|    case 2:
  ------------------
  |  Branch (8207:5): [True: 0, False: 46.7k]
  ------------------
 8208|      0|      while (i < str.len && (str.buf[i] == '0' || str.buf[i] == '1')) {
  ------------------
  |  Branch (8208:14): [True: 0, False: 0]
  |  Branch (8208:30): [True: 0, False: 0]
  |  Branch (8208:51): [True: 0, False: 0]
  ------------------
 8209|      0|        uint64_t digit = (uint64_t) (str.buf[i] - '0');
 8210|      0|        if (result > max / 2) return false;  // Overflow
  ------------------
  |  Branch (8210:13): [True: 0, False: 0]
  ------------------
 8211|      0|        result *= 2;
 8212|      0|        if (result > max - digit) return false;  // Overflow
  ------------------
  |  Branch (8212:13): [True: 0, False: 0]
  ------------------
 8213|      0|        result += digit;
 8214|      0|        i++, ndigits++;
 8215|      0|      }
 8216|      0|      break;
 8217|      0|    case 10:
  ------------------
  |  Branch (8217:5): [True: 0, False: 46.7k]
  ------------------
 8218|      0|      while (i < str.len && str.buf[i] >= '0' && str.buf[i] <= '9') {
  ------------------
  |  Branch (8218:14): [True: 0, False: 0]
  |  Branch (8218:29): [True: 0, False: 0]
  |  Branch (8218:50): [True: 0, False: 0]
  ------------------
 8219|      0|        uint64_t digit = (uint64_t) (str.buf[i] - '0');
 8220|      0|        if (result > max / 10) return false;  // Overflow
  ------------------
  |  Branch (8220:13): [True: 0, False: 0]
  ------------------
 8221|      0|        result *= 10;
 8222|      0|        if (result > max - digit) return false;  // Overflow
  ------------------
  |  Branch (8222:13): [True: 0, False: 0]
  ------------------
 8223|      0|        result += digit;
 8224|      0|        i++, ndigits++;
 8225|      0|      }
 8226|      0|      break;
 8227|  46.7k|    case 16:
  ------------------
  |  Branch (8227:5): [True: 46.7k, False: 0]
  ------------------
 8228|   139k|      while (i < str.len) {
  ------------------
  |  Branch (8228:14): [True: 92.3k, False: 46.7k]
  ------------------
 8229|  92.3k|        char c = str.buf[i];
 8230|  92.3k|        uint64_t digit = (c >= '0' && c <= '9')   ? (uint64_t) (c - '0')
  ------------------
  |  Branch (8230:27): [True: 92.3k, False: 0]
  |  Branch (8230:39): [True: 62.2k, False: 30.1k]
  ------------------
 8231|  92.3k|                         : (c >= 'A' && c <= 'F') ? (uint64_t) (c - '7')
  ------------------
  |  Branch (8231:29): [True: 30.1k, False: 0]
  |  Branch (8231:41): [True: 7.59k, False: 22.5k]
  ------------------
 8232|  30.1k|                         : (c >= 'a' && c <= 'f') ? (uint64_t) (c - 'W')
  ------------------
  |  Branch (8232:29): [True: 22.5k, False: 0]
  |  Branch (8232:41): [True: 22.5k, False: 0]
  ------------------
 8233|  22.5k|                                                  : (uint64_t) ~0;
 8234|  92.3k|        if (digit == (uint64_t) ~0) break;
  ------------------
  |  Branch (8234:13): [True: 0, False: 92.3k]
  ------------------
 8235|  92.3k|        if (result > max / 16) return false;  // Overflow
  ------------------
  |  Branch (8235:13): [True: 0, False: 92.3k]
  ------------------
 8236|  92.3k|        result *= 16;
 8237|  92.3k|        if (result > max - digit) return false;  // Overflow
  ------------------
  |  Branch (8237:13): [True: 0, False: 92.3k]
  ------------------
 8238|  92.3k|        result += digit;
 8239|  92.3k|        i++, ndigits++;
 8240|  92.3k|      }
 8241|  46.7k|      break;
 8242|  46.7k|    default:
  ------------------
  |  Branch (8242:5): [True: 0, False: 46.7k]
  ------------------
 8243|      0|      return false;
 8244|  46.7k|  }
 8245|  46.7k|  if (ndigits == 0) return false;
  ------------------
  |  Branch (8245:7): [True: 0, False: 46.7k]
  ------------------
 8246|  46.7k|  if (i != str.len) return false;
  ------------------
  |  Branch (8246:7): [True: 0, False: 46.7k]
  ------------------
 8247|  46.7k|  if (val_len == 1) {
  ------------------
  |  Branch (8247:7): [True: 43.4k, False: 3.35k]
  ------------------
 8248|  43.4k|    *((uint8_t *) val) = (uint8_t) result;
 8249|  43.4k|  } else if (val_len == 2) {
  ------------------
  |  Branch (8249:14): [True: 0, False: 3.35k]
  ------------------
 8250|      0|    *((uint16_t *) val) = (uint16_t) result;
 8251|  3.35k|  } else if (val_len == 4) {
  ------------------
  |  Branch (8251:14): [True: 3.35k, False: 0]
  ------------------
 8252|  3.35k|    *((uint32_t *) val) = (uint32_t) result;
 8253|  3.35k|  } else {
 8254|      0|    *((uint64_t *) val) = (uint64_t) result;
 8255|      0|  }
 8256|  46.7k|  return true;
 8257|  46.7k|}
mg_timer_expired:
 8280|  5.02k|bool mg_timer_expired(uint64_t *t, uint64_t prd, uint64_t now) {
 8281|  5.02k|  if (now + prd < *t) *t = 0;                    // Time wrapped? Reset timer
  ------------------
  |  Branch (8281:7): [True: 0, False: 5.02k]
  ------------------
 8282|  5.02k|  if (*t == 0) *t = now + prd;                   // Firt poll? Set expiration
  ------------------
  |  Branch (8282:7): [True: 0, False: 5.02k]
  ------------------
 8283|  5.02k|  if (*t > now) return false;                    // Not expired yet, return
  ------------------
  |  Branch (8283:7): [True: 0, False: 5.02k]
  ------------------
 8284|  5.02k|  *t = (now - *t) > prd ? now + prd : *t + prd;  // Next expiration time
  ------------------
  |  Branch (8284:8): [True: 26, False: 5.00k]
  ------------------
 8285|  5.02k|  return true;                                   // Expired, return true
 8286|  5.02k|}
mg_timer_poll:
 8288|  5.02k|void mg_timer_poll(struct mg_timer **head, uint64_t now_ms) {
 8289|  5.02k|  struct mg_timer *t, *tmp;
 8290|  5.02k|  for (t = *head; t != NULL; t = tmp) {
  ------------------
  |  Branch (8290:19): [True: 0, False: 5.02k]
  ------------------
 8291|      0|    bool once = t->expire == 0 && (t->flags & MG_TIMER_RUN_NOW) &&
  ------------------
  |  |  975|      0|#define MG_TIMER_RUN_NOW 2  // Call immediately when timer is set
  ------------------
  |  Branch (8291:17): [True: 0, False: 0]
  |  Branch (8291:35): [True: 0, False: 0]
  ------------------
 8292|      0|                !(t->flags & MG_TIMER_CALLED);  // Handle MG_TIMER_NOW only once
  ------------------
  |  | 8265|      0|#define MG_TIMER_CALLED 4
  ------------------
  |  Branch (8292:17): [True: 0, False: 0]
  ------------------
 8293|      0|    bool expired = mg_timer_expired(&t->expire, t->period_ms, now_ms);
 8294|      0|    tmp = t->next;
 8295|      0|    if (!once && !expired) continue;
  ------------------
  |  Branch (8295:9): [True: 0, False: 0]
  |  Branch (8295:18): [True: 0, False: 0]
  ------------------
 8296|      0|    if ((t->flags & MG_TIMER_REPEAT) || !(t->flags & MG_TIMER_CALLED)) {
  ------------------
  |  |  974|      0|#define MG_TIMER_REPEAT 1   // Call function periodically
  ------------------
                  if ((t->flags & MG_TIMER_REPEAT) || !(t->flags & MG_TIMER_CALLED)) {
  ------------------
  |  | 8265|      0|#define MG_TIMER_CALLED 4
  ------------------
  |  Branch (8296:9): [True: 0, False: 0]
  |  Branch (8296:41): [True: 0, False: 0]
  ------------------
 8297|      0|      t->fn(t->arg);
 8298|      0|    }
 8299|      0|    t->flags |= MG_TIMER_CALLED;
  ------------------
  |  | 8265|      0|#define MG_TIMER_CALLED 4
  ------------------
 8300|      0|  }
 8301|  5.02k|}
mg_tls_free:
12206|  5.02k|void mg_tls_free(struct mg_connection *c) {
12207|  5.02k|  (void) c;
12208|  5.02k|}
mg_tls_ctx_init:
12219|  5.02k|void mg_tls_ctx_init(struct mg_mgr *mgr) {
12220|  5.02k|  (void) mgr;
12221|  5.02k|}
mg_tls_ctx_free:
12222|  5.02k|void mg_tls_ctx_free(struct mg_mgr *mgr) {
12223|  5.02k|  (void) mgr;
12224|  5.02k|}
mg_url_host:
16281|  5.02k|struct mg_str mg_url_host(const char *url) {
16282|  5.02k|  struct url u = urlparse(url);
16283|  5.02k|  size_t n = u.port  ? u.port - u.host - 1
  ------------------
  |  Branch (16283:14): [True: 5.02k, False: 0]
  ------------------
16284|  5.02k|             : u.uri ? u.uri - u.host
  ------------------
  |  Branch (16284:16): [True: 0, False: 0]
  ------------------
16285|      0|                     : u.end - u.host;
16286|  5.02k|  struct mg_str s = mg_str_n(url + u.host, n);
16287|  5.02k|  return s;
16288|  5.02k|}
mg_url_port:
16295|  5.02k|unsigned short mg_url_port(const char *url) {
16296|  5.02k|  struct url u = urlparse(url);
16297|  5.02k|  unsigned short port = 0;
16298|  5.02k|  if (strncmp(url, "http:", 5) == 0 || strncmp(url, "ws:", 3) == 0) port = 80;
  ------------------
  |  Branch (16298:7): [True: 5.02k, False: 0]
  |  Branch (16298:40): [True: 0, False: 0]
  ------------------
16299|  5.02k|  if (strncmp(url, "wss:", 4) == 0 || strncmp(url, "https:", 6) == 0)
  ------------------
  |  Branch (16299:7): [True: 0, False: 5.02k]
  |  Branch (16299:39): [True: 0, False: 5.02k]
  ------------------
16300|      0|    port = 443;
16301|  5.02k|  if (strncmp(url, "mqtt:", 5) == 0) port = 1883;
  ------------------
  |  Branch (16301:7): [True: 0, False: 5.02k]
  ------------------
16302|  5.02k|  if (strncmp(url, "mqtts:", 6) == 0) port = 8883;
  ------------------
  |  Branch (16302:7): [True: 0, False: 5.02k]
  ------------------
16303|  5.02k|  if (u.port) port = (unsigned short) atoi(url + u.port);
  ------------------
  |  Branch (16303:7): [True: 5.02k, False: 0]
  ------------------
16304|  5.02k|  return port;
16305|  5.02k|}
mg_bzero:
16334|  65.5k|void mg_bzero(volatile unsigned char *buf, size_t len) {
16335|  65.5k|  if (buf != NULL) {
  ------------------
  |  Branch (16335:7): [True: 43.3k, False: 22.2k]
  ------------------
16336|   246G|    while (len--) *buf++ = 0;
  ------------------
  |  Branch (16336:12): [True: 246G, False: 43.3k]
  ------------------
16337|  43.3k|  }
16338|  65.5k|}
mg_random:
16342|  10.0k|void mg_random(void *buf, size_t len) {
16343|  10.0k|  bool done = false;
16344|  10.0k|  unsigned char *p = (unsigned char *) buf;
16345|       |#if MG_ARCH == MG_ARCH_ESP32
16346|       |  while (len--) *p++ = (unsigned char) (esp_random() & 255);
16347|       |  done = true;
16348|       |#elif MG_ARCH == MG_ARCH_WIN32
16349|       |#elif MG_ARCH == MG_ARCH_UNIX
16350|       |  FILE *fp = fopen("/dev/urandom", "rb");
16351|  10.0k|  if (fp != NULL) {
  ------------------
  |  Branch (16351:7): [True: 10.0k, False: 0]
  ------------------
16352|  10.0k|    if (fread(buf, 1, len, fp) == len) done = true;
  ------------------
  |  Branch (16352:9): [True: 10.0k, False: 0]
  ------------------
16353|  10.0k|    fclose(fp);
16354|  10.0k|  }
16355|  10.0k|#endif
16356|       |  // If everything above did not work, fallback to a pseudo random generator
16357|  10.0k|  while (!done && len--) *p++ = (unsigned char) (rand() & 255);
  ------------------
  |  Branch (16357:10): [True: 0, False: 10.0k]
  |  Branch (16357:19): [True: 0, False: 0]
  ------------------
16358|  10.0k|}
mg_ntohl:
16374|  11.2k|uint32_t mg_ntohl(uint32_t net) {
16375|  11.2k|  uint8_t data[4] = {0, 0, 0, 0};
16376|  11.2k|  memcpy(&data, &net, sizeof(data));
16377|  11.2k|  return (((uint32_t) data[3]) << 0) | (((uint32_t) data[2]) << 8) |
16378|  11.2k|         (((uint32_t) data[1]) << 16) | (((uint32_t) data[0]) << 24);
16379|  11.2k|}
mg_ntohs:
16381|  79.3k|uint16_t mg_ntohs(uint16_t net) {
16382|  79.3k|  uint8_t data[2] = {0, 0};
16383|  79.3k|  memcpy(&data, &net, sizeof(data));
16384|  79.3k|  return (uint16_t) ((uint16_t) data[1] | (((uint16_t) data[0]) << 8));
16385|  79.3k|}
mg_crc32:
16387|   157k|uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len) {
16388|   157k|  static const uint32_t crclut[16] = {
16389|       |      // table for polynomial 0xEDB88320 (reflected)
16390|   157k|      0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC, 0x76DC4190, 0x6B6B51F4,
16391|   157k|      0x4DB26158, 0x5005713C, 0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C,
16392|   157k|      0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C};
16393|   157k|  crc = ~crc;
16394|  43.4M|  while (len--) {
  ------------------
  |  Branch (16394:10): [True: 43.2M, False: 157k]
  ------------------
16395|  43.2M|    uint8_t b = *(uint8_t *) buf++;
16396|  43.2M|    crc = crclut[(crc ^ b) & 0x0F] ^ (crc >> 4);
16397|  43.2M|    crc = crclut[(crc ^ (b >> 4)) & 0x0F] ^ (crc >> 4);
16398|  43.2M|  }
16399|   157k|  return ~crc;
16400|   157k|}
mg_path_is_sane:
16438|   395k|bool mg_path_is_sane(const struct mg_str path) {
16439|   395k|  const char *s = path.buf;
16440|   395k|  size_t n = path.len;
16441|   395k|  if (path.buf[0] == '.' && path.buf[1] == '.') return false;  // Starts with ..
  ------------------
  |  Branch (16441:7): [True: 395k, False: 0]
  |  Branch (16441:29): [True: 0, False: 395k]
  ------------------
16442|  38.9M|  for (; s[0] != '\0' && n > 0; s++, n--) {
  ------------------
  |  Branch (16442:10): [True: 38.5M, False: 393k]
  |  Branch (16442:26): [True: 38.5M, False: 0]
  ------------------
16443|  38.5M|    if ((s[0] == '/' || s[0] == '\\') && n >= 2) {   // Subdir?
  ------------------
  |  Branch (16443:10): [True: 36.7M, False: 1.88M]
  |  Branch (16443:25): [True: 2.12k, False: 1.87M]
  |  Branch (16443:42): [True: 36.7M, False: 0]
  ------------------
16444|  36.7M|      if (s[1] == '.' && s[2] == '.') return false;  // Starts with ..
  ------------------
  |  Branch (16444:11): [True: 221k, False: 36.4M]
  |  Branch (16444:26): [True: 1.44k, False: 220k]
  ------------------
16445|  36.7M|    }
16446|  38.5M|  }
16447|   393k|  return true;
16448|   395k|}
mg_millis:
16452|  10.2k|uint64_t mg_millis(void) {
16453|       |#if MG_ARCH == MG_ARCH_WIN32
16454|       |  return GetTickCount();
16455|       |#elif MG_ARCH == MG_ARCH_RP2040
16456|       |  return time_us_64() / 1000;
16457|       |#elif MG_ARCH == MG_ARCH_ESP8266 || MG_ARCH == MG_ARCH_ESP32 || \
16458|       |    MG_ARCH == MG_ARCH_FREERTOS
16459|       |  return xTaskGetTickCount() * portTICK_PERIOD_MS;
16460|       |#elif MG_ARCH == MG_ARCH_AZURERTOS
16461|       |  return tx_time_get() * (1000 /* MS per SEC */ / TX_TIMER_TICKS_PER_SECOND);
16462|       |#elif MG_ARCH == MG_ARCH_TIRTOS
16463|       |  return (uint64_t) Clock_getTicks();
16464|       |#elif MG_ARCH == MG_ARCH_ZEPHYR
16465|       |  return (uint64_t) k_uptime_get();
16466|       |#elif MG_ARCH == MG_ARCH_CMSIS_RTOS1
16467|       |  return (uint64_t) rt_time_get();
16468|       |#elif MG_ARCH == MG_ARCH_CMSIS_RTOS2
16469|       |  return (uint64_t) ((osKernelGetTickCount() * 1000) / osKernelGetTickFreq());
16470|       |#elif MG_ARCH == MG_ARCH_RTTHREAD
16471|       |  return (uint64_t) ((rt_tick_get() * 1000) / RT_TICK_PER_SECOND);
16472|       |#elif MG_ARCH == MG_ARCH_UNIX && defined(__APPLE__)
16473|       |  // Apple CLOCK_MONOTONIC_RAW is equivalent to CLOCK_BOOTTIME on linux
16474|       |  // Apple CLOCK_UPTIME_RAW is equivalent to CLOCK_MONOTONIC_RAW on linux
16475|       |  return clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1000000;
16476|       |#elif MG_ARCH == MG_ARCH_UNIX
16477|       |  struct timespec ts = {0, 0};
16478|       |  // See #1615 - prefer monotonic clock
16479|  10.2k|#if defined(CLOCK_MONOTONIC_RAW)
16480|       |  // Raw hardware-based time that is not subject to NTP adjustment
16481|  10.2k|  clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
16482|       |#elif defined(CLOCK_MONOTONIC)
16483|       |  // Affected by the incremental adjustments performed by adjtime and NTP
16484|       |  clock_gettime(CLOCK_MONOTONIC, &ts);
16485|       |#else
16486|       |  // Affected by discontinuous jumps in the system time and by the incremental
16487|       |  // adjustments performed by adjtime and NTP
16488|       |  clock_gettime(CLOCK_REALTIME, &ts);
16489|       |#endif
16490|  10.2k|  return ((uint64_t) ts.tv_sec * 1000 + (uint64_t) ts.tv_nsec / 1000000);
16491|       |#elif defined(ARDUINO)
16492|       |  return (uint64_t) millis();
16493|       |#else
16494|       |  return (uint64_t) (time(NULL) * 1000);
16495|       |#endif
16496|  10.2k|}
fuzz.c:_ZL23mg_base64_encode_singlei:
   27|   208M|static int mg_base64_encode_single(int c) {
   28|   208M|  if (c < 26) {
  ------------------
  |  Branch (28:7): [True: 121M, False: 87.1M]
  ------------------
   29|   121M|    return c + 'A';
   30|   121M|  } else if (c < 52) {
  ------------------
  |  Branch (30:14): [True: 62.7M, False: 24.3M]
  ------------------
   31|  62.7M|    return c - 26 + 'a';
   32|  62.7M|  } else if (c < 62) {
  ------------------
  |  Branch (32:14): [True: 19.4M, False: 4.83M]
  ------------------
   33|  19.4M|    return c - 52 + '0';
   34|  19.4M|  } else {
   35|  4.83M|    return c == 62 ? '+' : '/';
  ------------------
  |  Branch (35:12): [True: 536k, False: 4.29M]
  ------------------
   36|  4.83M|  }
   37|   208M|}
fuzz.c:_ZL23mg_base64_decode_singlei:
   39|  5.76M|static int mg_base64_decode_single(int c) {
   40|  5.76M|  if (c >= 'A' && c <= 'Z') {
  ------------------
  |  Branch (40:7): [True: 168k, False: 5.59M]
  |  Branch (40:19): [True: 4.60k, False: 164k]
  ------------------
   41|  4.60k|    return c - 'A';
   42|  5.75M|  } else if (c >= 'a' && c <= 'z') {
  ------------------
  |  Branch (42:14): [True: 163k, False: 5.59M]
  |  Branch (42:26): [True: 162k, False: 462]
  ------------------
   43|   162k|    return c + 26 - 'a';
   44|  5.59M|  } else if (c >= '0' && c <= '9') {
  ------------------
  |  Branch (44:14): [True: 5.58M, False: 12.8k]
  |  Branch (44:26): [True: 5.58M, False: 2.84k]
  ------------------
   45|  5.58M|    return c + 52 - '0';
   46|  5.58M|  } else if (c == '+') {
  ------------------
  |  Branch (46:14): [True: 1.21k, False: 14.5k]
  ------------------
   47|  1.21k|    return 62;
   48|  14.5k|  } else if (c == '/') {
  ------------------
  |  Branch (48:14): [True: 2.09k, False: 12.4k]
  ------------------
   49|  2.09k|    return 63;
   50|  12.4k|  } else if (c == '=') {
  ------------------
  |  Branch (50:14): [True: 685, False: 11.7k]
  ------------------
   51|    685|    return 64;
   52|  11.7k|  } else {
   53|  11.7k|    return -1;
   54|  11.7k|  }
   55|  5.76M|}
fuzz.c:_ZL17mg_dns_parse_namePKhmmPcm:
 1133|    906|                                char *dst, size_t dstlen) {
 1134|    906|  return mg_dns_parse_name_depth(s, n, ofs, dst, dstlen, 0, 0);
 1135|    906|}
fuzz.c:_ZL23mg_dns_parse_name_depthPKhmmPcmmi:
 1097|  1.61k|                                      int depth) {
 1098|  1.61k|  size_t i = 0;
 1099|  1.61k|  if (tolen > 0 && depth == 0) to[0] = '\0';
  ------------------
  |  Branch (1099:7): [True: 550, False: 1.06k]
  |  Branch (1099:20): [True: 307, False: 243]
  ------------------
 1100|  1.61k|  if (depth > 5) return 0;
  ------------------
  |  Branch (1100:7): [True: 16, False: 1.59k]
  ------------------
 1101|       |  // MG_INFO(("ofs %lx %x %x", (unsigned long) ofs, s[ofs], s[ofs + 1]));
 1102|  5.09k|  while (ofs + i + 1 < len) {
  ------------------
  |  Branch (1102:10): [True: 5.01k, False: 79]
  ------------------
 1103|  5.01k|    size_t n = s[ofs + i];
 1104|  5.01k|    if (n == 0) {
  ------------------
  |  Branch (1104:9): [True: 532, False: 4.48k]
  ------------------
 1105|    532|      i++;
 1106|    532|      break;
 1107|    532|    }
 1108|  4.48k|    if (n & 0xc0) {
  ------------------
  |  Branch (1108:9): [True: 944, False: 3.53k]
  ------------------
 1109|    944|      size_t ptr = (((n & 0x3f) << 8) | s[ofs + i + 1]);  // 12 is hdr len
 1110|       |      // MG_INFO(("PTR %lx", (unsigned long) ptr));
 1111|    944|      if (ptr + 1 < len && (s[ptr] & 0xc0) == 0 &&
  ------------------
  |  Branch (1111:11): [True: 744, False: 200]
  |  Branch (1111:28): [True: 705, False: 39]
  ------------------
 1112|    944|          mg_dns_parse_name_depth(s, len, ptr, to, tolen, j, depth + 1) == 0)
  ------------------
  |  Branch (1112:11): [True: 113, False: 592]
  ------------------
 1113|    113|        return 0;
 1114|    831|      i += 2;
 1115|    831|      break;
 1116|    944|    }
 1117|  3.53k|    if (ofs + i + n + 1 >= len) return 0;
  ------------------
  |  Branch (1117:9): [True: 40, False: 3.49k]
  ------------------
 1118|  3.49k|    if (j > 0) {
  ------------------
  |  Branch (1118:9): [True: 3.18k, False: 314]
  ------------------
 1119|  3.18k|      if (j < tolen) to[j] = '.';
  ------------------
  |  Branch (1119:11): [True: 777, False: 2.40k]
  ------------------
 1120|  3.18k|      j++;
 1121|  3.18k|    }
 1122|  3.49k|    if (j + n < tolen) memcpy(&to[j], &s[ofs + i + 1], n);
  ------------------
  |  Branch (1122:9): [True: 880, False: 2.61k]
  ------------------
 1123|  3.49k|    j += n;
 1124|  3.49k|    i += n + 1;
 1125|  3.49k|    if (j < tolen) to[j] = '\0';  // Zero-terminate this chunk
  ------------------
  |  Branch (1125:9): [True: 880, False: 2.61k]
  ------------------
 1126|       |    // MG_INFO(("--> [%s]", to));
 1127|  3.49k|  }
 1128|  1.44k|  if (tolen > 0) to[tolen - 1] = '\0';  // Make sure make sure it is nul-term
  ------------------
  |  Branch (1128:7): [True: 550, False: 892]
  ------------------
 1129|  1.44k|  return i;
 1130|  1.59k|}
fuzz.c:_ZL8is_digiti:
 1375|  56.8M|static bool is_digit(int c) {
 1376|  56.8M|  return c >= '0' && c <= '9';
  ------------------
  |  Branch (1376:10): [True: 51.6M, False: 5.17M]
  |  Branch (1376:22): [True: 107k, False: 51.5M]
  ------------------
 1377|  56.8M|}
fuzz.c:_ZL6mg_lldPclbb:
 1469|  13.4M|static size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) {
 1470|  13.4M|  const char *letters = "0123456789abcdef";
 1471|  13.4M|  uint64_t v = (uint64_t) val;
 1472|  13.4M|  size_t s = 0, n, i;
 1473|  13.4M|  if (is_signed && val < 0) buf[s++] = '-', v = (uint64_t) (-val);
  ------------------
  |  Branch (1473:7): [True: 4.80M, False: 8.61M]
  |  Branch (1473:20): [True: 3.48M, False: 1.32M]
  ------------------
 1474|       |  // This loop prints a number in reverse order. I guess this is because we
 1475|       |  // write numbers from right to left: least significant digit comes last.
 1476|       |  // Maybe because we use Arabic numbers, and Arabs write RTL?
 1477|  13.4M|  if (is_hex) {
  ------------------
  |  Branch (1477:7): [True: 0, False: 13.4M]
  ------------------
 1478|      0|    for (n = 0; v; v >>= 4) buf[s + n++] = letters[v & 15];
  ------------------
  |  Branch (1478:17): [True: 0, False: 0]
  ------------------
 1479|  13.4M|  } else {
 1480|   109M|    for (n = 0; v; v /= 10) buf[s + n++] = letters[v % 10];
  ------------------
  |  Branch (1480:17): [True: 96.2M, False: 13.4M]
  ------------------
 1481|  13.4M|  }
 1482|       |  // Reverse a string
 1483|  59.1M|  for (i = 0; i < n / 2; i++) {
  ------------------
  |  Branch (1483:15): [True: 45.7M, False: 13.4M]
  ------------------
 1484|  45.7M|    char t = buf[s + i];
 1485|  45.7M|    buf[s + i] = buf[s + n - i - 1], buf[s + n - i - 1] = t;
 1486|  45.7M|  }
 1487|  13.4M|  if (val == 0) buf[n++] = '0';  // Handle special case
  ------------------
  |  Branch (1487:7): [True: 252, False: 13.4M]
  ------------------
 1488|  13.4M|  return n + s;
 1489|  13.4M|}
fuzz.c:_ZL4scpyPFvcPvES_Pcm:
 1492|  66.4M|                          size_t len) {
 1493|  66.4M|  size_t i = 0;
 1494|   713M|  while (i < len && buf[i] != '\0') out(buf[i++], ptr);
  ------------------
  |  Branch (1494:10): [True: 647M, False: 66.4M]
  |  Branch (1494:21): [True: 647M, False: 92]
  ------------------
 1495|  66.4M|  return i;
 1496|  66.4M|}
fuzz.c:_ZL6p_statPKcPmPl:
 1963|  5.27M|static int p_stat(const char *path, size_t *size, time_t *mtime) {
 1964|       |#if !defined(S_ISDIR)
 1965|       |  MG_ERROR(("stat() API is not supported. %p %p %p", path, size, mtime));
 1966|       |  return 0;
 1967|       |#else
 1968|       |#if MG_ARCH == MG_ARCH_WIN32
 1969|       |  struct _stati64 st;
 1970|       |  wchar_t tmp[MG_PATH_MAX];
 1971|       |  MultiByteToWideChar(CP_UTF8, 0, path, -1, tmp, sizeof(tmp) / sizeof(tmp[0]));
 1972|       |  if (_wstati64(tmp, &st) != 0) return 0;
 1973|       |  // If path is a symlink, windows reports 0 in st.st_size.
 1974|       |  // Get a real file size by opening it and jumping to the end
 1975|       |  if (st.st_size == 0 && (st.st_mode & _S_IFREG)) {
 1976|       |    FILE *fp = _wfopen(tmp, L"rb");
 1977|       |    if (fp != NULL) {
 1978|       |      fseek(fp, 0, SEEK_END);
 1979|       |      if (ftell(fp) > 0) st.st_size = ftell(fp);  // Use _ftelli64 on win10+
 1980|       |      fclose(fp);
 1981|       |    }
 1982|       |  }
 1983|       |#else
 1984|  5.27M|  struct MG_STAT_STRUCT st;
 1985|  5.27M|  if (MG_STAT_FUNC(path, &st) != 0) return 0;
  ------------------
  |  | 1960|  5.27M|#define MG_STAT_FUNC stat
  ------------------
  |  Branch (1985:7): [True: 1.00M, False: 4.27M]
  ------------------
 1986|  4.27M|#endif
 1987|  4.27M|  if (size) *size = (size_t) st.st_size;
  ------------------
  |  Branch (1987:7): [True: 4.12M, False: 150k]
  ------------------
 1988|  4.27M|  if (mtime) *mtime = st.st_mtime;
  ------------------
  |  Branch (1988:7): [True: 4.12M, False: 150k]
  ------------------
 1989|  4.27M|  return MG_FS_READ | MG_FS_WRITE | (S_ISDIR(st.st_mode) ? MG_FS_DIR : 0);
 1990|  5.27M|#endif
 1991|  5.27M|}
fuzz.c:_ZL6p_listPKcPFvS0_PvES1_:
 2105|   316k|                   void *userdata) {
 2106|   316k|#if MG_ENABLE_DIRLIST
 2107|   316k|  struct dirent *dp;
 2108|   316k|  DIR *dirp;
 2109|   316k|  if ((dirp = (opendir(dir))) == NULL) return;
  ------------------
  |  Branch (2109:7): [True: 0, False: 316k]
  ------------------
 2110|  5.07M|  while ((dp = readdir(dirp)) != NULL) {
  ------------------
  |  Branch (2110:10): [True: 4.75M, False: 316k]
  ------------------
 2111|  4.75M|    if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
  ------------------
  |  Branch (2111:9): [True: 316k, False: 4.43M]
  |  Branch (2111:37): [True: 316k, False: 4.12M]
  ------------------
 2112|  4.12M|    fn(dp->d_name, userdata);
 2113|  4.12M|  }
 2114|   316k|  closedir(dirp);
 2115|       |#else
 2116|       |  (void) dir, (void) fn, (void) userdata;
 2117|       |#endif
 2118|   316k|}
fuzz.c:_ZL6p_openPKci:
 2120|  52.5k|static void *p_open(const char *path, int flags) {
 2121|       |#if MG_ARCH == MG_ARCH_WIN32
 2122|       |  const char *mode = flags == MG_FS_READ ? "rb" : "a+b";
 2123|       |  wchar_t b1[MG_PATH_MAX], b2[10];
 2124|       |  MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
 2125|       |  MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
 2126|       |  return (void *) _wfopen(b1, b2);
 2127|       |#else
 2128|  52.5k|  const char *mode = flags == MG_FS_READ ? "rbe" : "a+be";  // e for CLOEXEC
  ------------------
  |  Branch (2128:22): [True: 52.5k, False: 0]
  ------------------
 2129|  52.5k|  return (void *) fopen(path, mode);
 2130|  52.5k|#endif
 2131|  52.5k|}
fuzz.c:_ZL11mg_ncasecmpPKcS0_m:
 2230|   883k|static int mg_ncasecmp(const char *s1, const char *s2, size_t len) {
 2231|   883k|  int diff = 0;
 2232|  1.02M|  if (len > 0) do {
  ------------------
  |  Branch (2232:7): [True: 883k, False: 0]
  ------------------
 2233|  1.02M|      int c = *s1++, d = *s2++;
 2234|  1.02M|      if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
  ------------------
  |  Branch (2234:11): [True: 508k, False: 517k]
  |  Branch (2234:23): [True: 88.1k, False: 420k]
  ------------------
 2235|  1.02M|      if (d >= 'A' && d <= 'Z') d += 'a' - 'A';
  ------------------
  |  Branch (2235:11): [True: 1.01M, False: 13.6k]
  |  Branch (2235:23): [True: 821k, False: 190k]
  ------------------
 2236|  1.02M|      diff = c - d;
 2237|  1.02M|    } while (diff == 0 && s1[-1] != '\0' && --len > 0);
  ------------------
  |  Branch (2237:14): [True: 151k, False: 874k]
  |  Branch (2237:27): [True: 151k, False: 0]
  |  Branch (2237:45): [True: 142k, False: 9.05k]
  ------------------
 2238|   883k|  return diff;
 2239|   883k|}
fuzz.c:_ZL3isxi:
 2376|   197k|static bool isx(int c) {
 2377|   197k|  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
  ------------------
  |  Branch (2377:11): [True: 193k, False: 3.62k]
  |  Branch (2377:23): [True: 57.5k, False: 136k]
  |  Branch (2377:37): [True: 104k, False: 35.9k]
  |  Branch (2377:49): [True: 22.5k, False: 81.4k]
  ------------------
 2378|   197k|         (c >= 'A' && c <= 'F');
  ------------------
  |  Branch (2378:11): [True: 113k, False: 3.76k]
  |  Branch (2378:23): [True: 31.9k, False: 81.7k]
  ------------------
 2379|   197k|}
fuzz.c:_ZL4isokh:
 2403|   153M|static bool isok(uint8_t c) {
 2404|   153M|  return c == '\n' || c == '\r' || c == '\t' || c >= ' ';
  ------------------
  |  Branch (2404:10): [True: 872k, False: 153M]
  |  Branch (2404:23): [True: 3.89k, False: 153M]
  |  Branch (2404:36): [True: 42.2k, False: 153M]
  |  Branch (2404:49): [True: 153M, False: 2.13k]
  ------------------
 2405|   153M|}
fuzz.c:_ZL4clenPKcS0_:
 2432|  42.0M|static size_t clen(const char *s, const char *end) {
 2433|  42.0M|  const unsigned char *u = (unsigned char *) s, c = *u;
 2434|  42.0M|  long n = (long) (end - s);
 2435|  42.0M|  if (c > ' ' && c < '~') return 1;  // Usual ascii printed char
  ------------------
  |  Branch (2435:7): [True: 41.3M, False: 681k]
  |  Branch (2435:18): [True: 41.2M, False: 139k]
  ------------------
 2436|   820k|  if ((c & 0xe0) == 0xc0 && n > 1 && vcb(u[1])) return 2;  // 2-byte UTF8
  ------------------
  |  Branch (2436:7): [True: 13.5k, False: 807k]
  |  Branch (2436:29): [True: 13.5k, False: 0]
  |  Branch (2436:38): [True: 10.9k, False: 2.56k]
  ------------------
 2437|   809k|  if ((c & 0xf0) == 0xe0 && n > 2 && vcb(u[1]) && vcb(u[2])) return 3;
  ------------------
  |  Branch (2437:7): [True: 4.78k, False: 805k]
  |  Branch (2437:29): [True: 4.78k, False: 0]
  |  Branch (2437:38): [True: 3.79k, False: 993]
  |  Branch (2437:51): [True: 3.53k, False: 259]
  ------------------
 2438|   806k|  if ((c & 0xf8) == 0xf0 && n > 3 && vcb(u[1]) && vcb(u[2]) && vcb(u[3]))
  ------------------
  |  Branch (2438:7): [True: 10.0k, False: 796k]
  |  Branch (2438:29): [True: 9.64k, False: 442]
  |  Branch (2438:38): [True: 7.13k, False: 2.50k]
  |  Branch (2438:51): [True: 6.33k, False: 802]
  |  Branch (2438:64): [True: 6.00k, False: 331]
  ------------------
 2439|  6.00k|    return 4;
 2440|   800k|  return 0;
 2441|   806k|}
fuzz.c:_ZL3vcbh:
 2427|  45.2k|static bool vcb(uint8_t c) {
 2428|  45.2k|  return (c & 0xc0) == 0x80;
 2429|  45.2k|}
fuzz.c:_ZL8skiptornPKcS0_P6mg_str:
 2444|   426k|static const char *skiptorn(const char *s, const char *end, struct mg_str *v) {
 2445|   426k|  v->buf = (char *) s;
 2446|  32.7M|  while (s < end && s[0] != '\n' && s[0] != '\r') s++, v->len++;  // To newline
  ------------------
  |  Branch (2446:10): [True: 32.7M, False: 0]
  |  Branch (2446:21): [True: 32.3M, False: 425k]
  |  Branch (2446:37): [True: 32.3M, False: 1.44k]
  ------------------
 2447|   426k|  if (s >= end || (s[0] == '\r' && s[1] != '\n')) return NULL;    // Stray \r
  ------------------
  |  Branch (2447:7): [True: 0, False: 426k]
  |  Branch (2447:20): [True: 1.44k, False: 425k]
  |  Branch (2447:36): [True: 290, False: 1.15k]
  ------------------
 2448|   426k|  if (s < end && s[0] == '\r') s++;                               // Skip \r
  ------------------
  |  Branch (2448:7): [True: 426k, False: 0]
  |  Branch (2448:18): [True: 1.15k, False: 425k]
  ------------------
 2449|   426k|  if (s >= end || *s++ != '\n') return NULL;                      // Skip \n
  ------------------
  |  Branch (2449:7): [True: 0, False: 426k]
  |  Branch (2449:19): [True: 0, False: 426k]
  ------------------
 2450|   426k|  return s;
 2451|   426k|}
fuzz.c:_ZL21mg_http_parse_headersPKcS0_P14mg_http_headerm:
 2454|   399k|                                  struct mg_http_header *h, size_t max_hdrs) {
 2455|   399k|  size_t i, n;
 2456|   425k|  for (i = 0; i < max_hdrs; i++) {
  ------------------
  |  Branch (2456:15): [True: 425k, False: 428]
  ------------------
 2457|   425k|    struct mg_str k = {NULL, 0}, v = {NULL, 0};
 2458|   425k|    if (s >= end) return false;
  ------------------
  |  Branch (2458:9): [True: 0, False: 425k]
  ------------------
 2459|   425k|    if (s[0] == '\n' || (s[0] == '\r' && s[1] == '\n')) break;
  ------------------
  |  Branch (2459:9): [True: 397k, False: 28.0k]
  |  Branch (2459:26): [True: 1.03k, False: 26.9k]
  |  Branch (2459:42): [True: 1.02k, False: 8]
  ------------------
 2460|  26.9k|    k.buf = (char *) s;
 2461|  13.4M|    while (s < end && s[0] != ':' && (n = clen(s, end)) > 0) s += n, k.len += n;
  ------------------
  |  Branch (2461:12): [True: 13.4M, False: 0]
  |  Branch (2461:23): [True: 13.4M, False: 26.6k]
  |  Branch (2461:38): [True: 13.4M, False: 326]
  ------------------
 2462|  26.9k|    if (k.len == 0) return false;                     // Empty name
  ------------------
  |  Branch (2462:9): [True: 85, False: 26.9k]
  ------------------
 2463|  26.9k|    if (s >= end || clen(s, end) == 0) return false;  // Invalid UTF-8
  ------------------
  |  Branch (2463:9): [True: 0, False: 26.9k]
  |  Branch (2463:21): [True: 248, False: 26.6k]
  ------------------
 2464|  26.6k|    if (*s++ != ':') return false;  // Invalid, not followed by :
  ------------------
  |  Branch (2464:9): [True: 0, False: 26.6k]
  ------------------
 2465|       |    // if (clen(s, end) == 0) return false;        // Invalid UTF-8
 2466|  27.7k|    while (s < end && (s[0] == ' ' || s[0] == '\t')) s++;  // Skip spaces
  ------------------
  |  Branch (2466:12): [True: 27.7k, False: 0]
  |  Branch (2466:24): [True: 934, False: 26.8k]
  |  Branch (2466:39): [True: 180, False: 26.6k]
  ------------------
 2467|  26.6k|    if ((s = skiptorn(s, end, &v)) == NULL) return false;
  ------------------
  |  Branch (2467:9): [True: 11, False: 26.6k]
  ------------------
 2468|  27.6k|    while (v.len > 0 && (v.buf[v.len - 1] == ' ' || v.buf[v.len - 1] == '\t')) {
  ------------------
  |  Branch (2468:12): [True: 9.04k, False: 18.6k]
  |  Branch (2468:26): [True: 536, False: 8.51k]
  |  Branch (2468:53): [True: 472, False: 8.04k]
  ------------------
 2469|  1.00k|      v.len--;  // Trim spaces
 2470|  1.00k|    }
 2471|       |    // MG_INFO(("--HH [%.*s] [%.*s]", (int) k.len, k.buf, (int) v.len, v.buf));
 2472|  26.6k|    h[i].name = k, h[i].value = v;  // Success. Assign values
 2473|  26.6k|  }
 2474|   398k|  return true;
 2475|   399k|}
fuzz.c:_ZL23mg_http_status_code_stri:
 2578|  53.9k|static const char *mg_http_status_code_str(int status_code) {
 2579|  53.9k|  switch (status_code) {
 2580|      0|    case 100: return "Continue";
  ------------------
  |  Branch (2580:5): [True: 0, False: 53.9k]
  ------------------
 2581|      0|    case 101: return "Switching Protocols";
  ------------------
  |  Branch (2581:5): [True: 0, False: 53.9k]
  ------------------
 2582|      0|    case 102: return "Processing";
  ------------------
  |  Branch (2582:5): [True: 0, False: 53.9k]
  ------------------
 2583|      0|    case 200: return "OK";
  ------------------
  |  Branch (2583:5): [True: 0, False: 53.9k]
  ------------------
 2584|      0|    case 201: return "Created";
  ------------------
  |  Branch (2584:5): [True: 0, False: 53.9k]
  ------------------
 2585|      0|    case 202: return "Accepted";
  ------------------
  |  Branch (2585:5): [True: 0, False: 53.9k]
  ------------------
 2586|      0|    case 203: return "Non-authoritative Information";
  ------------------
  |  Branch (2586:5): [True: 0, False: 53.9k]
  ------------------
 2587|      0|    case 204: return "No Content";
  ------------------
  |  Branch (2587:5): [True: 0, False: 53.9k]
  ------------------
 2588|      0|    case 205: return "Reset Content";
  ------------------
  |  Branch (2588:5): [True: 0, False: 53.9k]
  ------------------
 2589|      0|    case 206: return "Partial Content";
  ------------------
  |  Branch (2589:5): [True: 0, False: 53.9k]
  ------------------
 2590|      0|    case 207: return "Multi-Status";
  ------------------
  |  Branch (2590:5): [True: 0, False: 53.9k]
  ------------------
 2591|      0|    case 208: return "Already Reported";
  ------------------
  |  Branch (2591:5): [True: 0, False: 53.9k]
  ------------------
 2592|      0|    case 226: return "IM Used";
  ------------------
  |  Branch (2592:5): [True: 0, False: 53.9k]
  ------------------
 2593|      0|    case 300: return "Multiple Choices";
  ------------------
  |  Branch (2593:5): [True: 0, False: 53.9k]
  ------------------
 2594|      0|    case 301: return "Moved Permanently";
  ------------------
  |  Branch (2594:5): [True: 0, False: 53.9k]
  ------------------
 2595|      0|    case 302: return "Found";
  ------------------
  |  Branch (2595:5): [True: 0, False: 53.9k]
  ------------------
 2596|      0|    case 303: return "See Other";
  ------------------
  |  Branch (2596:5): [True: 0, False: 53.9k]
  ------------------
 2597|      0|    case 304: return "Not Modified";
  ------------------
  |  Branch (2597:5): [True: 0, False: 53.9k]
  ------------------
 2598|      0|    case 305: return "Use Proxy";
  ------------------
  |  Branch (2598:5): [True: 0, False: 53.9k]
  ------------------
 2599|      0|    case 307: return "Temporary Redirect";
  ------------------
  |  Branch (2599:5): [True: 0, False: 53.9k]
  ------------------
 2600|      0|    case 308: return "Permanent Redirect";
  ------------------
  |  Branch (2600:5): [True: 0, False: 53.9k]
  ------------------
 2601|  1.44k|    case 400: return "Bad Request";
  ------------------
  |  Branch (2601:5): [True: 1.44k, False: 52.5k]
  ------------------
 2602|      0|    case 401: return "Unauthorized";
  ------------------
  |  Branch (2602:5): [True: 0, False: 53.9k]
  ------------------
 2603|      0|    case 402: return "Payment Required";
  ------------------
  |  Branch (2603:5): [True: 0, False: 53.9k]
  ------------------
 2604|      0|    case 403: return "Forbidden";
  ------------------
  |  Branch (2604:5): [True: 0, False: 53.9k]
  ------------------
 2605|  52.2k|    case 404: return "Not Found";
  ------------------
  |  Branch (2605:5): [True: 52.2k, False: 1.69k]
  ------------------
 2606|      0|    case 405: return "Method Not Allowed";
  ------------------
  |  Branch (2606:5): [True: 0, False: 53.9k]
  ------------------
 2607|      0|    case 406: return "Not Acceptable";
  ------------------
  |  Branch (2607:5): [True: 0, False: 53.9k]
  ------------------
 2608|      0|    case 407: return "Proxy Authentication Required";
  ------------------
  |  Branch (2608:5): [True: 0, False: 53.9k]
  ------------------
 2609|      0|    case 408: return "Request Timeout";
  ------------------
  |  Branch (2609:5): [True: 0, False: 53.9k]
  ------------------
 2610|      0|    case 409: return "Conflict";
  ------------------
  |  Branch (2610:5): [True: 0, False: 53.9k]
  ------------------
 2611|      0|    case 410: return "Gone";
  ------------------
  |  Branch (2611:5): [True: 0, False: 53.9k]
  ------------------
 2612|    252|    case 411: return "Length Required";
  ------------------
  |  Branch (2612:5): [True: 252, False: 53.7k]
  ------------------
 2613|      0|    case 412: return "Precondition Failed";
  ------------------
  |  Branch (2613:5): [True: 0, False: 53.9k]
  ------------------
 2614|      0|    case 413: return "Payload Too Large";
  ------------------
  |  Branch (2614:5): [True: 0, False: 53.9k]
  ------------------
 2615|      0|    case 414: return "Request-URI Too Long";
  ------------------
  |  Branch (2615:5): [True: 0, False: 53.9k]
  ------------------
 2616|      0|    case 415: return "Unsupported Media Type";
  ------------------
  |  Branch (2616:5): [True: 0, False: 53.9k]
  ------------------
 2617|      0|    case 416: return "Requested Range Not Satisfiable";
  ------------------
  |  Branch (2617:5): [True: 0, False: 53.9k]
  ------------------
 2618|      0|    case 417: return "Expectation Failed";
  ------------------
  |  Branch (2618:5): [True: 0, False: 53.9k]
  ------------------
 2619|      0|    case 418: return "I'm a teapot";
  ------------------
  |  Branch (2619:5): [True: 0, False: 53.9k]
  ------------------
 2620|      0|    case 421: return "Misdirected Request";
  ------------------
  |  Branch (2620:5): [True: 0, False: 53.9k]
  ------------------
 2621|      0|    case 422: return "Unprocessable Entity";
  ------------------
  |  Branch (2621:5): [True: 0, False: 53.9k]
  ------------------
 2622|      0|    case 423: return "Locked";
  ------------------
  |  Branch (2622:5): [True: 0, False: 53.9k]
  ------------------
 2623|      0|    case 424: return "Failed Dependency";
  ------------------
  |  Branch (2623:5): [True: 0, False: 53.9k]
  ------------------
 2624|      0|    case 426: return "Upgrade Required";
  ------------------
  |  Branch (2624:5): [True: 0, False: 53.9k]
  ------------------
 2625|      0|    case 428: return "Precondition Required";
  ------------------
  |  Branch (2625:5): [True: 0, False: 53.9k]
  ------------------
 2626|      0|    case 429: return "Too Many Requests";
  ------------------
  |  Branch (2626:5): [True: 0, False: 53.9k]
  ------------------
 2627|      0|    case 431: return "Request Header Fields Too Large";
  ------------------
  |  Branch (2627:5): [True: 0, False: 53.9k]
  ------------------
 2628|      0|    case 444: return "Connection Closed Without Response";
  ------------------
  |  Branch (2628:5): [True: 0, False: 53.9k]
  ------------------
 2629|      0|    case 451: return "Unavailable For Legal Reasons";
  ------------------
  |  Branch (2629:5): [True: 0, False: 53.9k]
  ------------------
 2630|      0|    case 499: return "Client Closed Request";
  ------------------
  |  Branch (2630:5): [True: 0, False: 53.9k]
  ------------------
 2631|      0|    case 500: return "Internal Server Error";
  ------------------
  |  Branch (2631:5): [True: 0, False: 53.9k]
  ------------------
 2632|      0|    case 501: return "Not Implemented";
  ------------------
  |  Branch (2632:5): [True: 0, False: 53.9k]
  ------------------
 2633|      0|    case 502: return "Bad Gateway";
  ------------------
  |  Branch (2633:5): [True: 0, False: 53.9k]
  ------------------
 2634|      0|    case 503: return "Service Unavailable";
  ------------------
  |  Branch (2634:5): [True: 0, False: 53.9k]
  ------------------
 2635|      0|    case 504: return "Gateway Timeout";
  ------------------
  |  Branch (2635:5): [True: 0, False: 53.9k]
  ------------------
 2636|      0|    case 505: return "HTTP Version Not Supported";
  ------------------
  |  Branch (2636:5): [True: 0, False: 53.9k]
  ------------------
 2637|      0|    case 506: return "Variant Also Negotiates";
  ------------------
  |  Branch (2637:5): [True: 0, False: 53.9k]
  ------------------
 2638|      0|    case 507: return "Insufficient Storage";
  ------------------
  |  Branch (2638:5): [True: 0, False: 53.9k]
  ------------------
 2639|      0|    case 508: return "Loop Detected";
  ------------------
  |  Branch (2639:5): [True: 0, False: 53.9k]
  ------------------
 2640|      0|    case 510: return "Not Extended";
  ------------------
  |  Branch (2640:5): [True: 0, False: 53.9k]
  ------------------
 2641|      0|    case 511: return "Network Authentication Required";
  ------------------
  |  Branch (2641:5): [True: 0, False: 53.9k]
  ------------------
 2642|      0|    case 599: return "Network Connect Timeout Error";
  ------------------
  |  Branch (2642:5): [True: 0, False: 53.9k]
  ------------------
 2643|      0|    default: return "";
  ------------------
  |  Branch (2643:5): [True: 0, False: 53.9k]
  ------------------
 2644|  53.9k|  }
 2645|  53.9k|}
fuzz.c:_ZL18guess_content_type6mg_strPKc:
 2739|  52.2k|static struct mg_str guess_content_type(struct mg_str path, const char *extra) {
 2740|  52.2k|  struct mg_str entry, k, v, s = mg_str(extra);
  ------------------
  |  |  859|  52.2k|#define mg_str(s) mg_str_s(s)
  ------------------
 2741|  52.2k|  size_t i = 0;
 2742|       |
 2743|       |  // Shrink path to its extension only
 2744|  2.22M|  while (i < path.len && path.buf[path.len - i - 1] != '.') i++;
  ------------------
  |  Branch (2744:10): [True: 2.22M, False: 0]
  |  Branch (2744:26): [True: 2.16M, False: 52.2k]
  ------------------
 2745|  52.2k|  path.buf += path.len - i;
 2746|  52.2k|  path.len = i;
 2747|       |
 2748|       |  // Process user-provided mime type overrides, if any
 2749|  52.2k|  while (mg_span(s, &entry, &s, ',')) {
  ------------------
  |  Branch (2749:10): [True: 0, False: 52.2k]
  ------------------
 2750|      0|    if (mg_span(entry, &k, &v, '=') && mg_strcmp(path, k) == 0) return v;
  ------------------
  |  Branch (2750:9): [True: 0, False: 0]
  |  Branch (2750:40): [True: 0, False: 0]
  ------------------
 2751|      0|  }
 2752|       |
 2753|       |  // Process built-in mime types
 2754|  1.53M|  for (i = 0; s_known_types[i].buf != NULL; i += 2) {
  ------------------
  |  Branch (2754:15): [True: 1.49M, False: 46.6k]
  ------------------
 2755|  1.49M|    if (mg_strcmp(path, s_known_types[i]) == 0) return s_known_types[i + 1];
  ------------------
  |  Branch (2755:9): [True: 5.62k, False: 1.48M]
  ------------------
 2756|  1.49M|  }
 2757|       |
 2758|  46.6k|  return mg_str("text/plain; charset=utf-8");
  ------------------
  |  |  859|  46.6k|#define mg_str(s) mg_str_s(s)
  ------------------
 2759|  52.2k|}
fuzz.c:_ZL11uri_to_pathP13mg_connectionP15mg_http_messagePK18mg_http_serve_optsPcm:
 3048|   395k|                       size_t path_size) {
 3049|   395k|  struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  ------------------
  |  Branch (3049:22): [True: 395k, False: 0]
  ------------------
 3050|   395k|  struct mg_str k, v, part, s = mg_str(opts->root_dir), u = {NULL, 0}, p = u;
  ------------------
  |  |  859|   395k|#define mg_str(s) mg_str_s(s)
  ------------------
 3051|   790k|  while (mg_span(s, &part, &s, ',')) {
  ------------------
  |  Branch (3051:10): [True: 395k, False: 395k]
  ------------------
 3052|   395k|    if (!mg_span(part, &k, &v, '=')) k = part, v = mg_str_n(NULL, 0);
  ------------------
  |  Branch (3052:9): [True: 0, False: 395k]
  ------------------
 3053|   395k|    if (v.len == 0) v = k, k = mg_str("/"), u = k, p = v;
  ------------------
  |  |  859|   395k|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (3053:9): [True: 395k, False: 0]
  ------------------
 3054|   395k|    if (hm->uri.len < k.len) continue;
  ------------------
  |  Branch (3054:9): [True: 0, False: 395k]
  ------------------
 3055|   395k|    if (mg_strcmp(k, mg_str_n(hm->uri.buf, k.len)) != 0) continue;
  ------------------
  |  Branch (3055:9): [True: 41.8k, False: 353k]
  ------------------
 3056|   353k|    u = k, p = v;
 3057|   353k|  }
 3058|   395k|  return uri_to_path2(c, hm, fs, u, p, path, path_size);
 3059|   395k|}
fuzz.c:_ZL12uri_to_path2P13mg_connectionP15mg_http_messageP5mg_fs6mg_strS5_Pcm:
 2988|   395k|                        char *path, size_t path_size) {
 2989|   395k|  int flags, tmp;
 2990|       |  // Append URI to the root_dir, and sanitize it
 2991|   395k|  size_t n = mg_snprintf(path, path_size, "%.*s", (int) dir.len, dir.buf);
 2992|   395k|  if (n + 2 >= path_size) {
  ------------------
  |  Branch (2992:7): [True: 0, False: 395k]
  ------------------
 2993|      0|    mg_http_reply(c, 400, "", "Exceeded path size");
 2994|      0|    return -1;
 2995|      0|  }
 2996|   395k|  path[path_size - 1] = '\0';
 2997|       |  // Terminate root dir with slash
 2998|   395k|  if (n > 0 && path[n - 1] != '/') path[n++] = '/', path[n] = '\0';
  ------------------
  |  Branch (2998:7): [True: 395k, False: 0]
  |  Branch (2998:16): [True: 395k, False: 0]
  ------------------
 2999|   395k|  if (url.len < hm->uri.len) {
  ------------------
  |  Branch (2999:7): [True: 197k, False: 198k]
  ------------------
 3000|   197k|    mg_url_decode(hm->uri.buf + url.len, hm->uri.len - url.len, path + n,
 3001|   197k|                  path_size - n, 0);
 3002|   197k|  }
 3003|   395k|  path[path_size - 1] = '\0';  // Double-check
 3004|   395k|  if (!mg_path_is_sane(mg_str_n(path, path_size))) {
  ------------------
  |  Branch (3004:7): [True: 1.44k, False: 393k]
  ------------------
 3005|  1.44k|    mg_http_reply(c, 400, "", "Invalid path");
 3006|  1.44k|    return -1;
 3007|  1.44k|  }
 3008|   393k|  n = strlen(path);
 3009|  1.10M|  while (n > 1 && path[n - 1] == '/') path[--n] = 0;  // Trim trailing slashes
  ------------------
  |  Branch (3009:10): [True: 761k, False: 339k]
  |  Branch (3009:19): [True: 707k, False: 53.8k]
  ------------------
 3010|   393k|  flags = mg_strcmp(hm->uri, mg_str("/")) == 0 ? MG_FS_DIR
  ------------------
  |  |  859|   393k|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (3010:11): [True: 190k, False: 203k]
  ------------------
 3011|   393k|                                               : fs->st(path, NULL, NULL);
 3012|   393k|  MG_VERBOSE(("%lu %.*s -> %s %d", c->id, (int) hm->uri.len, hm->uri.buf, path,
  ------------------
  |  |  963|   393k|#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  |  |  ------------------
  |  |  |  |  955|   393k|  do {                      \
  |  |  |  |  956|   393k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|   393k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3013|   393k|              flags));
 3014|   393k|  if (flags == 0) {
  ------------------
  |  Branch (3014:7): [True: 52.2k, False: 341k]
  ------------------
 3015|       |    // Do nothing - let's caller decide
 3016|   341k|  } else if ((flags & MG_FS_DIR) && hm->uri.len > 0 &&
  ------------------
  |  Branch (3016:14): [True: 341k, False: 0]
  |  Branch (3016:37): [True: 341k, False: 0]
  ------------------
 3017|   341k|             hm->uri.buf[hm->uri.len - 1] != '/') {
  ------------------
  |  Branch (3017:14): [True: 24.5k, False: 316k]
  ------------------
 3018|  24.5k|    mg_printf(c,
 3019|  24.5k|              "HTTP/1.1 301 Moved\r\n"
 3020|  24.5k|              "Location: %.*s/\r\n"
 3021|  24.5k|              "Content-Length: 0\r\n"
 3022|  24.5k|              "\r\n",
 3023|  24.5k|              (int) hm->uri.len, hm->uri.buf);
 3024|  24.5k|    c->is_resp = 0;
 3025|  24.5k|    flags = -1;
 3026|   316k|  } else if (flags & MG_FS_DIR) {
  ------------------
  |  Branch (3026:14): [True: 316k, False: 0]
  ------------------
 3027|   316k|    if (((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX) > 0 &&
  ------------------
  |  |  765|   316k|#define MG_HTTP_INDEX "index.html"
  ------------------
  |  Branch (3027:11): [True: 316k, False: 0]
  ------------------
 3028|   316k|          (tmp = fs->st(path, NULL, NULL)) != 0) ||
  ------------------
  |  Branch (3028:11): [True: 7, False: 316k]
  ------------------
 3029|   316k|         (mg_snprintf(path + n, path_size - n, "/index.shtml") > 0 &&
  ------------------
  |  Branch (3029:11): [True: 316k, False: 0]
  ------------------
 3030|   316k|          (tmp = fs->st(path, NULL, NULL)) != 0))) {
  ------------------
  |  Branch (3030:11): [True: 0, False: 316k]
  ------------------
 3031|      7|      flags = tmp;
 3032|   316k|    } else if ((mg_snprintf(path + n, path_size - n, "/" MG_HTTP_INDEX ".gz") >
  ------------------
  |  Branch (3032:17): [True: 316k, False: 0]
  ------------------
 3033|   316k|                    0 &&
 3034|   316k|                (tmp = fs->st(path, NULL, NULL)) !=
  ------------------
  |  Branch (3034:17): [True: 0, False: 316k]
  ------------------
 3035|   316k|                    0)) {  // check for gzipped index
 3036|      0|      flags = tmp;
 3037|      0|      path[n + 1 + strlen(MG_HTTP_INDEX)] =
  ------------------
  |  |  765|      0|#define MG_HTTP_INDEX "index.html"
  ------------------
 3038|      0|          '\0';  // Remove appended .gz in index file name
 3039|   316k|    } else {
 3040|   316k|      path[n] = '\0';  // Remove appended index file name
 3041|   316k|    }
 3042|   316k|  }
 3043|   393k|  return flags;
 3044|   395k|}
fuzz.c:_ZL7listdirP13mg_connectionP15mg_http_messagePK18mg_http_serve_optsPc:
 2918|   316k|                    const struct mg_http_serve_opts *opts, char *dir) {
 2919|   316k|  const char *sort_js_code =
 2920|   316k|      "<script>function srt(tb, sc, so, d) {"
 2921|   316k|      "var tr = Array.prototype.slice.call(tb.rows, 0),"
 2922|   316k|      "tr = tr.sort(function (a, b) { var c1 = a.cells[sc], c2 = b.cells[sc],"
 2923|   316k|      "n1 = c1.getAttribute('name'), n2 = c2.getAttribute('name'), "
 2924|   316k|      "t1 = a.cells[2].getAttribute('name'), "
 2925|   316k|      "t2 = b.cells[2].getAttribute('name'); "
 2926|   316k|      "return so * (t1 < 0 && t2 >= 0 ? -1 : t2 < 0 && t1 >= 0 ? 1 : "
 2927|   316k|      "n1 ? parseInt(n2) - parseInt(n1) : "
 2928|   316k|      "c1.textContent.trim().localeCompare(c2.textContent.trim())); });";
 2929|   316k|  const char *sort_js_code2 =
 2930|   316k|      "for (var i = 0; i < tr.length; i++) tb.appendChild(tr[i]); "
 2931|   316k|      "if (!d) window.location.hash = ('sc=' + sc + '&so=' + so); "
 2932|   316k|      "};"
 2933|   316k|      "window.onload = function() {"
 2934|   316k|      "var tb = document.getElementById('tb');"
 2935|   316k|      "var m = /sc=([012]).so=(1|-1)/.exec(window.location.hash) || [0, 2, 1];"
 2936|   316k|      "var sc = m[1], so = m[2]; document.onclick = function(ev) { "
 2937|   316k|      "var c = ev.target.rel; if (c) {if (c == sc) so *= -1; srt(tb, c, so); "
 2938|   316k|      "sc = c; ev.preventDefault();}};"
 2939|   316k|      "srt(tb, sc, so, true);"
 2940|   316k|      "}"
 2941|   316k|      "</script>";
 2942|   316k|  struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
  ------------------
  |  Branch (2942:22): [True: 316k, False: 0]
  ------------------
 2943|   316k|  struct printdirentrydata d = {c, hm, opts, dir};
 2944|   316k|  char tmp[10], buf[MG_PATH_MAX];
 2945|   316k|  size_t off, n;
 2946|   316k|  int len = mg_url_decode(hm->uri.buf, hm->uri.len, buf, sizeof(buf), 0);
 2947|   316k|  struct mg_str uri = len > 0 ? mg_str_n(buf, (size_t) len) : hm->uri;
  ------------------
  |  Branch (2947:23): [True: 301k, False: 15.4k]
  ------------------
 2948|       |
 2949|   316k|  mg_printf(c,
 2950|   316k|            "HTTP/1.1 200 OK\r\n"
 2951|   316k|            "Content-Type: text/html; charset=utf-8\r\n"
 2952|   316k|            "%s"
 2953|   316k|            "Content-Length:         \r\n\r\n",
 2954|   316k|            opts->extra_headers == NULL ? "" : opts->extra_headers);
  ------------------
  |  Branch (2954:13): [True: 316k, False: 0]
  ------------------
 2955|   316k|  off = c->send.len;  // Start of body
 2956|   316k|  mg_printf(c,
 2957|   316k|            "<!DOCTYPE html><html><head><title>Index of %.*s</title>%s%s"
 2958|   316k|            "<style>th,td {text-align: left; padding-right: 1em; "
 2959|   316k|            "font-family: monospace; }</style></head>"
 2960|   316k|            "<body><h1>Index of %.*s</h1><table cellpadding=\"0\"><thead>"
 2961|   316k|            "<tr><th><a href=\"#\" rel=\"0\">Name</a></th><th>"
 2962|   316k|            "<a href=\"#\" rel=\"1\">Modified</a></th>"
 2963|   316k|            "<th><a href=\"#\" rel=\"2\">Size</a></th></tr>"
 2964|   316k|            "<tr><td colspan=\"3\"><hr></td></tr>"
 2965|   316k|            "</thead>"
 2966|   316k|            "<tbody id=\"tb\">\n",
 2967|   316k|            (int) uri.len, uri.buf, sort_js_code, sort_js_code2, (int) uri.len,
 2968|   316k|            uri.buf);
 2969|   316k|  mg_printf(c, "%s",
 2970|   316k|            "  <tr><td><a href=\"..\">..</a></td>"
 2971|   316k|            "<td name=-1></td><td name=-1>[DIR]</td></tr>\n");
 2972|       |
 2973|   316k|  fs->ls(dir, printdirentry, &d);
 2974|   316k|  mg_printf(c,
 2975|   316k|            "</tbody><tfoot><tr><td colspan=\"3\"><hr></td></tr></tfoot>"
 2976|   316k|            "</table><address>Mongoose v.%s</address></body></html>\n",
 2977|   316k|            MG_VERSION);
  ------------------
  |  |   23|   316k|#define MG_VERSION "7.14"
  ------------------
 2978|   316k|  n = mg_snprintf(tmp, sizeof(tmp), "%lu", (unsigned long) (c->send.len - off));
 2979|   316k|  if (n > sizeof(tmp)) n = 0;
  ------------------
  |  Branch (2979:7): [True: 0, False: 316k]
  ------------------
 2980|   316k|  memcpy(c->send.buf + off - 12, tmp, n);  // Set content length
 2981|   316k|  c->is_resp = 0;                          // Mark response end
 2982|   316k|}
fuzz.c:_ZL13printdirentryPKcPv:
 2877|  4.12M|static void printdirentry(const char *name, void *userdata) {
 2878|  4.12M|  struct printdirentrydata *d = (struct printdirentrydata *) userdata;
 2879|  4.12M|  struct mg_fs *fs = d->opts->fs == NULL ? &mg_fs_posix : d->opts->fs;
  ------------------
  |  Branch (2879:22): [True: 4.12M, False: 0]
  ------------------
 2880|  4.12M|  size_t size = 0;
 2881|  4.12M|  time_t t = 0;
 2882|  4.12M|  char path[MG_PATH_MAX], sz[40], mod[40];
 2883|  4.12M|  int flags, n = 0;
 2884|       |
 2885|       |  // MG_DEBUG(("[%s] [%s]", d->dir, name));
 2886|  4.12M|  if (mg_snprintf(path, sizeof(path), "%s%c%s", d->dir, '/', name) >
  ------------------
  |  Branch (2886:7): [True: 299, False: 4.12M]
  ------------------
 2887|  4.12M|      sizeof(path)) {
 2888|    299|    MG_ERROR(("%s truncated", name));
  ------------------
  |  |  960|    299|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|    299|  do {                      \
  |  |  |  |  956|    299|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|    299|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2889|  4.12M|  } else if ((flags = fs->st(path, &size, &t)) == 0) {
  ------------------
  |  Branch (2889:14): [True: 27, False: 4.12M]
  ------------------
 2890|     27|    MG_ERROR(("%lu stat(%s): %d", d->c->id, path, errno));
  ------------------
  |  |  960|     27|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|     27|  do {                      \
  |  |  |  |  956|     27|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|     27|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2891|  4.12M|  } else {
 2892|  4.12M|    const char *slash = flags & MG_FS_DIR ? "/" : "";
  ------------------
  |  Branch (2892:25): [True: 3.48M, False: 633k]
  ------------------
 2893|  4.12M|    if (flags & MG_FS_DIR) {
  ------------------
  |  Branch (2893:9): [True: 3.48M, False: 633k]
  ------------------
 2894|  3.48M|      mg_snprintf(sz, sizeof(sz), "%s", "[DIR]");
 2895|  3.48M|    } else {
 2896|   633k|      mg_snprintf(sz, sizeof(sz), "%lld", (uint64_t) size);
 2897|   633k|    }
 2898|       |#if defined(MG_HTTP_DIRLIST_TIME_FMT)
 2899|       |    {
 2900|       |      char time_str[40];
 2901|       |      struct tm *time_info = localtime(&t);
 2902|       |      strftime(time_str, sizeof time_str, "%Y/%m/%d %H:%M:%S", time_info);
 2903|       |      mg_snprintf(mod, sizeof(mod), "%s", time_str);
 2904|       |    }
 2905|       |#else
 2906|  4.12M|    mg_snprintf(mod, sizeof(mod), "%lu", (unsigned long) t);
 2907|  4.12M|#endif
 2908|  4.12M|    n = (int) mg_url_encode(name, strlen(name), path, sizeof(path));
 2909|  4.12M|    mg_printf(d->c,
 2910|  4.12M|              "  <tr><td><a href=\"%.*s%s\">%s%s</a></td>"
 2911|  4.12M|              "<td name=%lu>%s</td><td name=%lld>%s</td></tr>\n",
 2912|  4.12M|              n, path, slash, name, slash, (unsigned long) t, mod,
 2913|  4.12M|              flags & MG_FS_DIR ? (int64_t) -1 : (int64_t) size, sz);
  ------------------
  |  Branch (2913:15): [True: 3.48M, False: 633k]
  ------------------
 2914|  4.12M|  }
 2915|  4.12M|}
fuzz.c:_ZL14mg_is_url_safei:
 3081|  39.2M|static bool mg_is_url_safe(int c) {
 3082|  39.2M|  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
  ------------------
  |  Branch (3082:11): [True: 38.9M, False: 316k]
  |  Branch (3082:23): [True: 0, False: 38.9M]
  |  Branch (3082:37): [True: 36.4M, False: 2.85M]
  |  Branch (3082:49): [True: 36.4M, False: 0]
  ------------------
 3083|  39.2M|         (c >= 'A' && c <= 'Z') || c == '.' || c == '_' || c == '-' || c == '~';
  ------------------
  |  Branch (3083:11): [True: 2.53M, False: 316k]
  |  Branch (3083:23): [True: 0, False: 2.53M]
  |  Branch (3083:36): [True: 0, False: 2.85M]
  |  Branch (3083:48): [True: 2.53M, False: 316k]
  |  Branch (3083:60): [True: 316k, False: 0]
  |  Branch (3083:72): [True: 0, False: 0]
  ------------------
 3084|  39.2M|}
fuzz.c:_ZL7http_cbP13mg_connectioniPv:
 3217|   812k|static void http_cb(struct mg_connection *c, int ev, void *ev_data) {
 3218|   812k|  if (ev == MG_EV_READ || ev == MG_EV_CLOSE ||
  ------------------
  |  Branch (3218:7): [True: 5.02k, False: 807k]
  |  Branch (3218:27): [True: 5.02k, False: 802k]
  ------------------
 3219|   812k|      (ev == MG_EV_POLL && c->is_accepted && !c->is_draining &&
  ------------------
  |  Branch (3219:8): [True: 5.02k, False: 797k]
  |  Branch (3219:28): [True: 0, False: 5.02k]
  |  Branch (3219:46): [True: 0, False: 0]
  ------------------
 3220|   802k|       c->recv.len > 0)) {  // see #2796
  ------------------
  |  Branch (3220:8): [True: 0, False: 0]
  ------------------
 3221|  10.0k|    struct mg_http_message hm;
 3222|  10.0k|    size_t ofs = 0;  // Parsing offset
 3223|   405k|    while (c->is_resp == 0 && ofs < c->recv.len) {
  ------------------
  |  Branch (3223:12): [True: 405k, False: 0]
  |  Branch (3223:31): [True: 401k, False: 4.07k]
  ------------------
 3224|   401k|      const char *buf = (char *) c->recv.buf + ofs;
 3225|   401k|      int n = mg_http_parse(buf, c->recv.len - ofs, &hm);
 3226|   401k|      struct mg_str *te;  // Transfer - encoding header
 3227|   401k|      bool is_chunked = false;
 3228|   401k|      if (n < 0) {
  ------------------
  |  Branch (3228:11): [True: 1.68k, False: 399k]
  ------------------
 3229|       |        // We don't use mg_error() here, to avoid closing pipelined requests
 3230|       |        // prematurely, see #2592
 3231|  1.68k|        MG_ERROR(("HTTP parse, %lu bytes", c->recv.len));
  ------------------
  |  |  960|  1.68k|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|  1.68k|  do {                      \
  |  |  |  |  956|  1.68k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  1.68k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3232|  1.68k|        c->is_draining = 1;
 3233|  1.68k|        mg_hexdump(buf, c->recv.len - ofs > 16 ? 16 : c->recv.len - ofs);
  ------------------
  |  Branch (3233:25): [True: 1.03k, False: 647]
  ------------------
 3234|  1.68k|        c->recv.len = 0;
 3235|  1.68k|        return;
 3236|  1.68k|      }
 3237|   399k|      if (n == 0) break;                 // Request is not buffered yet
  ------------------
  |  Branch (3237:11): [True: 3.10k, False: 396k]
  ------------------
 3238|   396k|      mg_call(c, MG_EV_HTTP_HDRS, &hm);  // Got all HTTP headers
 3239|   396k|      if (ev == MG_EV_CLOSE) {           // If client did not set Content-Length
  ------------------
  |  Branch (3239:11): [True: 1.29k, False: 395k]
  ------------------
 3240|  1.29k|        hm.message.len = c->recv.len - ofs;  // and closes now, deliver MSG
 3241|  1.29k|        hm.body.len = hm.message.len - (size_t) (hm.body.buf - hm.message.buf);
 3242|  1.29k|      }
 3243|   396k|      if ((te = mg_http_get_header(&hm, "Transfer-Encoding")) != NULL) {
  ------------------
  |  Branch (3243:11): [True: 1.59k, False: 394k]
  ------------------
 3244|  1.59k|        if (mg_strcasecmp(*te, mg_str("chunked")) == 0) {
  ------------------
  |  |  859|  1.59k|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (3244:13): [True: 1.44k, False: 148]
  ------------------
 3245|  1.44k|          is_chunked = true;
 3246|  1.44k|        } else {
 3247|    148|          mg_error(c, "Invalid Transfer-Encoding");  // See #2460
 3248|    148|          return;
 3249|    148|        }
 3250|   394k|      } else if (mg_http_get_header(&hm, "Content-length") == NULL) {
  ------------------
  |  Branch (3250:18): [True: 393k, False: 934]
  ------------------
 3251|       |        // #2593: HTTP packets must contain either Transfer-Encoding or
 3252|       |        // Content-length
 3253|   393k|        bool is_response = mg_ncasecmp(hm.method.buf, "HTTP/", 5) == 0;
 3254|   393k|        bool require_content_len = false;
 3255|   393k|        if (!is_response && (mg_strcasecmp(hm.method, mg_str("POST")) == 0 ||
  ------------------
  |  |  859|   392k|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (3255:13): [True: 392k, False: 1.08k]
  |  Branch (3255:30): [True: 17, False: 392k]
  ------------------
 3256|   392k|                             mg_strcasecmp(hm.method, mg_str("PUT")) == 0)) {
  ------------------
  |  |  859|   392k|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (3256:30): [True: 104, False: 392k]
  ------------------
 3257|       |          // POST and PUT should include an entity body. Therefore, they should
 3258|       |          // contain a Content-length header. Other requests can also contain a
 3259|       |          // body, but their content has no defined semantics (RFC 7231)
 3260|    121|          require_content_len = true;
 3261|    121|          ofs += (size_t) n;  // this request has been processed
 3262|   393k|        } else if (is_response) {
  ------------------
  |  Branch (3262:20): [True: 1.08k, False: 392k]
  ------------------
 3263|       |          // HTTP spec 7.2 Entity body: All other responses must include a body
 3264|       |          // or Content-Length header field defined with a value of 0.
 3265|  1.08k|          int status = mg_http_status(&hm);
 3266|  1.08k|          require_content_len = status >= 200 && status != 204 && status != 304;
  ------------------
  |  Branch (3266:33): [True: 739, False: 349]
  |  Branch (3266:50): [True: 133, False: 606]
  |  Branch (3266:67): [True: 131, False: 2]
  ------------------
 3267|  1.08k|        }
 3268|   393k|        if (require_content_len) {
  ------------------
  |  Branch (3268:13): [True: 252, False: 393k]
  ------------------
 3269|    252|          mg_http_reply(c, 411, "", "");
 3270|    252|          MG_ERROR(("%s", "Content length missing from request"));
  ------------------
  |  |  960|    252|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|    252|  do {                      \
  |  |  |  |  956|    252|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|    252|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3271|    252|        }
 3272|   393k|      }
 3273|       |
 3274|   396k|      if (is_chunked) {
  ------------------
  |  Branch (3274:11): [True: 1.44k, False: 394k]
  ------------------
 3275|       |        // For chunked data, strip off prefixes and suffixes from chunks
 3276|       |        // and relocate them right after the headers, then report a message
 3277|  1.44k|        char *s = (char *) c->recv.buf + ofs + n;
 3278|  1.44k|        int o = 0, pl, dl, cl, len = (int) (c->recv.len - ofs - (size_t) n);
 3279|       |
 3280|       |        // Find zero-length chunk (the end of the body)
 3281|  2.32k|        while ((cl = skip_chunk(s + o, len - o, &pl, &dl)) > 0 && dl) o += cl;
  ------------------
  |  Branch (3281:16): [True: 1.89k, False: 431]
  |  Branch (3281:67): [True: 879, False: 1.01k]
  ------------------
 3282|  1.44k|        if (cl == 0) break;  // No zero-len chunk, buffer more data
  ------------------
  |  Branch (3282:13): [True: 158, False: 1.29k]
  ------------------
 3283|  1.29k|        if (cl < 0) {
  ------------------
  |  Branch (3283:13): [True: 273, False: 1.01k]
  ------------------
 3284|    273|          mg_error(c, "Invalid chunk");
 3285|    273|          break;
 3286|    273|        }
 3287|       |
 3288|       |        // Zero chunk found. Second pass: strip + relocate
 3289|  1.01k|        o = 0, hm.body.len = 0, hm.message.len = (size_t) n;
 3290|  1.23k|        while ((cl = skip_chunk(s + o, len - o, &pl, &dl)) > 0) {
  ------------------
  |  Branch (3290:16): [True: 1.23k, False: 0]
  ------------------
 3291|  1.23k|          memmove(s + hm.body.len, s + o + pl, (size_t) dl);
 3292|  1.23k|          o += cl, hm.body.len += (size_t) dl, hm.message.len += (size_t) dl;
 3293|  1.23k|          if (dl == 0) break;
  ------------------
  |  Branch (3293:15): [True: 1.01k, False: 221]
  ------------------
 3294|  1.23k|        }
 3295|  1.01k|        ofs += (size_t) (n + o);
 3296|   394k|      } else {  // Normal, non-chunked data
 3297|   394k|        size_t len = c->recv.len - ofs - (size_t) n;
 3298|   394k|        if (hm.body.len > len) break;  // Buffer more data
  ------------------
  |  Branch (3298:13): [True: 623, False: 394k]
  ------------------
 3299|   394k|        ofs += (size_t) n + hm.body.len;
 3300|   394k|      }
 3301|       |
 3302|   395k|      if (c->is_accepted) c->is_resp = 1;  // Start generating response
  ------------------
  |  Branch (3302:11): [True: 0, False: 395k]
  ------------------
 3303|   395k|      mg_call(c, MG_EV_HTTP_MSG, &hm);     // User handler can clear is_resp
 3304|   395k|      if (c->is_accepted) {
  ------------------
  |  Branch (3304:11): [True: 0, False: 395k]
  ------------------
 3305|      0|        struct mg_str *cc = mg_http_get_header(&hm, "Connection");
 3306|      0|        if (cc != NULL && mg_strcasecmp(*cc, mg_str("close")) == 0) {
  ------------------
  |  |  859|      0|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (3306:13): [True: 0, False: 0]
  |  Branch (3306:27): [True: 0, False: 0]
  ------------------
 3307|      0|          c->is_draining = 1;  // honor "Connection: close"
 3308|      0|          break;
 3309|      0|        }
 3310|      0|      }
 3311|   395k|    }
 3312|  8.22k|    if (ofs > 0) mg_iobuf_del(&c->recv, 0, ofs);  // Delete processed data
  ------------------
  |  Branch (3312:9): [True: 1.86k, False: 6.36k]
  ------------------
 3313|  8.22k|  }
 3314|   810k|  (void) ev_data;
 3315|   810k|}
fuzz.c:_ZL10skip_chunkPKciPiS1_:
 3201|  3.56k|static int skip_chunk(const char *buf, int len, int *pl, int *dl) {
 3202|  3.56k|  int i = 0, n = 0;
 3203|  3.56k|  if (len < 3) return 0;
  ------------------
  |  Branch (3203:7): [True: 28, False: 3.53k]
  ------------------
 3204|  4.76M|  while (i < len && is_hex_digit(buf[i])) i++;
  ------------------
  |  Branch (3204:10): [True: 4.76M, False: 70]
  |  Branch (3204:21): [True: 4.76M, False: 3.46k]
  ------------------
 3205|  3.53k|  if (i == 0) return -1;                     // Error, no length specified
  ------------------
  |  Branch (3205:7): [True: 16, False: 3.52k]
  ------------------
 3206|  3.52k|  if (i > (int) sizeof(int) * 2) return -1;  // Chunk length is too big
  ------------------
  |  Branch (3206:7): [True: 89, False: 3.43k]
  ------------------
 3207|  3.43k|  if (len < i + 1 || buf[i] != '\r' || buf[i + 1] != '\n') return -1;  // Error
  ------------------
  |  Branch (3207:7): [True: 17, False: 3.41k]
  |  Branch (3207:22): [True: 37, False: 3.37k]
  |  Branch (3207:40): [True: 21, False: 3.35k]
  ------------------
 3208|  3.35k|  if (mg_str_to_num(mg_str_n(buf, (size_t) i), 16, &n, sizeof(int)) == false)
  ------------------
  |  Branch (3208:7): [True: 0, False: 3.35k]
  ------------------
 3209|      0|    return -1;                    // Decode chunk length, overflow
 3210|  3.35k|  if (n < 0) return -1;           // Error. TODO(): some checks now redundant
  ------------------
  |  Branch (3210:7): [True: 45, False: 3.31k]
  ------------------
 3211|  3.31k|  if (n > len - i - 4) return 0;  // Chunk not yet fully buffered
  ------------------
  |  Branch (3211:7): [True: 130, False: 3.18k]
  ------------------
 3212|  3.18k|  if (buf[i + n + 2] != '\r' || buf[i + n + 3] != '\n') return -1;  // Error
  ------------------
  |  Branch (3212:7): [True: 33, False: 3.14k]
  |  Branch (3212:33): [True: 15, False: 3.13k]
  ------------------
 3213|  3.13k|  *pl = i + 2, *dl = n;
 3214|  3.13k|  return i + 2 + n + 2;
 3215|  3.18k|}
fuzz.c:_ZL12is_hex_digiti:
 3196|  4.76M|static bool is_hex_digit(int c) {
 3197|  4.76M|  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
  ------------------
  |  Branch (3197:11): [True: 4.76M, False: 3.44k]
  |  Branch (3197:23): [True: 5.17k, False: 4.75M]
  |  Branch (3197:37): [True: 4.75M, False: 5.86k]
  |  Branch (3197:49): [True: 4.75M, False: 11]
  ------------------
 3198|  4.76M|         (c >= 'A' && c <= 'F');
  ------------------
  |  Branch (3198:11): [True: 2.42k, False: 3.45k]
  |  Branch (3198:23): [True: 2.40k, False: 17]
  ------------------
 3199|  4.76M|}
fuzz.c:_ZL7roundupmm:
 3367|  63.7k|static size_t roundup(size_t size, size_t align) {
 3368|  63.7k|  return align == 0 ? size : (size + align - 1) / align * align;
  ------------------
  |  Branch (3368:10): [True: 5.02k, False: 58.6k]
  ------------------
 3369|  63.7k|}
fuzz.c:_ZL7mg_atodPKciPi:
 3463|   484k|static double mg_atod(const char *p, int len, int *numlen) {
 3464|   484k|  double d = 0.0;
 3465|   484k|  int i = 0, sign = 1;
 3466|       |
 3467|       |  // Sign
 3468|   484k|  if (i < len && *p == '-') {
  ------------------
  |  Branch (3468:7): [True: 484k, False: 0]
  |  Branch (3468:18): [True: 226k, False: 258k]
  ------------------
 3469|   226k|    sign = -1, i++;
 3470|   258k|  } else if (i < len && *p == '+') {
  ------------------
  |  Branch (3470:14): [True: 258k, False: 0]
  |  Branch (3470:25): [True: 0, False: 258k]
  ------------------
 3471|      0|    i++;
 3472|      0|  }
 3473|       |
 3474|       |  // Decimal
 3475|  20.4M|  for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
  ------------------
  |  Branch (3475:10): [True: 20.4M, False: 174]
  |  Branch (3475:21): [True: 20.0M, False: 401k]
  |  Branch (3475:36): [True: 19.9M, False: 82.9k]
  ------------------
 3476|  19.9M|    d *= 10.0;
 3477|  19.9M|    d += p[i] - '0';
 3478|  19.9M|  }
 3479|   484k|  d *= sign;
 3480|       |
 3481|       |  // Fractional
 3482|   484k|  if (i < len && p[i] == '.') {
  ------------------
  |  Branch (3482:7): [True: 484k, False: 174]
  |  Branch (3482:18): [True: 193k, False: 290k]
  ------------------
 3483|   193k|    double frac = 0.0, base = 0.1;
 3484|   193k|    i++;
 3485|  4.49M|    for (; i < len && p[i] >= '0' && p[i] <= '9'; i++) {
  ------------------
  |  Branch (3485:12): [True: 4.49M, False: 78]
  |  Branch (3485:23): [True: 4.30M, False: 193k]
  |  Branch (3485:38): [True: 4.30M, False: 147]
  ------------------
 3486|  4.30M|      frac += base * (p[i] - '0');
 3487|  4.30M|      base /= 10.0;
 3488|  4.30M|    }
 3489|   193k|    d += frac * sign;
 3490|   193k|  }
 3491|       |
 3492|       |  // Exponential
 3493|   484k|  if (i < len && (p[i] == 'e' || p[i] == 'E')) {
  ------------------
  |  Branch (3493:7): [True: 483k, False: 252]
  |  Branch (3493:19): [True: 5.45k, False: 478k]
  |  Branch (3493:34): [True: 76.3k, False: 402k]
  ------------------
 3494|  81.8k|    int j, exp = 0, minus = 0;
 3495|  81.8k|    i++;
 3496|  81.8k|    if (i < len && p[i] == '-') minus = 1, i++;
  ------------------
  |  Branch (3496:9): [True: 81.8k, False: 33]
  |  Branch (3496:20): [True: 68.9k, False: 12.8k]
  ------------------
 3497|  81.8k|    if (i < len && p[i] == '+') i++;
  ------------------
  |  Branch (3497:9): [True: 81.8k, False: 52]
  |  Branch (3497:20): [True: 221, False: 81.5k]
  ------------------
 3498|  1.50M|    while (i < len && p[i] >= '0' && p[i] <= '9' && exp < 308)
  ------------------
  |  Branch (3498:12): [True: 1.50M, False: 251]
  |  Branch (3498:23): [True: 1.42M, False: 79.5k]
  |  Branch (3498:38): [True: 1.42M, False: 2.06k]
  |  Branch (3498:53): [True: 1.42M, False: 26]
  ------------------
 3499|  1.42M|      exp = exp * 10 + (p[i++] - '0');
 3500|  81.8k|    if (minus) exp = -exp;
  ------------------
  |  Branch (3500:9): [True: 68.9k, False: 12.9k]
  ------------------
 3501|   221k|    for (j = 0; j < exp; j++) d *= 10.0;
  ------------------
  |  Branch (3501:17): [True: 140k, False: 81.8k]
  ------------------
 3502|  3.27M|    for (j = 0; j < -exp; j++) d /= 10.0;
  ------------------
  |  Branch (3502:17): [True: 3.19M, False: 81.8k]
  ------------------
 3503|  81.8k|  }
 3504|       |
 3505|   484k|  if (numlen != NULL) *numlen = i;
  ------------------
  |  Branch (3505:7): [True: 484k, False: 0]
  ------------------
 3506|   484k|  return d;
 3507|   484k|}
fuzz.c:_ZL14mg_pass_stringPKci:
 3449|  30.1k|static int mg_pass_string(const char *s, int len) {
 3450|  30.1k|  int i;
 3451|  36.3M|  for (i = 0; i < len; i++) {
  ------------------
  |  Branch (3451:15): [True: 36.3M, False: 566]
  ------------------
 3452|  36.3M|    if (s[i] == '\\' && i + 1 < len && json_esc(s[i + 1], 1)) {
  ------------------
  |  Branch (3452:9): [True: 1.75M, False: 34.5M]
  |  Branch (3452:25): [True: 1.75M, False: 43]
  |  Branch (3452:40): [True: 1.67M, False: 76.5k]
  ------------------
 3453|  1.67M|      i++;
 3454|  34.6M|    } else if (s[i] == '\0') {
  ------------------
  |  Branch (3454:16): [True: 67, False: 34.6M]
  ------------------
 3455|     67|      return MG_JSON_INVALID;
 3456|  34.6M|    } else if (s[i] == '"') {
  ------------------
  |  Branch (3456:16): [True: 29.5k, False: 34.6M]
  ------------------
 3457|  29.5k|      return i;
 3458|  29.5k|    }
 3459|  36.3M|  }
 3460|    566|  return MG_JSON_INVALID;
 3461|  30.1k|}
fuzz.c:_ZL8json_escii:
 3441|  1.75M|static char json_esc(int c, int esc) {
 3442|  1.75M|  const char *p, *esc1 = escapeseq(esc), *esc2 = escapeseq(!esc);
 3443|  9.07M|  for (p = esc1; *p != '\0'; p++) {
  ------------------
  |  Branch (3443:18): [True: 8.99M, False: 76.5k]
  ------------------
 3444|  8.99M|    if (*p == c) return esc2[p - esc1];
  ------------------
  |  Branch (3444:9): [True: 1.67M, False: 7.32M]
  ------------------
 3445|  8.99M|  }
 3446|  76.5k|  return 0;
 3447|  1.75M|}
fuzz.c:_ZL9escapeseqi:
 3437|  3.50M|static const char *escapeseq(int esc) {
 3438|  3.50M|  return esc ? "\b\f\n\r\t\\\"" : "bfnrt\\\"";
  ------------------
  |  Branch (3438:10): [True: 1.75M, False: 1.75M]
  ------------------
 3439|  3.50M|}
fuzz.c:_ZL4logsPKcm:
 3821|  11.1k|static void logs(const char *buf, size_t len) {
 3822|  11.1k|  size_t i;
 3823|  64.5k|  for (i = 0; i < len; i++) logc(((unsigned char *) buf)[i]);
  ------------------
  |  Branch (3823:15): [True: 53.4k, False: 11.1k]
  ------------------
 3824|  11.1k|}
fuzz.c:_ZL4logch:
 3817|   124k|static void logc(unsigned char c) {
 3818|   124k|  s_log_func((char) c, s_log_func_param);
 3819|   124k|}
fuzz.c:_ZL6nibblej:
 3850|  46.7k|static unsigned char nibble(unsigned c) {
 3851|  46.7k|  return (unsigned char) (c < 10 ? c + '0' : c + 'W');
  ------------------
  |  Branch (3851:27): [True: 35.1k, False: 11.5k]
  ------------------
 3852|  46.7k|}
fuzz.c:_ZL13decode_varintPKhmPm:
 4175|     24|static size_t decode_varint(const uint8_t *buf, size_t len, size_t *value) {
 4176|     24|  size_t multiplier = 1, offset;
 4177|     24|  *value = 0;
 4178|       |
 4179|     45|  for (offset = 0; offset < 4 && offset < len; offset++) {
  ------------------
  |  Branch (4179:20): [True: 44, False: 1]
  |  Branch (4179:34): [True: 41, False: 3]
  ------------------
 4180|     41|    uint8_t encoded_byte = buf[offset];
 4181|     41|    *value += (encoded_byte & 0x7f) * multiplier;
 4182|     41|    multiplier *= 128;
 4183|       |
 4184|     41|    if ((encoded_byte & 0x80) == 0) return offset + 1;
  ------------------
  |  Branch (4184:9): [True: 20, False: 21]
  ------------------
 4185|     41|  }
 4186|       |
 4187|      4|  return 0;
 4188|     24|}
fuzz.c:_ZL8mg_atone6mg_strP7mg_addr:
 4664|  5.02k|static bool mg_atone(struct mg_str str, struct mg_addr *addr) {
 4665|  5.02k|  if (str.len > 0) return false;
  ------------------
  |  Branch (4665:7): [True: 5.02k, False: 0]
  ------------------
 4666|      0|  memset(addr->ip, 0, sizeof(addr->ip));
 4667|      0|  addr->is_ip6 = false;
 4668|      0|  return true;
 4669|  5.02k|}
fuzz.c:_ZL8mg_atonl6mg_strP7mg_addr:
 4656|  5.02k|static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
 4657|  5.02k|  uint32_t localhost = mg_htonl(0x7f000001);
  ------------------
  |  | 1060|  5.02k|#define mg_htonl(x) mg_ntohl(x)
  ------------------
 4658|  5.02k|  if (mg_strcasecmp(str, mg_str("localhost")) != 0) return false;
  ------------------
  |  |  859|  5.02k|#define mg_str(s) mg_str_s(s)
  ------------------
  |  Branch (4658:7): [True: 0, False: 5.02k]
  ------------------
 4659|  5.02k|  memcpy(addr->ip, &localhost, sizeof(uint32_t));
 4660|  5.02k|  addr->is_ip6 = false;
 4661|  5.02k|  return true;
 4662|  5.02k|}
fuzz.c:_ZL5tx_ipP11mg_tcpip_ifPhhjjm:
 5132|  5.08k|                        size_t plen) {
 5133|  5.08k|  struct eth *eth = (struct eth *) ifp->tx.buf;
 5134|  5.08k|  struct ip *ip = (struct ip *) (eth + 1);
 5135|  5.08k|  memcpy(eth->dst, mac_dst, sizeof(eth->dst));
 5136|  5.08k|  memcpy(eth->src, ifp->mac, sizeof(eth->src));  // Use our MAC
 5137|  5.08k|  eth->type = mg_htons(0x800);
  ------------------
  |  | 1059|  5.08k|#define mg_htons(x) mg_ntohs(x)
  ------------------
 5138|  5.08k|  memset(ip, 0, sizeof(*ip));
 5139|  5.08k|  ip->ver = 0x45;   // Version 4, header length 5 words
 5140|  5.08k|  ip->frag = 0x40;  // Don't fragment
 5141|  5.08k|  ip->len = mg_htons((uint16_t) (sizeof(*ip) + plen));
  ------------------
  |  | 1059|  5.08k|#define mg_htons(x) mg_ntohs(x)
  ------------------
 5142|  5.08k|  ip->ttl = 64;
 5143|  5.08k|  ip->proto = proto;
 5144|  5.08k|  ip->src = ip_src;
 5145|  5.08k|  ip->dst = ip_dst;
 5146|  5.08k|  ip->csum = ipcsum(ip, sizeof(*ip));
 5147|  5.08k|  return ip;
 5148|  5.08k|}
fuzz.c:_ZL6ipcsumPKvm:
 5077|  5.11k|static uint16_t ipcsum(const void *buf, size_t len) {
 5078|  5.11k|  uint32_t sum = csumup(0, buf, len);
 5079|  5.11k|  return csumfin(sum);
 5080|  5.11k|}
fuzz.c:_ZL6csumupjPKvm:
 5065|  25.3k|static uint32_t csumup(uint32_t sum, const void *buf, size_t len) {
 5066|  25.3k|  size_t i;
 5067|  25.3k|  const uint8_t *p = (const uint8_t *) buf;
 5068|   307k|  for (i = 0; i < len; i++) sum += i & 1 ? p[i] : (uint32_t) (p[i] << 8);
  ------------------
  |  Branch (5068:15): [True: 282k, False: 25.3k]
  |  Branch (5068:36): [True: 141k, False: 141k]
  ------------------
 5069|  25.3k|  return sum;
 5070|  25.3k|}
fuzz.c:_ZL7csumfinj:
 5072|  10.1k|static uint16_t csumfin(uint32_t sum) {
 5073|  20.2k|  while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
  ------------------
  |  Branch (5073:10): [True: 10.1k, False: 10.1k]
  ------------------
 5074|  10.1k|  return mg_htons(~sum & 0xffff);
  ------------------
  |  | 1059|  10.1k|#define mg_htons(x) mg_ntohs(x)
  ------------------
 5075|  10.1k|}
fuzz.c:_ZL12ether_outputP11mg_tcpip_ifm:
 5095|  10.1k|static size_t ether_output(struct mg_tcpip_if *ifp, size_t len) {
 5096|  10.1k|  size_t n = ifp->driver->tx(ifp->tx.buf, len, ifp);
 5097|  10.1k|  if (n == len) ifp->nsent++;
  ------------------
  |  Branch (5097:7): [True: 10.1k, False: 0]
  ------------------
 5098|  10.1k|  return n;
 5099|  10.1k|}
fuzz.c:_ZL6tx_tcpP11mg_tcpip_ifPhjhttjjPKvm:
 5425|  5.05k|                     uint32_t seq, uint32_t ack, const void *buf, size_t len) {
 5426|       |#if 0
 5427|       |  uint8_t opts[] = {2, 4, 5, 0xb4, 4, 2, 0, 0};  // MSS = 1460, SACK permitted
 5428|       |  if (flags & TH_SYN) {
 5429|       |    // Handshake? Set MSS
 5430|       |    buf = opts;
 5431|       |    len = sizeof(opts);
 5432|       |  }
 5433|       |#endif
 5434|  5.05k|  struct ip *ip =
 5435|  5.05k|      tx_ip(ifp, dst_mac, 6, ifp->ip, dst_ip, sizeof(struct tcp) + len);
 5436|  5.05k|  struct tcp *tcp = (struct tcp *) (ip + 1);
 5437|  5.05k|  memset(tcp, 0, sizeof(*tcp));
 5438|  5.05k|  if (buf != NULL && len) memmove(tcp + 1, buf, len);
  ------------------
  |  Branch (5438:7): [True: 0, False: 5.05k]
  |  Branch (5438:22): [True: 0, False: 0]
  ------------------
 5439|  5.05k|  tcp->sport = sport;
 5440|  5.05k|  tcp->dport = dport;
 5441|  5.05k|  tcp->seq = seq;
 5442|  5.05k|  tcp->ack = ack;
 5443|  5.05k|  tcp->flags = flags;
 5444|  5.05k|  tcp->win = mg_htons(MIP_TCP_WIN);
  ------------------
  |  | 1059|  5.05k|#define mg_htons(x) mg_ntohs(x)
  ------------------
 5445|  5.05k|  tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
 5446|       |  // if (flags & TH_SYN) tcp->off = 0x70;  // Handshake? header size 28 bytes
 5447|       |
 5448|  5.05k|  uint32_t cs = 0;
 5449|  5.05k|  uint16_t n = (uint16_t) (sizeof(*tcp) + len);
 5450|  5.05k|  uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
 5451|  5.05k|  cs = csumup(cs, tcp, n);
 5452|  5.05k|  cs = csumup(cs, &ip->src, sizeof(ip->src));
 5453|  5.05k|  cs = csumup(cs, &ip->dst, sizeof(ip->dst));
 5454|  5.05k|  cs = csumup(cs, pseudo, sizeof(pseudo));
 5455|  5.05k|  tcp->csum = csumfin(cs);
 5456|  5.05k|  MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip4, &ip->src,
  ------------------
  |  |  963|  5.05k|#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  |  |  ------------------
  |  |  |  |  955|  5.05k|  do {                      \
  |  |  |  |  956|  5.05k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.05k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5457|  5.05k|              mg_ntohs(tcp->sport), mg_print_ip4, &ip->dst,
 5458|  5.05k|              mg_ntohs(tcp->dport), tcp->flags, len));
 5459|       |  // mg_hexdump(ifp->tx.buf, PDIFF(ifp->tx.buf, tcp + 1) + len);
 5460|  5.05k|  return ether_output(ifp, PDIFF(ifp->tx.buf, tcp + 1) + len);
  ------------------
  |  | 4918|  5.05k|#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
  ------------------
 5461|  5.05k|}
fuzz.c:_ZL8settmoutP13mg_connectionh:
 5082|  10.0k|static void settmout(struct mg_connection *c, uint8_t type) {
 5083|  10.0k|  struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
 5084|  10.0k|  struct connstate *s = (struct connstate *) (c + 1);
 5085|  10.0k|  unsigned n = type == MIP_TTYPE_ACK   ? MIP_TCP_ACK_MS
  ------------------
  |  | 4938|  10.0k|#define MIP_TTYPE_ACK 1        // Peer sent us data, we have to ack it soon
  ------------------
                unsigned n = type == MIP_TTYPE_ACK   ? MIP_TCP_ACK_MS
  ------------------
  |  | 4924|      0|#define MIP_TCP_ACK_MS 150    // Timeout for ACKing
  ------------------
  |  Branch (5085:16): [True: 0, False: 10.0k]
  ------------------
 5086|  10.0k|               : type == MIP_TTYPE_ARP ? MIP_TCP_ARP_MS
  ------------------
  |  | 4939|  10.0k|#define MIP_TTYPE_ARP 2        // ARP resolve sent, waiting for response
  ------------------
                             : type == MIP_TTYPE_ARP ? MIP_TCP_ARP_MS
  ------------------
  |  | 4925|      0|#define MIP_TCP_ARP_MS 100    // Timeout for ARP response
  ------------------
  |  Branch (5086:18): [True: 0, False: 10.0k]
  ------------------
 5087|  10.0k|               : type == MIP_TTYPE_SYN ? MIP_TCP_SYN_MS
  ------------------
  |  | 4940|  10.0k|#define MIP_TTYPE_SYN 3        // SYN sent, waiting for response
  ------------------
                             : type == MIP_TTYPE_SYN ? MIP_TCP_SYN_MS
  ------------------
  |  | 4926|  5.02k|#define MIP_TCP_SYN_MS 15000  // Timeout for connection establishment
  ------------------
  |  Branch (5087:18): [True: 5.02k, False: 5.02k]
  ------------------
 5088|  10.0k|               : type == MIP_TTYPE_FIN ? MIP_TCP_FIN_MS
  ------------------
  |  | 4941|  5.02k|#define MIP_TTYPE_FIN 4  // FIN sent, waiting until terminating the connection
  ------------------
                             : type == MIP_TTYPE_FIN ? MIP_TCP_FIN_MS
  ------------------
  |  | 4927|      0|#define MIP_TCP_FIN_MS 1000   // Timeout for closing connection
  ------------------
  |  Branch (5088:18): [True: 0, False: 5.02k]
  ------------------
 5089|  5.02k|                                       : MIP_TCP_KEEPALIVE_MS;
  ------------------
  |  | 4921|  15.0k|#define MIP_TCP_KEEPALIVE_MS 45000  // TCP keep-alive period, ms
  ------------------
 5090|  10.0k|  s->timer = ifp->now + n;
 5091|  10.0k|  s->ttype = type;
 5092|  10.0k|  MG_VERBOSE(("%lu %d -> %llx", c->id, type, s->timer));
  ------------------
  |  |  963|  10.0k|#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  |  |  ------------------
  |  |  |  |  955|  10.0k|  do {                      \
  |  |  |  |  956|  10.0k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  10.0k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5093|  10.0k|}
fuzz.c:_ZL7arp_askP11mg_tcpip_ifj:
 5101|  5.02k|static void arp_ask(struct mg_tcpip_if *ifp, uint32_t ip) {
 5102|  5.02k|  struct eth *eth = (struct eth *) ifp->tx.buf;
 5103|  5.02k|  struct arp *arp = (struct arp *) (eth + 1);
 5104|  5.02k|  memset(eth->dst, 255, sizeof(eth->dst));
 5105|  5.02k|  memcpy(eth->src, ifp->mac, sizeof(eth->src));
 5106|  5.02k|  eth->type = mg_htons(0x806);
  ------------------
  |  | 1059|  5.02k|#define mg_htons(x) mg_ntohs(x)
  ------------------
 5107|  5.02k|  memset(arp, 0, sizeof(*arp));
 5108|  5.02k|  arp->fmt = mg_htons(1), arp->pro = mg_htons(0x800), arp->hlen = 6,
  ------------------
  |  | 1059|  5.02k|#define mg_htons(x) mg_ntohs(x)
  ------------------
                arp->fmt = mg_htons(1), arp->pro = mg_htons(0x800), arp->hlen = 6,
  ------------------
  |  | 1059|  5.02k|#define mg_htons(x) mg_ntohs(x)
  ------------------
 5109|  5.02k|  arp->plen = 4;
 5110|  5.02k|  arp->op = mg_htons(1), arp->tpa = ip, arp->spa = ifp->ip;
  ------------------
  |  | 1059|  5.02k|#define mg_htons(x) mg_ntohs(x)
  ------------------
 5111|  5.02k|  memcpy(arp->sha, ifp->mac, sizeof(arp->sha));
 5112|  5.02k|  ether_output(ifp, PDIFF(eth, arp + 1));
  ------------------
  |  | 4918|  5.02k|#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
  ------------------
 5113|  5.02k|}
fuzz.c:_ZL8send_synP13mg_connection:
 5945|  5.02k|static void send_syn(struct mg_connection *c) {
 5946|  5.02k|  struct connstate *s = (struct connstate *) (c + 1);
 5947|  5.02k|  uint32_t isn = mg_htonl((uint32_t) mg_ntohs(c->loc.port));
  ------------------
  |  | 1060|  5.02k|#define mg_htonl(x) mg_ntohl(x)
  ------------------
 5948|  5.02k|  struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
 5949|  5.02k|  uint32_t rem_ip;
 5950|  5.02k|  memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
 5951|  5.02k|  tx_tcp(ifp, s->mac, rem_ip, TH_SYN, c->loc.port, c->rem.port, isn, 0, NULL,
  ------------------
  |  | 5009|  5.02k|#define TH_SYN 0x02
  ------------------
 5952|  5.02k|         0);
 5953|  5.02k|}
fuzz.c:_ZL13mg_tcpip_pollP11mg_tcpip_ifm:
 5801|  5.02k|static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {
 5802|  5.02k|  struct mg_connection *c;
 5803|  5.02k|  bool expired_1000ms = mg_timer_expired(&ifp->timer_1000ms, 1000, now);
 5804|  5.02k|  ifp->now = now;
 5805|       |
 5806|       |#if MG_ENABLE_TCPIP_PRINT_DEBUG_STATS
 5807|       |  if (expired_1000ms) {
 5808|       |    const char *names[] = {"down", "up", "req", "ready"};
 5809|       |    MG_INFO(("Status: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
 5810|       |             names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
 5811|       |             ifp->ndrop, ifp->nerr));
 5812|       |  }
 5813|       |#endif
 5814|       |  // Handle physical interface up/down status
 5815|  5.02k|  if (expired_1000ms && ifp->driver->up) {
  ------------------
  |  Branch (5815:7): [True: 5.02k, False: 0]
  |  Branch (5815:25): [True: 5.02k, False: 0]
  ------------------
 5816|  5.02k|    bool up = ifp->driver->up(ifp);
 5817|  5.02k|    bool current = ifp->state != MG_TCPIP_STATE_DOWN;
  ------------------
  |  | 2726|  5.02k|#define MG_TCPIP_STATE_DOWN 0   // Interface is down
  ------------------
 5818|  5.02k|    if (up != current) {
  ------------------
  |  Branch (5818:9): [True: 5.02k, False: 0]
  ------------------
 5819|  5.02k|      ifp->state = up == false               ? MG_TCPIP_STATE_DOWN
  ------------------
  |  | 2726|      0|#define MG_TCPIP_STATE_DOWN 0   // Interface is down
  ------------------
  |  Branch (5819:20): [True: 0, False: 5.02k]
  ------------------
 5820|  5.02k|                   : ifp->enable_dhcp_client ? MG_TCPIP_STATE_UP
  ------------------
  |  | 2727|      0|#define MG_TCPIP_STATE_UP 1     // Interface is up
  ------------------
  |  Branch (5820:22): [True: 0, False: 5.02k]
  ------------------
 5821|  5.02k|                                             : MG_TCPIP_STATE_READY;
  ------------------
  |  | 2729|  10.0k|#define MG_TCPIP_STATE_READY 3  // Interface is up and has an IP assigned
  ------------------
 5822|  5.02k|      if (!up && ifp->enable_dhcp_client) ifp->ip = 0;
  ------------------
  |  Branch (5822:11): [True: 0, False: 5.02k]
  |  Branch (5822:18): [True: 0, False: 0]
  ------------------
 5823|  5.02k|      onstatechange(ifp);
 5824|  5.02k|    }
 5825|  5.02k|    if (ifp->state == MG_TCPIP_STATE_DOWN) MG_ERROR(("Network is down"));
  ------------------
  |  | 2726|  5.02k|#define MG_TCPIP_STATE_DOWN 0   // Interface is down
  ------------------
                  if (ifp->state == MG_TCPIP_STATE_DOWN) MG_ERROR(("Network is down"));
  ------------------
  |  |  960|      0|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (5825:9): [True: 0, False: 5.02k]
  ------------------
 5826|  5.02k|  }
 5827|  5.02k|  if (ifp->state == MG_TCPIP_STATE_DOWN) return;
  ------------------
  |  | 2726|  5.02k|#define MG_TCPIP_STATE_DOWN 0   // Interface is down
  ------------------
  |  Branch (5827:7): [True: 0, False: 5.02k]
  ------------------
 5828|       |
 5829|       |  // DHCP RFC-2131 (4.4)
 5830|  5.02k|  if (ifp->state == MG_TCPIP_STATE_UP && expired_1000ms) {
  ------------------
  |  | 2727|  10.0k|#define MG_TCPIP_STATE_UP 1     // Interface is up
  ------------------
  |  Branch (5830:7): [True: 0, False: 5.02k]
  |  Branch (5830:42): [True: 0, False: 0]
  ------------------
 5831|      0|    tx_dhcp_discover(ifp);  // INIT (4.4.1)
 5832|  5.02k|  } else if (expired_1000ms && ifp->state == MG_TCPIP_STATE_READY &&
  ------------------
  |  | 2729|  10.0k|#define MG_TCPIP_STATE_READY 3  // Interface is up and has an IP assigned
  ------------------
  |  Branch (5832:14): [True: 5.02k, False: 0]
  |  Branch (5832:32): [True: 5.02k, False: 0]
  ------------------
 5833|  5.02k|             ifp->lease_expire > 0) {  // BOUND / RENEWING / REBINDING
  ------------------
  |  Branch (5833:14): [True: 0, False: 5.02k]
  ------------------
 5834|      0|    if (ifp->now >= ifp->lease_expire) {
  ------------------
  |  Branch (5834:9): [True: 0, False: 0]
  ------------------
 5835|      0|      ifp->state = MG_TCPIP_STATE_UP, ifp->ip = 0;  // expired, release IP
  ------------------
  |  | 2727|      0|#define MG_TCPIP_STATE_UP 1     // Interface is up
  ------------------
 5836|      0|      onstatechange(ifp);
 5837|      0|    } else if (ifp->now + 30UL * 60UL * 1000UL > ifp->lease_expire &&
  ------------------
  |  Branch (5837:16): [True: 0, False: 0]
  ------------------
 5838|      0|               ((ifp->now / 1000) % 60) == 0) {
  ------------------
  |  Branch (5838:16): [True: 0, False: 0]
  ------------------
 5839|       |      // hack: 30 min before deadline, try to rebind (4.3.6) every min
 5840|      0|      tx_dhcp_request_re(ifp, (uint8_t *) broadcast, ifp->ip, 0xffffffff);
 5841|      0|    }  // TODO(): Handle T1 (RENEWING) and T2 (REBINDING) (4.4.5)
 5842|      0|  }
 5843|       |
 5844|       |  // Read data from the network
 5845|  5.02k|  if (ifp->driver->rx != NULL) {  // Polling driver. We must call it
  ------------------
  |  Branch (5845:7): [True: 5.02k, False: 0]
  ------------------
 5846|  5.02k|    size_t len =
 5847|  5.02k|        ifp->driver->rx(ifp->recv_queue.buf, ifp->recv_queue.size, ifp);
 5848|  5.02k|    if (len > 0) {
  ------------------
  |  Branch (5848:9): [True: 0, False: 5.02k]
  ------------------
 5849|      0|      ifp->nrecv++;
 5850|      0|      mg_tcpip_rx(ifp, ifp->recv_queue.buf, len);
 5851|      0|    }
 5852|  5.02k|  } else {  // Interrupt-based driver. Fills recv queue itself
 5853|      0|    char *buf;
 5854|      0|    size_t len = mg_queue_next(&ifp->recv_queue, &buf);
 5855|      0|    if (len > 0) {
  ------------------
  |  Branch (5855:9): [True: 0, False: 0]
  ------------------
 5856|      0|      mg_tcpip_rx(ifp, buf, len);
 5857|      0|      mg_queue_del(&ifp->recv_queue, len);
 5858|      0|    }
 5859|      0|  }
 5860|       |
 5861|       |  // Process timeouts
 5862|  10.0k|  for (c = ifp->mgr->conns; c != NULL; c = c->next) {
  ------------------
  |  Branch (5862:29): [True: 5.02k, False: 5.02k]
  ------------------
 5863|  5.02k|    if (c->is_udp || c->is_listening || c->is_resolving) continue;
  ------------------
  |  Branch (5863:9): [True: 0, False: 5.02k]
  |  Branch (5863:22): [True: 0, False: 5.02k]
  |  Branch (5863:41): [True: 0, False: 5.02k]
  ------------------
 5864|  5.02k|    struct connstate *s = (struct connstate *) (c + 1);
 5865|  5.02k|    uint32_t rem_ip;
 5866|  5.02k|    memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
 5867|  5.02k|    if (now > s->timer) {
  ------------------
  |  Branch (5867:9): [True: 5.02k, False: 0]
  ------------------
 5868|  5.02k|      if (s->ttype == MIP_TTYPE_ACK && s->acked != s->ack) {
  ------------------
  |  | 4938|  10.0k|#define MIP_TTYPE_ACK 1        // Peer sent us data, we have to ack it soon
  ------------------
  |  Branch (5868:11): [True: 0, False: 5.02k]
  |  Branch (5868:40): [True: 0, False: 0]
  ------------------
 5869|      0|        MG_VERBOSE(("%lu ack %x %x", c->id, s->seq, s->ack));
  ------------------
  |  |  963|      0|#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5870|      0|        tx_tcp(ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port,
  ------------------
  |  | 5012|      0|#define TH_ACK 0x10
  ------------------
 5871|      0|               mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
  ------------------
  |  | 1060|      0|#define mg_htonl(x) mg_ntohl(x)
  ------------------
                             mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
  ------------------
  |  | 1060|      0|#define mg_htonl(x) mg_ntohl(x)
  ------------------
 5872|      0|        s->acked = s->ack;
 5873|  5.02k|      } else if (s->ttype == MIP_TTYPE_ARP) {
  ------------------
  |  | 4939|  5.02k|#define MIP_TTYPE_ARP 2        // ARP resolve sent, waiting for response
  ------------------
  |  Branch (5873:18): [True: 0, False: 5.02k]
  ------------------
 5874|      0|        mg_error(c, "ARP timeout");
 5875|  5.02k|      } else if (s->ttype == MIP_TTYPE_SYN) {
  ------------------
  |  | 4940|  5.02k|#define MIP_TTYPE_SYN 3        // SYN sent, waiting for response
  ------------------
  |  Branch (5875:18): [True: 5.02k, False: 0]
  ------------------
 5876|  5.02k|        mg_error(c, "Connection timeout");
 5877|  5.02k|      } else if (s->ttype == MIP_TTYPE_FIN) {
  ------------------
  |  | 4941|      0|#define MIP_TTYPE_FIN 4  // FIN sent, waiting until terminating the connection
  ------------------
  |  Branch (5877:18): [True: 0, False: 0]
  ------------------
 5878|      0|        c->is_closing = 1;
 5879|      0|        continue;
 5880|      0|      } else {
 5881|      0|        if (s->tmiss++ > 2) {
  ------------------
  |  Branch (5881:13): [True: 0, False: 0]
  ------------------
 5882|      0|          mg_error(c, "keepalive");
 5883|      0|        } else {
 5884|      0|          MG_VERBOSE(("%lu keepalive", c->id));
  ------------------
  |  |  963|      0|#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5885|      0|          tx_tcp(ifp, s->mac, rem_ip, TH_ACK, c->loc.port, c->rem.port,
  ------------------
  |  | 5012|      0|#define TH_ACK 0x10
  ------------------
 5886|      0|                 mg_htonl(s->seq - 1), mg_htonl(s->ack), NULL, 0);
  ------------------
  |  | 1060|      0|#define mg_htonl(x) mg_ntohl(x)
  ------------------
                               mg_htonl(s->seq - 1), mg_htonl(s->ack), NULL, 0);
  ------------------
  |  | 1060|      0|#define mg_htonl(x) mg_ntohl(x)
  ------------------
 5887|      0|        }
 5888|      0|      }
 5889|       |
 5890|  5.02k|      settmout(c, MIP_TTYPE_KEEPALIVE);
  ------------------
  |  | 4937|  5.02k|#define MIP_TTYPE_KEEPALIVE 0  // Connection is idle for long, send keepalive
  ------------------
 5891|  5.02k|    }
 5892|  5.02k|  }
 5893|  5.02k|}
fuzz.c:_ZL13onstatechangeP11mg_tcpip_if:
 5115|  5.02k|static void onstatechange(struct mg_tcpip_if *ifp) {
 5116|  5.02k|  if (ifp->state == MG_TCPIP_STATE_READY) {
  ------------------
  |  | 2729|  5.02k|#define MG_TCPIP_STATE_READY 3  // Interface is up and has an IP assigned
  ------------------
  |  Branch (5116:7): [True: 5.02k, False: 0]
  ------------------
 5117|  5.02k|    MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip));
  ------------------
  |  |  961|  5.02k|#define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
  |  |  ------------------
  |  |  |  |  955|  5.02k|  do {                      \
  |  |  |  |  956|  5.02k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.02k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5118|  5.02k|    MG_INFO(("       GW: %M", mg_print_ip4, &ifp->gw));
  ------------------
  |  |  961|  5.02k|#define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
  |  |  ------------------
  |  |  |  |  955|  5.02k|  do {                      \
  |  |  |  |  956|  5.02k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.02k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5119|  5.02k|    MG_INFO(("      MAC: %M", mg_print_mac, &ifp->mac));
  ------------------
  |  |  961|  5.02k|#define MG_INFO(args) MG_LOG(MG_LL_INFO, args)
  |  |  ------------------
  |  |  |  |  955|  5.02k|  do {                      \
  |  |  |  |  956|  5.02k|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|  5.02k|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5120|  5.02k|    arp_ask(ifp, ifp->gw);
 5121|  5.02k|  } else if (ifp->state == MG_TCPIP_STATE_UP) {
  ------------------
  |  | 2727|      0|#define MG_TCPIP_STATE_UP 1     // Interface is up
  ------------------
  |  Branch (5121:14): [True: 0, False: 0]
  ------------------
 5122|      0|    MG_ERROR(("Link up"));
  ------------------
  |  |  960|      0|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5123|      0|    srand((unsigned int) mg_millis());
 5124|      0|  } else if (ifp->state == MG_TCPIP_STATE_DOWN) {
  ------------------
  |  | 2726|      0|#define MG_TCPIP_STATE_DOWN 0   // Interface is down
  ------------------
  |  Branch (5124:14): [True: 0, False: 0]
  ------------------
 5125|      0|    MG_ERROR(("Link down"));
  ------------------
  |  |  960|      0|#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5126|      0|  }
 5127|  5.02k|  mg_tcpip_call(ifp, MG_TCPIP_EV_ST_CHG, &ifp->state);
 5128|  5.02k|}
fuzz.c:_ZL13mg_tcpip_callP11mg_tcpip_ifiPv:
 5054|  5.02k|static void mg_tcpip_call(struct mg_tcpip_if *ifp, int ev, void *ev_data) {
 5055|  5.02k|  if (ifp->fn != NULL) ifp->fn(ifp, ev, ev_data);
  ------------------
  |  Branch (5055:7): [True: 0, False: 5.02k]
  ------------------
 5056|  5.02k|}
fuzz.c:_ZL9can_writeP13mg_connection:
 6031|  5.02k|static bool can_write(struct mg_connection *c) {
 6032|  5.02k|  return c->is_connecting == 0 && c->is_resolving == 0 && c->send.len > 0 &&
  ------------------
  |  Branch (6032:10): [True: 0, False: 5.02k]
  |  Branch (6032:35): [True: 0, False: 0]
  |  Branch (6032:59): [True: 0, False: 0]
  ------------------
 6033|  5.02k|         c->is_tls_hs == 0 && c->is_arplooking == 0;
  ------------------
  |  Branch (6033:10): [True: 0, False: 0]
  |  Branch (6033:31): [True: 0, False: 0]
  ------------------
 6034|  5.02k|}
fuzz.c:_ZL12init_closureP13mg_connection:
 6011|  1.37k|static void init_closure(struct mg_connection *c) {
 6012|  1.37k|  struct connstate *s = (struct connstate *) (c + 1);
 6013|  1.37k|  if (c->is_udp == false && c->is_listening == false &&
  ------------------
  |  Branch (6013:7): [True: 1.37k, False: 0]
  |  Branch (6013:29): [True: 1.37k, False: 0]
  ------------------
 6014|  1.37k|      c->is_connecting == false) {  // For TCP conns,
  ------------------
  |  Branch (6014:7): [True: 0, False: 1.37k]
  ------------------
 6015|      0|    struct mg_tcpip_if *ifp =
 6016|      0|        (struct mg_tcpip_if *) c->mgr->priv;  // send TCP FIN
 6017|      0|    uint32_t rem_ip;
 6018|      0|    memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
 6019|      0|    tx_tcp(ifp, s->mac, rem_ip, TH_FIN | TH_ACK, c->loc.port, c->rem.port,
  ------------------
  |  | 5008|      0|#define TH_FIN 0x01
  ------------------
                  tx_tcp(ifp, s->mac, rem_ip, TH_FIN | TH_ACK, c->loc.port, c->rem.port,
  ------------------
  |  | 5012|      0|#define TH_ACK 0x10
  ------------------
 6020|      0|           mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
  ------------------
  |  | 1060|      0|#define mg_htonl(x) mg_ntohl(x)
  ------------------
                         mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
  ------------------
  |  | 1060|      0|#define mg_htonl(x) mg_ntohl(x)
  ------------------
 6021|      0|    settmout(c, MIP_TTYPE_FIN);
  ------------------
  |  | 4941|      0|#define MIP_TTYPE_FIN 4  // FIN sent, waiting until terminating the connection
  ------------------
 6022|      0|  }
 6023|  1.37k|}
fuzz.c:_ZL10close_connP13mg_connection:
 6025|  5.02k|static void close_conn(struct mg_connection *c) {
 6026|  5.02k|  struct connstate *s = (struct connstate *) (c + 1);
 6027|  5.02k|  mg_iobuf_free(&s->raw);  // For TLS connections, release raw data
 6028|  5.02k|  mg_close_conn(c);
 6029|  5.02k|}
fuzz.c:_ZL20mg_pfn_iobuf_privatecPvb:
 6410|  1.12G|static void mg_pfn_iobuf_private(char ch, void *param, bool expand) {
 6411|  1.12G|  struct mg_iobuf *io = (struct mg_iobuf *) param;
 6412|  1.12G|  if (expand && io->len + 2 > io->size) mg_iobuf_resize(io, io->len + 2);
  ------------------
  |  Branch (6412:7): [True: 991M, False: 129M]
  |  Branch (6412:17): [True: 33.5k, False: 991M]
  ------------------
 6413|  1.12G|  if (io->len + 2 <= io->size) {
  ------------------
  |  Branch (6413:7): [True: 1.12G, False: 3.53k]
  ------------------
 6414|  1.12G|    io->buf[io->len++] = (uint8_t) ch;
 6415|  1.12G|    io->buf[io->len] = 0;
 6416|  1.12G|  } else if (io->len < io->size) {
  ------------------
  |  Branch (6416:14): [True: 422, False: 3.11k]
  ------------------
 6417|    422|    io->buf[io->len++] = 0;  // Guarantee to 0-terminate
 6418|    422|  }
 6419|  1.12G|}
fuzz.c:_ZL23mg_putchar_iobuf_staticcPv:
 6421|   129M|static void mg_putchar_iobuf_static(char ch, void *param) {
 6422|   129M|  mg_pfn_iobuf_private(ch, param, false);
 6423|   129M|}
fuzz.c:_ZL12gettimestampPKj:
 7166|    585|static int64_t gettimestamp(const uint32_t *data) {
 7167|    585|  uint32_t sec = mg_ntohl(data[0]), frac = mg_ntohl(data[1]);
 7168|    585|  if (sec) sec -= SNTP_TIME_OFFSET;
  ------------------
  |  | 7157|    562|#define SNTP_TIME_OFFSET 2208988800U  // (1970 - 1900) in seconds
  ------------------
  |  Branch (7168:7): [True: 562, False: 23]
  ------------------
 7169|    585|  return ((int64_t) sec) * 1000 + (int64_t) (frac / SNTP_MAX_FRAC * 1000.0);
  ------------------
  |  | 7158|    585|#define SNTP_MAX_FRAC 4294967295.0    // 2 ** 32 - 1
  ------------------
 7170|    585|}
fuzz.c:_ZL7mg_tolcc:
 8087|  3.29M|static int mg_tolc(char c) {
 8088|  3.29M|  return (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
  ------------------
  |  Branch (8088:11): [True: 2.28M, False: 1.00M]
  |  Branch (8088:23): [True: 1.64M, False: 648k]
  ------------------
 8089|  3.29M|}
fuzz.c:_ZL8urlparsePKc:
16253|  10.0k|static struct url urlparse(const char *url) {
16254|  10.0k|  size_t i;
16255|  10.0k|  struct url u;
16256|  10.0k|  memset(&u, 0, sizeof(u));
16257|   231k|  for (i = 0; url[i] != '\0'; i++) {
  ------------------
  |  Branch (16257:15): [True: 221k, False: 10.0k]
  ------------------
16258|   221k|    if (url[i] == '/' && i > 0 && u.host == 0 && url[i - 1] == '/') {
  ------------------
  |  Branch (16258:9): [True: 20.1k, False: 201k]
  |  Branch (16258:26): [True: 20.1k, False: 0]
  |  Branch (16258:35): [True: 20.1k, False: 0]
  |  Branch (16258:50): [True: 10.0k, False: 10.0k]
  ------------------
16259|  10.0k|      u.host = i + 1;
16260|  10.0k|      u.port = 0;
16261|   211k|    } else if (url[i] == ']') {
  ------------------
  |  Branch (16261:16): [True: 0, False: 211k]
  ------------------
16262|      0|      u.port = 0;  // IPv6 URLs, like http://[::1]/bar
16263|   211k|    } else if (url[i] == ':' && u.port == 0 && u.uri == 0) {
  ------------------
  |  Branch (16263:16): [True: 20.1k, False: 191k]
  |  Branch (16263:33): [True: 20.1k, False: 0]
  |  Branch (16263:48): [True: 20.1k, False: 0]
  ------------------
16264|  20.1k|      u.port = i + 1;
16265|   191k|    } else if (url[i] == '@' && u.user == 0 && u.pass == 0 && u.uri == 0) {
  ------------------
  |  Branch (16265:16): [True: 0, False: 191k]
  |  Branch (16265:33): [True: 0, False: 0]
  |  Branch (16265:48): [True: 0, False: 0]
  |  Branch (16265:63): [True: 0, False: 0]
  ------------------
16266|      0|      u.user = u.host;
16267|      0|      u.pass = u.port;
16268|      0|      u.host = i + 1;
16269|      0|      u.port = 0;
16270|   191k|    } else if (url[i] == '/' && u.host && u.uri == 0) {
  ------------------
  |  Branch (16270:16): [True: 10.0k, False: 181k]
  |  Branch (16270:33): [True: 0, False: 10.0k]
  |  Branch (16270:43): [True: 0, False: 0]
  ------------------
16271|      0|      u.uri = i;
16272|      0|    }
16273|   221k|  }
16274|  10.0k|  u.end = i;
16275|       |#if 0
16276|       |  printf("[%s] %d %d %d %d %d\n", url, u.user, u.pass, u.host, u.port, u.uri);
16277|       |#endif
16278|  10.0k|  return u;
16279|  10.0k|}
fuzz.c:_ZL11mg_tcpip_rxP11mg_tcpip_ifPvm:
 5757|  5.02k|static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
 5758|  5.02k|  struct pkt pkt;
 5759|  5.02k|  memset(&pkt, 0, sizeof(pkt));
 5760|  5.02k|  pkt.raw.buf = (char *) buf;
 5761|  5.02k|  pkt.raw.len = len;
 5762|  5.02k|  pkt.eth = (struct eth *) buf;
 5763|       |  // mg_hexdump(buf, len > 16 ? 16: len);
 5764|  5.02k|  if (pkt.raw.len < sizeof(*pkt.eth)) return;  // Truncated - runt?
  ------------------
  |  Branch (5764:7): [True: 1.56k, False: 3.46k]
  ------------------
 5765|  3.46k|  if (ifp->enable_mac_check &&
  ------------------
  |  Branch (5765:7): [True: 0, False: 3.46k]
  ------------------
 5766|  3.46k|      memcmp(pkt.eth->dst, ifp->mac, sizeof(pkt.eth->dst)) != 0 &&
  ------------------
  |  Branch (5766:7): [True: 0, False: 0]
  ------------------
 5767|  3.46k|      memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0)
  ------------------
  |  Branch (5767:7): [True: 0, False: 0]
  ------------------
 5768|      0|    return;
 5769|  3.46k|  if (ifp->enable_crc32_check && len > 4) {
  ------------------
  |  Branch (5769:7): [True: 0, False: 3.46k]
  |  Branch (5769:34): [True: 0, False: 0]
  ------------------
 5770|      0|    len -= 4;  // TODO(scaprile): check on bigendian
 5771|      0|    uint32_t crc = mg_crc32(0, (const char *) buf, len);
 5772|      0|    if (memcmp((void *) ((size_t) buf + len), &crc, sizeof(crc))) return;
  ------------------
  |  Branch (5772:9): [True: 0, False: 0]
  ------------------
 5773|      0|  }
 5774|  3.46k|  if (pkt.eth->type == mg_htons(0x806)) {
  ------------------
  |  | 1059|  3.46k|#define mg_htons(x) mg_ntohs(x)
  ------------------
  |  Branch (5774:7): [True: 834, False: 2.63k]
  ------------------
 5775|    834|    pkt.arp = (struct arp *) (pkt.eth + 1);
 5776|    834|    if (sizeof(*pkt.eth) + sizeof(*pkt.arp) > pkt.raw.len) return;  // Truncated
  ------------------
  |  Branch (5776:9): [True: 285, False: 549]
  ------------------
 5777|    549|    rx_arp(ifp, &pkt);
 5778|  2.63k|  } else if (pkt.eth->type == mg_htons(0x86dd)) {
  ------------------
  |  | 1059|  2.63k|#define mg_htons(x) mg_ntohs(x)
  ------------------
  |  Branch (5778:14): [True: 834, False: 1.79k]
  ------------------
 5779|    834|    pkt.ip6 = (struct ip6 *) (pkt.eth + 1);
 5780|    834|    if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip6)) return;  // Truncated
  ------------------
  |  Branch (5780:9): [True: 357, False: 477]
  ------------------
 5781|    477|    if ((pkt.ip6->ver >> 4) != 0x6) return;                         // Not IP
  ------------------
  |  Branch (5781:9): [True: 375, False: 102]
  ------------------
 5782|    102|    mkpay(&pkt, pkt.ip6 + 1);
 5783|    102|    rx_ip6(ifp, &pkt);
 5784|  1.79k|  } else if (pkt.eth->type == mg_htons(0x800)) {
  ------------------
  |  | 1059|  1.79k|#define mg_htons(x) mg_ntohs(x)
  ------------------
  |  Branch (5784:14): [True: 1.66k, False: 131]
  ------------------
 5785|  1.66k|    pkt.ip = (struct ip *) (pkt.eth + 1);
 5786|  1.66k|    if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip)) return;  // Truncated
  ------------------
  |  Branch (5786:9): [True: 357, False: 1.31k]
  ------------------
 5787|       |    // Truncate frame to what IP header tells us
 5788|  1.31k|    if ((size_t) mg_ntohs(pkt.ip->len) + sizeof(struct eth) < pkt.raw.len) {
  ------------------
  |  Branch (5788:9): [True: 250, False: 1.06k]
  ------------------
 5789|    250|      pkt.raw.len = (size_t) mg_ntohs(pkt.ip->len) + sizeof(struct eth);
 5790|    250|    }
 5791|  1.31k|    if (pkt.raw.len < sizeof(*pkt.eth) + sizeof(*pkt.ip)) return;  // Truncated
  ------------------
  |  Branch (5791:9): [True: 25, False: 1.28k]
  ------------------
 5792|  1.28k|    if ((pkt.ip->ver >> 4) != 4) return;                           // Not IP
  ------------------
  |  Branch (5792:9): [True: 1.11k, False: 173]
  ------------------
 5793|    173|    mkpay(&pkt, pkt.ip + 1);
 5794|    173|    rx_ip(ifp, &pkt);
 5795|    173|  } else {
 5796|    131|    MG_DEBUG(("Unknown eth type %x", mg_htons(pkt.eth->type)));
  ------------------
  |  |  962|    131|#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  |  |  ------------------
  |  |  |  |  955|    131|  do {                      \
  |  |  |  |  956|    131|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|    131|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5797|    131|    if (mg_log_level >= MG_LL_VERBOSE) mg_hexdump(buf, len >= 32 ? 32 : len);
  ------------------
  |  Branch (5797:9): [True: 0, False: 131]
  |  Branch (5797:56): [True: 0, False: 0]
  ------------------
 5798|    131|  }
 5799|  3.46k|}
fuzz.c:_ZL6rx_arpP11mg_tcpip_ifP3pkt:
 5246|    549|static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
 5247|    549|  if (pkt->arp->op == mg_htons(1) && pkt->arp->tpa == ifp->ip) {
  ------------------
  |  | 1059|  1.09k|#define mg_htons(x) mg_ntohs(x)
  ------------------
  |  Branch (5247:7): [True: 15, False: 534]
  |  Branch (5247:38): [True: 1, False: 14]
  ------------------
 5248|       |    // ARP request. Make a response, then send
 5249|       |    // MG_DEBUG(("ARP op %d %M: %M", mg_ntohs(pkt->arp->op), mg_print_ip4,
 5250|       |    //          &pkt->arp->spa, mg_print_ip4, &pkt->arp->tpa));
 5251|      1|    struct eth *eth = (struct eth *) ifp->tx.buf;
 5252|      1|    struct arp *arp = (struct arp *) (eth + 1);
 5253|      1|    memcpy(eth->dst, pkt->eth->src, sizeof(eth->dst));
 5254|      1|    memcpy(eth->src, ifp->mac, sizeof(eth->src));
 5255|      1|    eth->type = mg_htons(0x806);
  ------------------
  |  | 1059|      1|#define mg_htons(x) mg_ntohs(x)
  ------------------
 5256|      1|    *arp = *pkt->arp;
 5257|      1|    arp->op = mg_htons(2);
  ------------------
  |  | 1059|      1|#define mg_htons(x) mg_ntohs(x)
  ------------------
 5258|      1|    memcpy(arp->tha, pkt->arp->sha, sizeof(pkt->arp->tha));
 5259|      1|    memcpy(arp->sha, ifp->mac, sizeof(pkt->arp->sha));
 5260|      1|    arp->tpa = pkt->arp->spa;
 5261|      1|    arp->spa = ifp->ip;
 5262|      1|    MG_DEBUG(("ARP: tell %M we're %M", mg_print_ip4, &arp->tpa, mg_print_mac,
  ------------------
  |  |  962|      1|#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  |  |  ------------------
  |  |  |  |  955|      1|  do {                      \
  |  |  |  |  956|      1|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      1|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5263|      1|              &ifp->mac));
 5264|      1|    ether_output(ifp, PDIFF(eth, arp + 1));
  ------------------
  |  | 4918|      1|#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
  ------------------
 5265|    548|  } else if (pkt->arp->op == mg_htons(2)) {
  ------------------
  |  | 1059|    548|#define mg_htons(x) mg_ntohs(x)
  ------------------
  |  Branch (5265:14): [True: 5, False: 543]
  ------------------
 5266|      5|    if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) return;
  ------------------
  |  Branch (5266:9): [True: 5, False: 0]
  ------------------
 5267|      0|    if (pkt->arp->spa == ifp->gw) {
  ------------------
  |  Branch (5267:9): [True: 0, False: 0]
  ------------------
 5268|       |      // Got response for the GW ARP request. Set ifp->gwmac
 5269|      0|      memcpy(ifp->gwmac, pkt->arp->sha, sizeof(ifp->gwmac));
 5270|      0|    } else {
 5271|      0|      struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
 5272|      0|      if (c != NULL && c->is_arplooking) {
  ------------------
  |  Branch (5272:11): [True: 0, False: 0]
  |  Branch (5272:24): [True: 0, False: 0]
  ------------------
 5273|      0|        struct connstate *s = (struct connstate *) (c + 1);
 5274|      0|        memcpy(s->mac, pkt->arp->sha, sizeof(s->mac));
 5275|      0|        MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, c->rem.ip,
  ------------------
  |  |  962|      0|#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args)
  |  |  ------------------
  |  |  |  |  955|      0|  do {                      \
  |  |  |  |  956|      0|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      0|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5276|      0|                  mg_print_mac, s->mac));
 5277|      0|        c->is_arplooking = 0;
 5278|      0|        send_syn(c);
 5279|      0|        settmout(c, MIP_TTYPE_SYN);
  ------------------
  |  | 4940|      0|#define MIP_TTYPE_SYN 3        // SYN sent, waiting for response
  ------------------
 5280|      0|      }
 5281|      0|    }
 5282|      0|  }
 5283|    549|}
fuzz.c:_ZL7getpeerP6mg_mgrP3pktb:
 5232|    150|                                     bool lsn) {
 5233|    150|  struct mg_connection *c = NULL;
 5234|    150|  for (c = mgr->conns; c != NULL; c = c->next) {
  ------------------
  |  Branch (5234:24): [True: 0, False: 150]
  ------------------
 5235|      0|    if (c->is_arplooking && pkt->arp &&
  ------------------
  |  Branch (5235:9): [True: 0, False: 0]
  |  Branch (5235:29): [True: 0, False: 0]
  ------------------
 5236|      0|        memcmp(&pkt->arp->spa, c->rem.ip, sizeof(pkt->arp->spa)) == 0)
  ------------------
  |  Branch (5236:9): [True: 0, False: 0]
  ------------------
 5237|      0|      break;
 5238|      0|    if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) break;
  ------------------
  |  Branch (5238:9): [True: 0, False: 0]
  |  Branch (5238:22): [True: 0, False: 0]
  |  Branch (5238:34): [True: 0, False: 0]
  ------------------
 5239|      0|    if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport &&
  ------------------
  |  Branch (5239:9): [True: 0, False: 0]
  |  Branch (5239:23): [True: 0, False: 0]
  |  Branch (5239:35): [True: 0, False: 0]
  ------------------
 5240|      0|        lsn == c->is_listening && (lsn || c->rem.port == pkt->tcp->sport))
  ------------------
  |  Branch (5240:9): [True: 0, False: 0]
  |  Branch (5240:36): [True: 0, False: 0]
  |  Branch (5240:43): [True: 0, False: 0]
  ------------------
 5241|      0|      break;
 5242|      0|  }
 5243|    150|  return c;
 5244|    150|}
fuzz.c:_ZL5mkpayP3pktPv:
 5060|    369|static void mkpay(struct pkt *pkt, void *p) {
 5061|    369|  pkt->pay =
 5062|    369|      mg_str_n((char *) p, (size_t) (&pkt->raw.buf[pkt->raw.len] - (char *) p));
 5063|    369|}
fuzz.c:_ZL6rx_ip6P11mg_tcpip_ifP3pkt:
 5741|    102|static void rx_ip6(struct mg_tcpip_if *ifp, struct pkt *pkt) {
 5742|       |  // MG_DEBUG(("IP %d", (int) len));
 5743|    102|  if (pkt->ip6->proto == 1 || pkt->ip6->proto == 58) {
  ------------------
  |  Branch (5743:7): [True: 0, False: 102]
  |  Branch (5743:31): [True: 28, False: 74]
  ------------------
 5744|     28|    pkt->icmp = (struct icmp *) (pkt->ip6 + 1);
 5745|     28|    if (pkt->pay.len < sizeof(*pkt->icmp)) return;
  ------------------
  |  Branch (5745:9): [True: 3, False: 25]
  ------------------
 5746|     25|    mkpay(pkt, pkt->icmp + 1);
 5747|     25|    rx_icmp(ifp, pkt);
 5748|     74|  } else if (pkt->ip6->proto == 17) {
  ------------------
  |  Branch (5748:14): [True: 3, False: 71]
  ------------------
 5749|      3|    pkt->udp = (struct udp *) (pkt->ip6 + 1);
 5750|      3|    if (pkt->pay.len < sizeof(*pkt->udp)) return;
  ------------------
  |  Branch (5750:9): [True: 0, False: 3]
  ------------------
 5751|       |    // MG_DEBUG(("  UDP %u %u -> %u", len, mg_htons(udp->sport),
 5752|       |    // mg_htons(udp->dport)));
 5753|      3|    mkpay(pkt, pkt->udp + 1);
 5754|      3|  }
 5755|    102|}
fuzz.c:_ZL7rx_icmpP11mg_tcpip_ifP3pkt:
 5285|     62|static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
 5286|       |  // MG_DEBUG(("ICMP %d", (int) len));
 5287|     62|  if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) {
  ------------------
  |  Branch (5287:7): [True: 34, False: 28]
  |  Branch (5287:31): [True: 34, False: 0]
  |  Branch (5287:50): [True: 33, False: 1]
  ------------------
 5288|     33|    size_t hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp);
 5289|     33|    size_t space = ifp->tx.len - hlen, plen = pkt->pay.len;
 5290|     33|    if (plen > space) plen = space;
  ------------------
  |  Branch (5290:9): [True: 9, False: 24]
  ------------------
 5291|     33|    struct ip *ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
 5292|     33|                          sizeof(struct icmp) + plen);
 5293|     33|    struct icmp *icmp = (struct icmp *) (ip + 1);
 5294|     33|    memset(icmp, 0, sizeof(*icmp));        // Set csum to 0
 5295|     33|    memcpy(icmp + 1, pkt->pay.buf, plen);  // Copy RX payload to TX
 5296|     33|    icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen);
 5297|     33|    ether_output(ifp, hlen + plen);
 5298|     33|  }
 5299|     62|}
fuzz.c:_ZL5rx_ipP11mg_tcpip_ifP3pkt:
 5698|    173|static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
 5699|    173|  if (pkt->ip->frag & IP_MORE_FRAGS_MSK || pkt->ip->frag & IP_FRAG_OFFSET_MSK) {
  ------------------
  |  | 4965|    346|#define IP_MORE_FRAGS_MSK 0x20
  ------------------
                if (pkt->ip->frag & IP_MORE_FRAGS_MSK || pkt->ip->frag & IP_FRAG_OFFSET_MSK) {
  ------------------
  |  | 4964|    137|#define IP_FRAG_OFFSET_MSK 0xFF1F
  ------------------
  |  Branch (5699:7): [True: 36, False: 137]
  |  Branch (5699:44): [True: 62, False: 75]
  ------------------
 5700|     98|    if (pkt->ip->proto == 17) pkt->udp = (struct udp *) (pkt->ip + 1);
  ------------------
  |  Branch (5700:9): [True: 0, False: 98]
  ------------------
 5701|     98|    if (pkt->ip->proto == 6) pkt->tcp = (struct tcp *) (pkt->ip + 1);
  ------------------
  |  Branch (5701:9): [True: 3, False: 95]
  ------------------
 5702|     98|    struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
 5703|     98|    if (c) mg_error(c, "Received fragmented packet");
  ------------------
  |  Branch (5703:9): [True: 0, False: 98]
  ------------------
 5704|     98|  } else if (pkt->ip->proto == 1) {
  ------------------
  |  Branch (5704:14): [True: 38, False: 37]
  ------------------
 5705|     38|    pkt->icmp = (struct icmp *) (pkt->ip + 1);
 5706|     38|    if (pkt->pay.len < sizeof(*pkt->icmp)) return;
  ------------------
  |  Branch (5706:9): [True: 1, False: 37]
  ------------------
 5707|     37|    mkpay(pkt, pkt->icmp + 1);
 5708|     37|    rx_icmp(ifp, pkt);
 5709|     37|  } else if (pkt->ip->proto == 17) {
  ------------------
  |  Branch (5709:14): [True: 8, False: 29]
  ------------------
 5710|      8|    pkt->udp = (struct udp *) (pkt->ip + 1);
 5711|      8|    if (pkt->pay.len < sizeof(*pkt->udp)) return;
  ------------------
  |  Branch (5711:9): [True: 2, False: 6]
  ------------------
 5712|      6|    mkpay(pkt, pkt->udp + 1);
 5713|      6|    MG_VERBOSE(("UDP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src,
  ------------------
  |  |  963|      6|#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  |  |  ------------------
  |  |  |  |  955|      6|  do {                      \
  |  |  |  |  956|      6|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|      6|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5714|      6|                mg_ntohs(pkt->udp->sport), mg_print_ip4, &pkt->ip->dst,
 5715|      6|                mg_ntohs(pkt->udp->dport), (int) pkt->pay.len));
 5716|      6|    if (ifp->enable_dhcp_client && pkt->udp->dport == mg_htons(68)) {
  ------------------
  |  | 1059|      0|#define mg_htons(x) mg_ntohs(x)
  ------------------
  |  Branch (5716:9): [True: 0, False: 6]
  |  Branch (5716:36): [True: 0, False: 0]
  ------------------
 5717|      0|      pkt->dhcp = (struct dhcp *) (pkt->udp + 1);
 5718|      0|      mkpay(pkt, pkt->dhcp + 1);
 5719|      0|      rx_dhcp_client(ifp, pkt);
 5720|      6|    } else if (ifp->enable_dhcp_server && pkt->udp->dport == mg_htons(67)) {
  ------------------
  |  | 1059|      0|#define mg_htons(x) mg_ntohs(x)
  ------------------
  |  Branch (5720:16): [True: 0, False: 6]
  |  Branch (5720:43): [True: 0, False: 0]
  ------------------
 5721|      0|      pkt->dhcp = (struct dhcp *) (pkt->udp + 1);
 5722|      0|      mkpay(pkt, pkt->dhcp + 1);
 5723|      0|      rx_dhcp_server(ifp, pkt);
 5724|      6|    } else {
 5725|      6|      rx_udp(ifp, pkt);
 5726|      6|    }
 5727|     29|  } else if (pkt->ip->proto == 6) {
  ------------------
  |  Branch (5727:14): [True: 23, False: 6]
  ------------------
 5728|     23|    pkt->tcp = (struct tcp *) (pkt->ip + 1);
 5729|     23|    if (pkt->pay.len < sizeof(*pkt->tcp)) return;
  ------------------
  |  Branch (5729:9): [True: 0, False: 23]
  ------------------
 5730|     23|    mkpay(pkt, pkt->tcp + 1);
 5731|     23|    uint16_t iplen = mg_ntohs(pkt->ip->len);
 5732|     23|    uint16_t off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
 5733|     23|    if (iplen >= off) pkt->pay.len = (size_t) (iplen - off);
  ------------------
  |  Branch (5733:9): [True: 23, False: 0]
  ------------------
 5734|     23|    MG_VERBOSE(("TCP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src,
  ------------------
  |  |  963|     23|#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args)
  |  |  ------------------
  |  |  |  |  955|     23|  do {                      \
  |  |  |  |  956|     23|    if (0) mg_log args;     \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (956:9): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  |  |  957|     23|  } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (957:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5735|     23|                mg_ntohs(pkt->tcp->sport), mg_print_ip4, &pkt->ip->dst,
 5736|     23|                mg_ntohs(pkt->tcp->dport), (int) pkt->pay.len));
 5737|     23|    rx_tcp(ifp, pkt);
 5738|     23|  }
 5739|    173|}
fuzz.c:_ZL6rx_udpP11mg_tcpip_ifP3pkt:
 5401|      6|static void rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
 5402|      6|  struct mg_connection *c = getpeer(ifp->mgr, pkt, true);
 5403|      6|  if (c == NULL) {
  ------------------
  |  Branch (5403:7): [True: 6, False: 0]
  ------------------
 5404|       |    // No UDP listener on this port. Should send ICMP, but keep silent.
 5405|      6|  } else {
 5406|      0|    c->rem.port = pkt->udp->sport;
 5407|      0|    memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t));
 5408|      0|    struct connstate *s = (struct connstate *) (c + 1);
 5409|      0|    memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
 5410|      0|    if (c->recv.len >= MG_MAX_RECV_SIZE) {
  ------------------
  |  |  753|      0|#define MG_MAX_RECV_SIZE (3UL * 1024UL * 1024UL)  // Maximum recv IO buffer size
  ------------------
  |  Branch (5410:9): [True: 0, False: 0]
  ------------------
 5411|      0|      mg_error(c, "max_recv_buf_size reached");
 5412|      0|    } else if (c->recv.size - c->recv.len < pkt->pay.len &&
  ------------------
  |  Branch (5412:16): [True: 0, False: 0]
  ------------------
 5413|      0|               !mg_iobuf_resize(&c->recv, c->recv.len + pkt->pay.len)) {
  ------------------
  |  Branch (5413:16): [True: 0, False: 0]
  ------------------
 5414|      0|      mg_error(c, "oom");
 5415|      0|    } else {
 5416|      0|      memcpy(&c->recv.buf[c->recv.len], pkt->pay.buf, pkt->pay.len);
 5417|      0|      c->recv.len += pkt->pay.len;
 5418|      0|      mg_call(c, MG_EV_READ, &pkt->pay.len);
 5419|      0|    }
 5420|      0|  }
 5421|      6|}
fuzz.c:_ZL6rx_tcpP11mg_tcpip_ifP3pkt:
 5648|     23|static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
 5649|     23|  struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
 5650|     23|  struct connstate *s = c == NULL ? NULL : (struct connstate *) (c + 1);
  ------------------
  |  Branch (5650:25): [True: 23, False: 0]
  ------------------
 5651|       |#if 0
 5652|       |  MG_INFO(("%lu %hhu %d", c ? c->id : 0, pkt->tcp->flags, (int) pkt->pay.len));
 5653|       |#endif
 5654|     23|  if (c != NULL && c->is_connecting && pkt->tcp->flags == (TH_SYN | TH_ACK)) {
  ------------------
  |  | 5009|      0|#define TH_SYN 0x02
  ------------------
                if (c != NULL && c->is_connecting && pkt->tcp->flags == (TH_SYN | TH_ACK)) {
  ------------------
  |  | 5012|      0|#define TH_ACK 0x10
  ------------------
  |  Branch (5654:7): [True: 0, False: 23]
  |  Branch (5654:20): [True: 0, False: 0]
  |  Branch (5654:40): [True: 0, False: 0]
  ------------------
 5655|      0|    s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq) + 1;
 5656|      0|    tx_tcp_pkt(ifp, pkt, TH_ACK, pkt->tcp->ack, NULL, 0);
  ------------------
  |  | 5012|      0|#define TH_ACK 0x10
  ------------------
 5657|      0|    c->is_connecting = 0;  // Client connected
 5658|      0|    settmout(c, MIP_TTYPE_KEEPALIVE);
  ------------------
  |  | 4937|      0|#define MIP_TTYPE_KEEPALIVE 0  // Connection is idle for long, send keepalive
  ------------------
 5659|      0|    mg_call(c, MG_EV_CONNECT, NULL);  // Let user know
 5660|      0|    if (c->is_tls_hs) mg_tls_handshake(c);
  ------------------
  |  Branch (5660:9): [True: 0, False: 0]
  ------------------
 5661|     23|  } else if (c != NULL && c->is_connecting && pkt->tcp->flags != TH_ACK) {
  ------------------
  |  | 5012|      0|#define TH_ACK 0x10
  ------------------
  |  Branch (5661:14): [True: 0, False: 23]
  |  Branch (5661:27): [True: 0, False: 0]
  |  Branch (5661:47): [True: 0, False: 0]
  ------------------
 5662|       |    // mg_hexdump(pkt->raw.buf, pkt->raw.len);
 5663|      0|    tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  ------------------
  |  | 5010|      0|#define TH_RST 0x04
  ------------------
                  tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  ------------------
  |  | 5012|      0|#define TH_ACK 0x10
  ------------------
 5664|     23|  } else if (c != NULL && pkt->tcp->flags & TH_RST) {
  ------------------
  |  | 5010|      0|#define TH_RST 0x04
  ------------------
  |  Branch (5664:14): [True: 0, False: 23]
  |  Branch (5664:27): [True: 0, False: 0]
  ------------------
 5665|      0|    mg_error(c, "peer RST");  // RFC-1122 4.2.2.13
 5666|     23|  } else if (c != NULL) {
  ------------------
  |  Branch (5666:14): [True: 0, False: 23]
  ------------------
 5667|       |#if 0
 5668|       |    MG_DEBUG(("%lu %d %M:%hu -> %M:%hu", c->id, (int) pkt->raw.len,
 5669|       |              mg_print_ip4, &pkt->ip->src, mg_ntohs(pkt->tcp->sport),
 5670|       |              mg_print_ip4, &pkt->ip->dst, mg_ntohs(pkt->tcp->dport)));
 5671|       |    mg_hexdump(pkt->pay.buf, pkt->pay.len);
 5672|       |#endif
 5673|      0|    s->tmiss = 0;                         // Reset missed keep-alive counter
 5674|      0|    if (s->ttype == MIP_TTYPE_KEEPALIVE)  // Advance keep-alive timer
  ------------------
  |  | 4937|      0|#define MIP_TTYPE_KEEPALIVE 0  // Connection is idle for long, send keepalive
  ------------------
  |  Branch (5674:9): [True: 0, False: 0]
  ------------------
 5675|      0|      settmout(c,
 5676|      0|               MIP_TTYPE_KEEPALIVE);  // unless a former ACK timeout is pending
  ------------------
  |  | 4937|      0|#define MIP_TTYPE_KEEPALIVE 0  // Connection is idle for long, send keepalive
  ------------------
 5677|      0|    read_conn(c, pkt);  // Override timer with ACK timeout if needed
 5678|     23|  } else if ((c = getpeer(ifp->mgr, pkt, true)) == NULL) {
  ------------------
  |  Branch (5678:14): [True: 23, False: 0]
  ------------------
 5679|     23|    tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  ------------------
  |  | 5010|     23|#define TH_RST 0x04
  ------------------
                  tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  ------------------
  |  | 5012|     23|#define TH_ACK 0x10
  ------------------
 5680|     23|  } else if (pkt->tcp->flags & TH_RST) {
  ------------------
  |  | 5010|      0|#define TH_RST 0x04
  ------------------
  |  Branch (5680:14): [True: 0, False: 0]
  ------------------
 5681|      0|    if (c->is_accepted) mg_error(c, "peer RST");  // RFC-1122 4.2.2.13
  ------------------
  |  Branch (5681:9): [True: 0, False: 0]
  ------------------
 5682|       |    // ignore RST if not connected
 5683|      0|  } else if (pkt->tcp->flags & TH_SYN) {
  ------------------
  |  | 5009|      0|#define TH_SYN 0x02
  ------------------
  |  Branch (5683:14): [True: 0, False: 0]
  ------------------
 5684|       |    // Use peer's source port as ISN, in order to recognise the handshake
 5685|      0|    uint32_t isn = mg_htonl((uint32_t) mg_ntohs(pkt->tcp->sport));
  ------------------
  |  | 1060|      0|#define mg_htonl(x) mg_ntohl(x)
  ------------------
 5686|      0|    tx_tcp_pkt(ifp, pkt, TH_SYN | TH_ACK, isn, NULL, 0);
  ------------------
  |  | 5009|      0|#define TH_SYN 0x02
  ------------------
                  tx_tcp_pkt(ifp, pkt, TH_SYN | TH_ACK, isn, NULL, 0);
  ------------------
  |  | 5012|      0|#define TH_ACK 0x10
  ------------------
 5687|      0|  } else if (pkt->tcp->flags & TH_FIN) {
  ------------------
  |  | 5008|      0|#define TH_FIN 0x01
  ------------------
  |  Branch (5687:14): [True: 0, False: 0]
  ------------------
 5688|      0|    tx_tcp_pkt(ifp, pkt, TH_FIN | TH_ACK, pkt->tcp->ack, NULL, 0);
  ------------------
  |  | 5008|      0|#define TH_FIN 0x01
  ------------------
                  tx_tcp_pkt(ifp, pkt, TH_FIN | TH_ACK, pkt->tcp->ack, NULL, 0);
  ------------------
  |  | 5012|      0|#define TH_ACK 0x10
  ------------------
 5689|      0|  } else if (mg_htonl(pkt->tcp->ack) == mg_htons(pkt->tcp->sport) + 1U) {
  ------------------
  |  | 1060|      0|#define mg_htonl(x) mg_ntohl(x)
  ------------------
                } else if (mg_htonl(pkt->tcp->ack) == mg_htons(pkt->tcp->sport) + 1U) {
  ------------------
  |  | 1059|      0|#define mg_htons(x) mg_ntohs(x)
  ------------------
  |  Branch (5689:14): [True: 0, False: 0]
  ------------------
 5690|      0|    accept_conn(c, pkt);
 5691|      0|  } else if (!c->is_accepted) {  // no peer
  ------------------
  |  Branch (5691:14): [True: 0, False: 0]
  ------------------
 5692|      0|    tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  ------------------
  |  | 5010|      0|#define TH_RST 0x04
  ------------------
                  tx_tcp_pkt(ifp, pkt, TH_RST | TH_ACK, pkt->tcp->ack, NULL, 0);
  ------------------
  |  | 5012|      0|#define TH_ACK 0x10
  ------------------
 5693|      0|  } else {
 5694|       |    // MG_VERBOSE(("dropped silently.."));
 5695|      0|  }
 5696|     23|}
fuzz.c:_ZL10tx_tcp_pktP11mg_tcpip_ifP3pkthjPKvm:
 5465|     23|                         size_t len) {
 5466|     23|  uint32_t delta = (pkt->tcp->flags & (TH_SYN | TH_FIN)) ? 1 : 0;
  ------------------
  |  | 5009|     23|#define TH_SYN 0x02
  ------------------
                uint32_t delta = (pkt->tcp->flags & (TH_SYN | TH_FIN)) ? 1 : 0;
  ------------------
  |  | 5008|     23|#define TH_FIN 0x01
  ------------------
  |  Branch (5466:20): [True: 10, False: 13]
  ------------------
 5467|     23|  return tx_tcp(ifp, pkt->eth->src, pkt->ip->src, flags, pkt->tcp->dport,
 5468|     23|                pkt->tcp->sport, seq, mg_htonl(mg_ntohl(pkt->tcp->seq) + delta),
  ------------------
  |  | 1060|     23|#define mg_htonl(x) mg_ntohl(x)
  ------------------
 5469|     23|                buf, len);
 5470|     23|}

