LLVMFuzzerTestOneInput:
   35|    573|int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   36|    573|  char *s = fuzz_strdup(data, size);
   37|    573|  lien_adrfil *af = calloct(1, sizeof(*af));
  ------------------
  |  |  646|    573|#define calloct(A, B) calloc((A), (B))
  ------------------
   38|       |  /* fil_simplifie rewrites in place and may grow an empty path to "./" */
   39|    573|  char *path = malloct(size + 3);
  ------------------
  |  |  644|    573|#define malloct(A) malloc(A)
  ------------------
   40|       |
   41|    573|  (void) ident_url_absolute(s, af);
   42|    573|  memcpy(path, s, size + 1);
   43|    573|  fil_simplifie(path);
   44|       |
   45|    573|  freet(path);
  ------------------
  |  |  649|    573|  do {                                                                         \
  |  |  650|    573|    if ((A) != NULL) {                                                         \
  |  |  ------------------
  |  |  |  Branch (650:9): [True: 573, False: 0]
  |  |  ------------------
  |  |  651|    573|      free(A);                                                                 \
  |  |  652|    573|      (A) = NULL;                                                              \
  |  |  653|    573|    }                                                                          \
  |  |  654|    573|  } while (0)
  |  |  ------------------
  |  |  |  Branch (654:12): [Folded, False: 573]
  |  |  ------------------
  ------------------
   46|    573|  freet(af);
  ------------------
  |  |  649|    573|  do {                                                                         \
  |  |  650|    573|    if ((A) != NULL) {                                                         \
  |  |  ------------------
  |  |  |  Branch (650:9): [True: 573, False: 0]
  |  |  ------------------
  |  |  651|    573|      free(A);                                                                 \
  |  |  652|    573|      (A) = NULL;                                                              \
  |  |  653|    573|    }                                                                          \
  |  |  654|    573|  } while (0)
  |  |  ------------------
  |  |  |  Branch (654:12): [Folded, False: 573]
  |  |  ------------------
  ------------------
   47|       |  freet(s);
  ------------------
  |  |  649|    573|  do {                                                                         \
  |  |  650|    573|    if ((A) != NULL) {                                                         \
  |  |  ------------------
  |  |  |  Branch (650:9): [True: 573, False: 0]
  |  |  ------------------
  |  |  651|    573|      free(A);                                                                 \
  |  |  652|    573|      (A) = NULL;                                                              \
  |  |  653|    573|    }                                                                          \
  |  |  654|    573|  } while (0)
  |  |  ------------------
  |  |  |  Branch (654:12): [Folded, False: 573]
  |  |  ------------------
  ------------------
   48|    573|  return 0;
   49|    573|}

fuzz-url.c:fuzz_strdup:
   41|    573|HTS_UNUSED static char *fuzz_strdup(const uint8_t *data, size_t size) {
   42|    573|  char *s = malloct(size + 1);
  ------------------
  |  |  644|    573|#define malloct(A) malloc(A)
  ------------------
   43|       |
   44|    573|  memcpy(s, data, size);
   45|    573|  s[size] = '\0';
   46|    573|  return s;
   47|    573|}

ident_url_absolute:
 2390|    573|int ident_url_absolute(const char *url, lien_adrfil *adrfil) {
 2391|    573|  int pos = 0;
 2392|    573|  int scheme = 0;
 2393|       |
 2394|       |  // effacer adrfil->adr et adrfil->fil
 2395|    573|  adrfil->adr[0] = adrfil->fil[0] = '\0';
 2396|       |
 2397|       |  // Reject an over-long URL: a root-relative path is copied whole into fil[].
 2398|    573|  if (strlen(url) >= HTS_URLMAXSIZE * 2)
  ------------------
  |  |  236|    573|#define HTS_URLMAXSIZE 1024
  ------------------
  |  Branch (2398:7): [True: 9, False: 564]
  ------------------
 2399|      9|    return -1;
 2400|       |
 2401|       |#if HDEBUG
 2402|       |  printf("protocol: %s\n", url);
 2403|       |#endif
 2404|       |
 2405|       |  // Scheme?
 2406|    564|  {
 2407|    564|    const char *a = url;
 2408|       |
 2409|    564|    while(isalpha((unsigned char) *a))
  ------------------
  |  Branch (2409:11): [True: 1.36k, False: 564]
  ------------------
 2410|  1.36k|      a++;
 2411|    564|    if (*a == ':')
  ------------------
  |  Branch (2411:9): [True: 144, False: 420]
  ------------------
 2412|    144|      scheme = 1;
 2413|    564|  }
 2414|       |
 2415|       |  // 1. optional scheme ":"
 2416|    564|  if ((pos = strfield(url, "file:"))) { // fichier local!! (pour les tests)
  ------------------
  |  Branch (2416:7): [True: 106, False: 458]
  ------------------
 2417|       |    //!!p+=3;
 2418|    106|    strcpybuff(adrfil->adr, "file://");
  ------------------
  |  |  265|    106|  __builtin_choose_expr(HTS_IS_CHAR_BUFFER(A),                                 \
  |  |  ------------------
  |  |  |  |  113|    106|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  266|    106|                        strcpy_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B),      \
  |  |  ------------------
  |  |  |  |  125|    106|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    106|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    106|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 106]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  267|    106|                                     "overflow while copying '" #B "' to '" #A \
  |  |  268|    106|                                     "'",                                      \
  |  |  269|    106|                                     __FILE__, __LINE__),                      \
  |  |  270|    106|                        strcpybuff_ptr_((A), (B)))
  ------------------
 2419|    458|  } else if ((pos = strfield(url, "http:"))) {  // HTTP
  ------------------
  |  Branch (2419:14): [True: 1, False: 457]
  ------------------
 2420|       |    //!!p+=3;
 2421|    457|  } else if ((pos = strfield(url, "ftp:"))) {   // FTP
  ------------------
  |  Branch (2421:14): [True: 35, False: 422]
  ------------------
 2422|     35|    strcpybuff(adrfil->adr, "ftp://");  // FTP!!
  ------------------
  |  |  265|     35|  __builtin_choose_expr(HTS_IS_CHAR_BUFFER(A),                                 \
  |  |  ------------------
  |  |  |  |  113|     35|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  266|     35|                        strcpy_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B),      \
  |  |  ------------------
  |  |  |  |  125|     35|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     35|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     35|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 35]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  267|     35|                                     "overflow while copying '" #B "' to '" #A \
  |  |  268|     35|                                     "'",                                      \
  |  |  269|     35|                                     __FILE__, __LINE__),                      \
  |  |  270|     35|                        strcpybuff_ptr_((A), (B)))
  ------------------
 2423|       |    //!!p+=3;
 2424|       |#if HTS_USEOPENSSL
 2425|       |  } else if ((pos = strfield(url, "https:"))) {     // HTTPS
 2426|       |    strcpybuff(adrfil->adr, "https://");
 2427|       |#endif
 2428|    422|  } else if (scheme) {
  ------------------
  |  Branch (2428:14): [True: 2, False: 420]
  ------------------
 2429|      2|    return -1;                  // erreur non reconnu
 2430|      2|  } else
 2431|    420|    pos = 0;
 2432|       |
 2433|       |  // 2. optional "//" authority
 2434|    562|  if (strncmp(url + pos, "//", 2) == 0)
  ------------------
  |  Branch (2434:7): [True: 53, False: 509]
  ------------------
 2435|     53|    pos += 2;
 2436|       |
 2437|       |  // (url+pos) now points to the path (not net path)
 2438|       |
 2439|       |  //## if (adrfil->adr[0]!=lOCAL_CHAR) {    // adrfil->adresse normale http
 2440|    562|  if (!strfield(adrfil->adr, "file:")) {        // PAS adrfil->file://
  ------------------
  |  Branch (2440:7): [True: 456, False: 106]
  ------------------
 2441|    456|    const char *p, *q;
 2442|       |
 2443|    456|    p = url + pos;
 2444|       |
 2445|       |    // p pointe sur le début de l'adrfil->adresse, ex: www.truc.fr/sommaire/index.html
 2446|    456|    q = strchr(jump_identification_const(p), '/');
 2447|    456|    if (q == 0)
  ------------------
  |  Branch (2447:9): [True: 324, False: 132]
  ------------------
 2448|    324|      q = strchr(jump_identification_const(p), '?');  // http://www.foo.com?bar=1
 2449|    456|    if (q == 0)
  ------------------
  |  Branch (2449:9): [True: 279, False: 177]
  ------------------
 2450|    279|      q = p + strlen(p);        // pointe sur \0
 2451|       |    // q pointe sur le chemin, ex: index.html?query=recherche
 2452|       |
 2453|       |    // chemin www... trop long!!
 2454|    456|    if ((((int) (q - p))) > HTS_URLMAXSIZE) {
  ------------------
  |  |  236|    456|#define HTS_URLMAXSIZE 1024
  ------------------
  |  Branch (2454:9): [True: 2, False: 454]
  ------------------
 2455|      2|      return -1;                // erreur
 2456|      2|    }
 2457|       |    // recopier adrfil->adresse www..
 2458|    454|    strncatbuff(adrfil->adr, p, ((int) (q - p)));
  ------------------
  |  |  219|    454|  __builtin_choose_expr(HTS_IS_CHAR_BUFFER(A),                                 \
  |  |  ------------------
  |  |  |  |  113|    454|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  220|    454|                        strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), N,  \
  |  |  ------------------
  |  |  |  |  125|    454|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    454|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    454|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 454, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  221|    454|                                      "overflow while appending '" #B          \
  |  |  222|    454|                                      "' to '" #A "'",                         \
  |  |  223|    454|                                      __FILE__, __LINE__),                     \
  |  |  224|    454|                        strncatbuff_ptr_((A), (B), (N)))
  ------------------
 2459|       |    // *( adrfil->adr+( ((int) q) - ((int) p) ) )=0;  // faut arrêter la fumette!
 2460|       |
 2461|       |    // fil[] holds the path plus a possible leading '/' the top strlen() misses.
 2462|    454|    if (strlen(q) >= sizeof(adrfil->fil) - (q[0] != '/' ? 1 : 0))
  ------------------
  |  Branch (2462:9): [True: 3, False: 451]
  |  Branch (2462:45): [True: 322, False: 132]
  ------------------
 2463|      3|      return -1;
 2464|       |
 2465|       |    // recopier chemin /pub/..
 2466|    451|    if (q[0] != '/')            // page par défaut (/)
  ------------------
  |  Branch (2466:9): [True: 319, False: 132]
  ------------------
 2467|    319|      strcatbuff(adrfil->fil, "/");
  ------------------
  |  |  242|    319|  __builtin_choose_expr(                                                       \
  |  |  243|    319|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|    319|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|    319|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|    319|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    319|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    319|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 319]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|    319|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|    319|      strcatbuff_ptr_((A), (B)))
  ------------------
 2468|    451|    strcatbuff(adrfil->fil, q);
  ------------------
  |  |  242|    451|  __builtin_choose_expr(                                                       \
  |  |  243|    451|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|    451|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|    451|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|    451|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    451|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    451|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 451, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|    451|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|    451|      strcatbuff_ptr_((A), (B)))
  ------------------
 2469|       |    // SECURITE:
 2470|       |    // simplifier url pour les ../
 2471|    451|    fil_simplifie(adrfil->fil);
 2472|    451|  } else {                      // localhost adrfil->file://
 2473|    106|    const char *p;
 2474|    106|    size_t i;
 2475|    106|    char *a;
 2476|       |
 2477|    106|    p = url + pos;
 2478|    106|    if (*p == '/' || *p == '\\') {      /* adrfil->file:///.. */
  ------------------
  |  Branch (2478:9): [True: 15, False: 91]
  |  Branch (2478:22): [True: 12, False: 79]
  ------------------
 2479|     27|      strcatbuff(adrfil->fil, p);       // fichier local ; adrfil->adr="#"
  ------------------
  |  |  242|     27|  __builtin_choose_expr(                                                       \
  |  |  243|     27|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|     27|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|     27|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|     27|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     27|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     27|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 27, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|     27|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|     27|      strcatbuff_ptr_((A), (B)))
  ------------------
 2480|     79|    } else {
 2481|     79|      if (*p == '\0' || p[1] != ':') {  /* empty path: not a DOS drive letter */
  ------------------
  |  Branch (2481:11): [True: 1, False: 78]
  |  Branch (2481:25): [True: 49, False: 29]
  ------------------
 2482|     50|        strcatbuff(adrfil->fil, "//");  /* adrfil->file://server/foo */
  ------------------
  |  |  242|     50|  __builtin_choose_expr(                                                       \
  |  |  243|     50|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|     50|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|     50|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|     50|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     50|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     50|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 50]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|     50|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|     50|      strcatbuff_ptr_((A), (B)))
  ------------------
 2483|     50|        strcatbuff(adrfil->fil, p);
  ------------------
  |  |  242|     50|  __builtin_choose_expr(                                                       \
  |  |  243|     50|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|     50|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|     50|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|     50|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     50|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     50|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 50, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|     50|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|     50|      strcatbuff_ptr_((A), (B)))
  ------------------
 2484|     50|      } else {
 2485|     29|        strcatbuff(adrfil->fil, p);     // adrfil->file://C:\..
  ------------------
  |  |  242|     29|  __builtin_choose_expr(                                                       \
  |  |  243|     29|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|     29|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|     29|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|     29|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     29|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     29|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 29, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|     29|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|     29|      strcatbuff_ptr_((A), (B)))
  ------------------
 2486|     29|      }
 2487|     79|    }
 2488|       |
 2489|    106|    a = strchr(adrfil->fil, '?');
 2490|    106|    if (a)
  ------------------
  |  Branch (2490:9): [True: 16, False: 90]
  ------------------
 2491|     16|      *a = '\0';                /* couper query (inutile pour adrfil->file:// lors de la requête) */
 2492|       |    // adrfil->filtrer les \\ -> / pour les fichiers DOS
 2493|  42.6k|    for(i = 0; adrfil->fil[i] != '\0'; i++)
  ------------------
  |  Branch (2493:16): [True: 42.5k, False: 106]
  ------------------
 2494|  42.5k|      if (adrfil->fil[i] == '\\')
  ------------------
  |  Branch (2494:11): [True: 647, False: 41.8k]
  ------------------
 2495|    647|        adrfil->fil[i] = '/';
 2496|       |    // collapse ../ like the http branch above (path-traversal safety)
 2497|    106|    fil_simplifie(adrfil->fil);
 2498|    106|  }
 2499|       |
 2500|       |  // no hostname
 2501|    557|  if (!strnotempty(adrfil->adr))
  ------------------
  |  |  313|    557|#define strnotempty(A) (((A) != NULL && (A)[0] != '\0'))
  |  |  ------------------
  |  |  |  Branch (313:26): [True: 557, False: 0]
  |  |  |  Branch (313:41): [True: 454, False: 103]
  |  |  ------------------
  ------------------
 2502|    103|    return -1;                  // erreur non reconnu
 2503|       |
 2504|       |  // nommer au besoin.. (non utilisé normalement)
 2505|    454|  if (!strnotempty(adrfil->fil))
  ------------------
  |  |  313|    454|#define strnotempty(A) (((A) != NULL && (A)[0] != '\0'))
  |  |  ------------------
  |  |  |  Branch (313:26): [True: 454, False: 0]
  |  |  |  Branch (313:41): [True: 454, False: 0]
  |  |  ------------------
  ------------------
 2506|      0|    strcpybuff(adrfil->fil, "default-index.html");
  ------------------
  |  |  265|      0|  __builtin_choose_expr(HTS_IS_CHAR_BUFFER(A),                                 \
  |  |  ------------------
  |  |  |  |  113|      0|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  266|      0|                        strcpy_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B),      \
  |  |  ------------------
  |  |  |  |  125|      0|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|      0|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|      0|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  267|      0|                                     "overflow while copying '" #B "' to '" #A \
  |  |  268|      0|                                     "'",                                      \
  |  |  269|      0|                                     __FILE__, __LINE__),                      \
  |  |  270|      0|                        strcpybuff_ptr_((A), (B)))
  ------------------
 2507|       |
 2508|       |  // case insensitive pour adrfil->adresse
 2509|    454|  {
 2510|    454|    char *a = jump_identification(adrfil->adr);
 2511|       |
 2512|  10.9k|    while(*a) {
  ------------------
  |  Branch (2512:11): [True: 10.5k, False: 454]
  ------------------
 2513|  10.5k|      if ((*a >= 'A') && (*a <= 'Z'))
  ------------------
  |  Branch (2513:11): [True: 4.09k, False: 6.42k]
  |  Branch (2513:26): [True: 1.24k, False: 2.84k]
  ------------------
 2514|  1.24k|        *a += 'a' - 'A';
 2515|  10.5k|      a++;
 2516|  10.5k|    }
 2517|    454|  }
 2518|       |
 2519|    454|  return 0;
 2520|    557|}
fil_simplifie:
 2523|  1.13k|void fil_simplifie(char *f) {
 2524|  1.13k|  char *a, *b;
 2525|  1.13k|  char *rollback[128];
 2526|  1.13k|  int rollid = 0;
 2527|  1.13k|  char lc = '/';
 2528|  1.13k|  int query = 0;
 2529|  1.13k|  int wasAbsolute = (*f == '/');
 2530|       |
 2531|   633k|  for(a = b = f; *a != '\0';) {
  ------------------
  |  Branch (2531:18): [True: 632k, False: 1.11k]
  ------------------
 2532|   632k|    if (*a == '?')
  ------------------
  |  Branch (2532:9): [True: 851, False: 631k]
  ------------------
 2533|    851|      query = 1;
 2534|   632k|    if (query == 0 && lc == '/' && a[0] == '.' && a[1] == '/') {        /* foo/./bar or ./foo  */
  ------------------
  |  Branch (2534:9): [True: 271k, False: 360k]
  |  Branch (2534:23): [True: 12.6k, False: 259k]
  |  Branch (2534:36): [True: 5.97k, False: 6.71k]
  |  Branch (2534:51): [True: 401, False: 5.57k]
  ------------------
 2535|    401|      a += 2;
 2536|   632k|    } else if (query == 0 && lc == '/' && a[0] == '.' && a[1] == '.' && (a[2] == '/' || a[2] == '\0')) {        /* foo/../bar or ../foo or .. */
  ------------------
  |  Branch (2536:16): [True: 271k, False: 360k]
  |  Branch (2536:30): [True: 12.2k, False: 259k]
  |  Branch (2536:43): [True: 5.57k, False: 6.71k]
  |  Branch (2536:58): [True: 4.71k, False: 853]
  |  Branch (2536:74): [True: 3.99k, False: 726]
  |  Branch (2536:89): [True: 66, False: 660]
  ------------------
 2537|  4.05k|      if (a[2] == '\0')
  ------------------
  |  Branch (2537:11): [True: 66, False: 3.99k]
  ------------------
 2538|     66|        a += 2;
 2539|  3.99k|      else
 2540|  3.99k|        a += 3;
 2541|  4.05k|      if (rollid > 1) {
  ------------------
  |  Branch (2541:11): [True: 1.43k, False: 2.62k]
  ------------------
 2542|  1.43k|        rollid--;
 2543|  1.43k|        b = rollback[rollid - 1];
 2544|  2.62k|      } else {                  /* too many ../ */
 2545|  2.62k|        rollid = 0;
 2546|  2.62k|        b = f;
 2547|  2.62k|        if (wasAbsolute)
  ------------------
  |  Branch (2547:13): [True: 935, False: 1.68k]
  ------------------
 2548|    935|          b++;                  /* after the / */
 2549|  2.62k|      }
 2550|   628k|    } else {
 2551|   628k|      *b++ = lc = *a;
 2552|   628k|      if (*a == '/') {
  ------------------
  |  Branch (2552:11): [True: 8.89k, False: 619k]
  ------------------
 2553|  8.89k|        rollback[rollid++] = b;
 2554|  8.89k|        if (rollid >= 127) {
  ------------------
  |  Branch (2554:13): [True: 15, False: 8.87k]
  ------------------
 2555|     15|          *f = '\0';            /* ERROR */
 2556|     15|          break;
 2557|     15|        }
 2558|  8.89k|      }
 2559|   628k|      a++;
 2560|   628k|    }
 2561|   632k|  }
 2562|  1.13k|  *b = '\0';
 2563|  1.13k|  if (*f == '\0') {
  ------------------
  |  Branch (2563:7): [True: 37, False: 1.09k]
  ------------------
 2564|     37|    if (wasAbsolute) {
  ------------------
  |  Branch (2564:9): [True: 8, False: 29]
  ------------------
 2565|      8|      f[0] = '/';
 2566|      8|      f[1] = '\0';
 2567|     29|    } else {
 2568|     29|      f[0] = '.';
 2569|     29|      f[1] = '/';
 2570|     29|      f[2] = '\0';
 2571|     29|    }
 2572|     37|  }
 2573|  1.13k|}
jump_identification_const:
 3405|  1.23k|HTSEXT_API const char *jump_identification_const(const char *source) {
 3406|  1.23k|  const char *a, *trytofind;
 3407|       |
 3408|  1.23k|  if (strcmp(source, "file://") == 0)
  ------------------
  |  Branch (3408:7): [True: 107, False: 1.12k]
  ------------------
 3409|    107|    return source;
 3410|       |  // rechercher dernier @ (car parfois email transmise dans adresse!)
 3411|       |  // mais sauter ftp:// éventuel
 3412|  1.12k|  a = jump_protocol_const(source);
 3413|  1.12k|  trytofind = strrchr_limit(a, '@', strchr(a, '/'));
 3414|  1.12k|  return trytofind != NULL ? trytofind : a;
  ------------------
  |  Branch (3414:10): [True: 61, False: 1.06k]
  ------------------
 3415|  1.23k|}
strrchr_limit:
 4058|  1.12k|const char *strrchr_limit(const char *s, char c, const char *limit) {
 4059|  1.12k|  if (limit == NULL) {
  ------------------
  |  Branch (4059:7): [True: 994, False: 133]
  ------------------
 4060|    994|    const char *p = strrchr(s, c);
 4061|       |
 4062|    994|    return p ? (p + 1) : NULL;
  ------------------
  |  Branch (4062:12): [True: 48, False: 946]
  ------------------
 4063|    994|  } else {
 4064|    133|    const char *a = NULL, *p;
 4065|       |
 4066|    410|    for(;;) {
 4067|    410|      p = strchr((a) ? a : s, c);
  ------------------
  |  Branch (4067:18): [True: 277, False: 133]
  ------------------
 4068|    410|      if ((p >= limit) || (p == NULL))
  ------------------
  |  Branch (4068:11): [True: 4, False: 406]
  |  Branch (4068:27): [True: 129, False: 277]
  ------------------
 4069|    133|        return a;
 4070|    277|      a = p + 1;
 4071|    277|    }
 4072|    133|  }
 4073|  1.12k|}
jump_protocol_const:
 4076|  1.12k|const char *jump_protocol_const(const char *source) {
 4077|  1.12k|  int p;
 4078|       |
 4079|       |  // scheme
 4080|       |  // "Comparisons of scheme names MUST be case-insensitive" (RFC2616)
 4081|  1.12k|  if ((p = strfield(source, "http:")))
  ------------------
  |  Branch (4081:7): [True: 9, False: 1.11k]
  ------------------
 4082|      9|    source += p;
 4083|  1.11k|  else if ((p = strfield(source, "ftp:")))
  ------------------
  |  Branch (4083:12): [True: 41, False: 1.07k]
  ------------------
 4084|     41|    source += p;
 4085|  1.07k|  else if ((p = strfield(source, "https:")))
  ------------------
  |  Branch (4085:12): [True: 7, False: 1.07k]
  ------------------
 4086|      7|    source += p;
 4087|  1.07k|  else if ((p = strfield(source, "file:")))
  ------------------
  |  Branch (4087:12): [True: 57, False: 1.01k]
  ------------------
 4088|     57|    source += p;
 4089|  1.01k|  else if ((p = strfield(source, "socks5h:")))
  ------------------
  |  Branch (4089:12): [True: 10, False: 1.00k]
  ------------------
 4090|     10|    source += p;
 4091|  1.00k|  else if ((p = strfield(source, "socks5:")))
  ------------------
  |  Branch (4091:12): [True: 7, False: 996]
  ------------------
 4092|      7|    source += p;
 4093|    996|  else if ((p = strfield(source, "connect:")))
  ------------------
  |  Branch (4093:12): [True: 5, False: 991]
  ------------------
 4094|      5|    source += p;
 4095|       |  // net_path
 4096|  1.12k|  if (strncmp(source, "//", 2) == 0)
  ------------------
  |  Branch (4096:7): [True: 76, False: 1.05k]
  ------------------
 4097|     76|    source += 2;
 4098|  1.12k|  return source;
 4099|  1.12k|}

htslib.c:strfield:
  562|  9.44k|HTS_STATIC int strfield(const char *f, const char *s) {
  563|  9.44k|  int r = 0;
  564|       |
  565|  13.2k|  while(streql(*f, *s) && ((*f) != 0) && ((*s) != 0)) {
  ------------------
  |  |  105|  26.5k|#define streql(a,b) (hichar(a)==hichar(b))
  |  |  ------------------
  |  |  |  |  103|  13.2k|#define hichar(a) ((((a)>='a') && ((a)<='z')) ? ((a)-('a'-'A')) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:21): [True: 4.92k, False: 8.34k]
  |  |  |  |  |  Branch (103:35): [True: 4.81k, False: 113]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define streql(a,b) (hichar(a)==hichar(b))
  |  |  ------------------
  |  |  |  |  103|  13.2k|#define hichar(a) ((((a)>='a') && ((a)<='z')) ? ((a)-('a'-'A')) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:21): [True: 12.3k, False: 968]
  |  |  |  |  |  Branch (103:35): [True: 12.3k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (105:21): [True: 3.88k, False: 9.38k]
  |  |  ------------------
  ------------------
  |  Branch (565:27): [True: 3.82k, False: 56]
  |  Branch (565:42): [True: 3.82k, False: 0]
  ------------------
  566|  3.82k|    f++;
  567|  3.82k|    s++;
  568|  3.82k|    r++;
  569|  3.82k|  }
  570|  9.44k|  if (*s == 0)
  ------------------
  |  Branch (570:7): [True: 384, False: 9.06k]
  ------------------
  571|    384|    return r;
  572|  9.06k|  else
  573|  9.06k|    return 0;
  574|  9.44k|}

htslib.c:strcpy_safe_:
  376|    141|             const char *exp, const char *file, int line) {
  377|    141|  assertf_(sizeof_dest != 0, file, line);
  ------------------
  |  |   86|    141|#define assertf_(exp, file, line) assertf__(exp, #exp, file, line)
  |  |  ------------------
  |  |  |  |   81|    141|  (void) ((exp) || (abortf_(sexp, file, line), 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (81:11): [True: 141, False: 0]
  |  |  |  |  |  Branch (81:20): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  378|    141|  dest[0] = '\0';
  379|    141|  return strncat_safe_(dest, sizeof_dest, source, sizeof_source, (size_t) -1,
  380|    141|                       exp, file, line);
  381|    141|}
htslib.c:strncat_safe_:
  358|  1.52k|              const size_t n, const char *exp, const char *file, int line) {
  359|  1.52k|  const size_t source_len = strlen_safe_(source, sizeof_source, file, line);
  360|  1.52k|  const size_t dest_len = strlen_safe_(dest, sizeof_dest, file, line);
  361|       |  /* note: "size_t is an unsigned integral type" ((size_t) -1 is positive) */
  362|  1.52k|  const size_t source_copy = source_len <= n ? source_len : n;
  ------------------
  |  Branch (362:30): [True: 1.34k, False: 177]
  ------------------
  363|  1.52k|  const size_t dest_final_len = dest_len + source_copy;
  364|  1.52k|  assertf__(dest_final_len < sizeof_dest, exp, file, line);
  ------------------
  |  |   81|  1.52k|  (void) ((exp) || (abortf_(sexp, file, line), 0))
  |  |  ------------------
  |  |  |  Branch (81:11): [True: 1.52k, False: 0]
  |  |  |  Branch (81:20): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  365|  1.52k|  memcpy(dest + dest_len, source, source_copy);
  366|  1.52k|  dest[dest_final_len] = '\0';
  367|  1.52k|  return dest;
  368|  1.52k|}
htslib.c:strlen_safe_:
  341|  3.04k|                                                 const char *file, int line) {
  342|  3.04k|  size_t size;
  343|  3.04k|  assertf_(source != NULL, file, line);
  ------------------
  |  |   86|  3.04k|#define assertf_(exp, file, line) assertf__(exp, #exp, file, line)
  |  |  ------------------
  |  |  |  |   81|  3.04k|  (void) ((exp) || (abortf_(sexp, file, line), 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (81:11): [True: 3.04k, False: 0]
  |  |  |  |  |  Branch (81:20): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  344|  3.04k|  size = sizeof_source != (size_t) -1 ? htssafe_strnlen_(source, sizeof_source)
  ------------------
  |  Branch (344:10): [True: 2.03k, False: 1.01k]
  ------------------
  345|  3.04k|                                      : strlen(source);
  346|  3.04k|  assertf_(size < sizeof_source, file, line);
  ------------------
  |  |   86|  3.04k|#define assertf_(exp, file, line) assertf__(exp, #exp, file, line)
  |  |  ------------------
  |  |  |  |   81|  3.04k|  (void) ((exp) || (abortf_(sexp, file, line), 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (81:11): [True: 3.04k, False: 0]
  |  |  |  |  |  Branch (81:20): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  347|  3.04k|  return size;
  348|  3.04k|}
htslib.c:htssafe_strnlen_:
  316|  2.03k|                                                     size_t maxlen) {
  317|  2.03k|#if (defined(_WIN32) || (defined(HAVE_STRNLEN) && !defined(__STRICT_ANSI__)))
  318|  2.03k|  return strnlen(s, maxlen);
  319|       |#else
  320|       |  size_t i;
  321|       |  for (i = 0; i < maxlen && s[i] != '\0'; i++)
  322|       |    ;
  323|       |  return i;
  324|       |#endif
  325|  2.03k|}

