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

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

ident_url_absolute:
 2368|    534|int ident_url_absolute(const char *url, lien_adrfil *adrfil) {
 2369|    534|  int pos = 0;
 2370|    534|  int scheme = 0;
 2371|       |
 2372|       |  // effacer adrfil->adr et adrfil->fil
 2373|    534|  adrfil->adr[0] = adrfil->fil[0] = '\0';
 2374|       |
 2375|       |  // Reject an over-long URL: a root-relative path is copied whole into fil[].
 2376|    534|  if (strlen(url) >= HTS_URLMAXSIZE * 2)
  ------------------
  |  |  214|    534|#define HTS_URLMAXSIZE 1024
  ------------------
  |  Branch (2376:7): [True: 9, False: 525]
  ------------------
 2377|      9|    return -1;
 2378|       |
 2379|       |#if HDEBUG
 2380|       |  printf("protocol: %s\n", url);
 2381|       |#endif
 2382|       |
 2383|       |  // Scheme?
 2384|    525|  {
 2385|    525|    const char *a = url;
 2386|       |
 2387|    525|    while(isalpha((unsigned char) *a))
  ------------------
  |  Branch (2387:11): [True: 1.34k, False: 525]
  ------------------
 2388|  1.34k|      a++;
 2389|    525|    if (*a == ':')
  ------------------
  |  Branch (2389:9): [True: 152, False: 373]
  ------------------
 2390|    152|      scheme = 1;
 2391|    525|  }
 2392|       |
 2393|       |  // 1. optional scheme ":"
 2394|    525|  if ((pos = strfield(url, "file:"))) { // fichier local!! (pour les tests)
  ------------------
  |  Branch (2394:7): [True: 114, False: 411]
  ------------------
 2395|       |    //!!p+=3;
 2396|    114|    strcpybuff(adrfil->adr, "file://");
  ------------------
  |  |  265|    114|  __builtin_choose_expr(HTS_IS_CHAR_BUFFER(A),                                 \
  |  |  ------------------
  |  |  |  |  113|    114|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  266|    114|                        strcpy_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B),      \
  |  |  ------------------
  |  |  |  |  125|    114|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    114|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    114|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 114]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  267|    114|                                     "overflow while copying '" #B "' to '" #A \
  |  |  268|    114|                                     "'",                                      \
  |  |  269|    114|                                     __FILE__, __LINE__),                      \
  |  |  270|    114|                        strcpybuff_ptr_((A), (B)))
  ------------------
 2397|    411|  } else if ((pos = strfield(url, "http:"))) {  // HTTP
  ------------------
  |  Branch (2397:14): [True: 1, False: 410]
  ------------------
 2398|       |    //!!p+=3;
 2399|    410|  } else if ((pos = strfield(url, "ftp:"))) {   // FTP
  ------------------
  |  Branch (2399:14): [True: 35, False: 375]
  ------------------
 2400|     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)))
  ------------------
 2401|       |    //!!p+=3;
 2402|       |#if HTS_USEOPENSSL
 2403|       |  } else if ((pos = strfield(url, "https:"))) {     // HTTPS
 2404|       |    strcpybuff(adrfil->adr, "https://");
 2405|       |#endif
 2406|    375|  } else if (scheme) {
  ------------------
  |  Branch (2406:14): [True: 2, False: 373]
  ------------------
 2407|      2|    return -1;                  // erreur non reconnu
 2408|      2|  } else
 2409|    373|    pos = 0;
 2410|       |
 2411|       |  // 2. optional "//" authority
 2412|    523|  if (strncmp(url + pos, "//", 2) == 0)
  ------------------
  |  Branch (2412:7): [True: 48, False: 475]
  ------------------
 2413|     48|    pos += 2;
 2414|       |
 2415|       |  // (url+pos) now points to the path (not net path)
 2416|       |
 2417|       |  //## if (adrfil->adr[0]!=lOCAL_CHAR) {    // adrfil->adresse normale http
 2418|    523|  if (!strfield(adrfil->adr, "file:")) {        // PAS adrfil->file://
  ------------------
  |  Branch (2418:7): [True: 409, False: 114]
  ------------------
 2419|    409|    const char *p, *q;
 2420|       |
 2421|    409|    p = url + pos;
 2422|       |
 2423|       |    // p pointe sur le début de l'adrfil->adresse, ex: www.truc.fr/sommaire/index.html
 2424|    409|    q = strchr(jump_identification_const(p), '/');
 2425|    409|    if (q == 0)
  ------------------
  |  Branch (2425:9): [True: 282, False: 127]
  ------------------
 2426|    282|      q = strchr(jump_identification_const(p), '?');  // http://www.foo.com?bar=1
 2427|    409|    if (q == 0)
  ------------------
  |  Branch (2427:9): [True: 247, False: 162]
  ------------------
 2428|    247|      q = p + strlen(p);        // pointe sur \0
 2429|       |    // q pointe sur le chemin, ex: index.html?query=recherche
 2430|       |
 2431|       |    // chemin www... trop long!!
 2432|    409|    if ((((int) (q - p))) > HTS_URLMAXSIZE) {
  ------------------
  |  |  214|    409|#define HTS_URLMAXSIZE 1024
  ------------------
  |  Branch (2432:9): [True: 2, False: 407]
  ------------------
 2433|      2|      return -1;                // erreur
 2434|      2|    }
 2435|       |    // recopier adrfil->adresse www..
 2436|    407|    strncatbuff(adrfil->adr, p, ((int) (q - p)));
  ------------------
  |  |  219|    407|  __builtin_choose_expr(HTS_IS_CHAR_BUFFER(A),                                 \
  |  |  ------------------
  |  |  |  |  113|    407|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  220|    407|                        strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), N,  \
  |  |  ------------------
  |  |  |  |  125|    407|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    407|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    407|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 407, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  221|    407|                                      "overflow while appending '" #B          \
  |  |  222|    407|                                      "' to '" #A "'",                         \
  |  |  223|    407|                                      __FILE__, __LINE__),                     \
  |  |  224|    407|                        strncatbuff_ptr_((A), (B), (N)))
  ------------------
 2437|       |    // *( adrfil->adr+( ((int) q) - ((int) p) ) )=0;  // faut arrêter la fumette!
 2438|       |
 2439|       |    // fil[] holds the path plus a possible leading '/' the top strlen() misses.
 2440|    407|    if (strlen(q) >= sizeof(adrfil->fil) - (q[0] != '/' ? 1 : 0))
  ------------------
  |  Branch (2440:9): [True: 3, False: 404]
  |  Branch (2440:45): [True: 280, False: 127]
  ------------------
 2441|      3|      return -1;
 2442|       |
 2443|       |    // recopier chemin /pub/..
 2444|    404|    if (q[0] != '/')            // page par défaut (/)
  ------------------
  |  Branch (2444:9): [True: 277, False: 127]
  ------------------
 2445|    277|      strcatbuff(adrfil->fil, "/");
  ------------------
  |  |  242|    277|  __builtin_choose_expr(                                                       \
  |  |  243|    277|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|    277|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|    277|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|    277|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    277|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    277|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 277]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|    277|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|    277|      strcatbuff_ptr_((A), (B)))
  ------------------
 2446|    404|    strcatbuff(adrfil->fil, q);
  ------------------
  |  |  242|    404|  __builtin_choose_expr(                                                       \
  |  |  243|    404|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|    404|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|    404|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|    404|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    404|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    404|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 404, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|    404|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|    404|      strcatbuff_ptr_((A), (B)))
  ------------------
 2447|       |    // SECURITE:
 2448|       |    // simplifier url pour les ../
 2449|    404|    fil_simplifie(adrfil->fil);
 2450|    404|  } else {                      // localhost adrfil->file://
 2451|    114|    const char *p;
 2452|    114|    size_t i;
 2453|    114|    char *a;
 2454|       |
 2455|    114|    p = url + pos;
 2456|    114|    if (*p == '/' || *p == '\\') {      /* adrfil->file:///.. */
  ------------------
  |  Branch (2456:9): [True: 11, False: 103]
  |  Branch (2456:22): [True: 15, False: 88]
  ------------------
 2457|     26|      strcatbuff(adrfil->fil, p);       // fichier local ; adrfil->adr="#"
  ------------------
  |  |  242|     26|  __builtin_choose_expr(                                                       \
  |  |  243|     26|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|     26|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|     26|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|     26|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     26|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     26|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 26, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|     26|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|     26|      strcatbuff_ptr_((A), (B)))
  ------------------
 2458|     88|    } else {
 2459|     88|      if (*p == '\0' || p[1] != ':') {  /* empty path: not a DOS drive letter */
  ------------------
  |  Branch (2459:11): [True: 1, False: 87]
  |  Branch (2459:25): [True: 60, False: 27]
  ------------------
 2460|     61|        strcatbuff(adrfil->fil, "//");  /* adrfil->file://server/foo */
  ------------------
  |  |  242|     61|  __builtin_choose_expr(                                                       \
  |  |  243|     61|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|     61|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|     61|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|     61|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     61|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     61|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 61]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|     61|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|     61|      strcatbuff_ptr_((A), (B)))
  ------------------
 2461|     61|        strcatbuff(adrfil->fil, p);
  ------------------
  |  |  242|     61|  __builtin_choose_expr(                                                       \
  |  |  243|     61|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|     61|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|     61|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|     61|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     61|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     61|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 61, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|     61|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|     61|      strcatbuff_ptr_((A), (B)))
  ------------------
 2462|     61|      } else {
 2463|     27|        strcatbuff(adrfil->fil, p);     // adrfil->file://C:\..
  ------------------
  |  |  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)))
  ------------------
 2464|     27|      }
 2465|     88|    }
 2466|       |
 2467|    114|    a = strchr(adrfil->fil, '?');
 2468|    114|    if (a)
  ------------------
  |  Branch (2468:9): [True: 24, False: 90]
  ------------------
 2469|     24|      *a = '\0';                /* couper query (inutile pour adrfil->file:// lors de la requête) */
 2470|       |    // adrfil->filtrer les \\ -> / pour les fichiers DOS
 2471|  29.0k|    for(i = 0; adrfil->fil[i] != '\0'; i++)
  ------------------
  |  Branch (2471:16): [True: 28.9k, False: 114]
  ------------------
 2472|  28.9k|      if (adrfil->fil[i] == '\\')
  ------------------
  |  Branch (2472:11): [True: 518, False: 28.3k]
  ------------------
 2473|    518|        adrfil->fil[i] = '/';
 2474|       |    // collapse ../ like the http branch above (path-traversal safety)
 2475|    114|    fil_simplifie(adrfil->fil);
 2476|    114|  }
 2477|       |
 2478|       |  // no hostname
 2479|    518|  if (!strnotempty(adrfil->adr))
  ------------------
  |  |  274|    518|#define strnotempty(A) (((A) != NULL && (A)[0] != '\0'))
  |  |  ------------------
  |  |  |  Branch (274:26): [True: 518, False: 0]
  |  |  |  Branch (274:41): [True: 422, False: 96]
  |  |  ------------------
  ------------------
 2480|     96|    return -1;                  // erreur non reconnu
 2481|       |
 2482|       |  // nommer au besoin.. (non utilisé normalement)
 2483|    422|  if (!strnotempty(adrfil->fil))
  ------------------
  |  |  274|    422|#define strnotempty(A) (((A) != NULL && (A)[0] != '\0'))
  |  |  ------------------
  |  |  |  Branch (274:26): [True: 422, False: 0]
  |  |  |  Branch (274:41): [True: 422, False: 0]
  |  |  ------------------
  ------------------
 2484|      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)))
  ------------------
 2485|       |
 2486|       |  // case insensitive pour adrfil->adresse
 2487|    422|  {
 2488|    422|    char *a = jump_identification(adrfil->adr);
 2489|       |
 2490|  10.3k|    while(*a) {
  ------------------
  |  Branch (2490:11): [True: 9.88k, False: 422]
  ------------------
 2491|  9.88k|      if ((*a >= 'A') && (*a <= 'Z'))
  ------------------
  |  Branch (2491:11): [True: 3.72k, False: 6.16k]
  |  Branch (2491:26): [True: 1.60k, False: 2.11k]
  ------------------
 2492|  1.60k|        *a += 'a' - 'A';
 2493|  9.88k|      a++;
 2494|  9.88k|    }
 2495|    422|  }
 2496|       |
 2497|    422|  return 0;
 2498|    518|}
fil_simplifie:
 2501|  1.05k|void fil_simplifie(char *f) {
 2502|  1.05k|  char *a, *b;
 2503|  1.05k|  char *rollback[128];
 2504|  1.05k|  int rollid = 0;
 2505|  1.05k|  char lc = '/';
 2506|  1.05k|  int query = 0;
 2507|  1.05k|  int wasAbsolute = (*f == '/');
 2508|       |
 2509|   565k|  for(a = b = f; *a != '\0';) {
  ------------------
  |  Branch (2509:18): [True: 564k, False: 1.03k]
  ------------------
 2510|   564k|    if (*a == '?')
  ------------------
  |  Branch (2510:9): [True: 1.04k, False: 563k]
  ------------------
 2511|  1.04k|      query = 1;
 2512|   564k|    if (query == 0 && lc == '/' && a[0] == '.' && a[1] == '/') {        /* foo/./bar or ./foo  */
  ------------------
  |  Branch (2512:9): [True: 375k, False: 189k]
  |  Branch (2512:23): [True: 12.0k, False: 363k]
  |  Branch (2512:36): [True: 5.76k, False: 6.27k]
  |  Branch (2512:51): [True: 1.01k, False: 4.74k]
  ------------------
 2513|  1.01k|      a += 2;
 2514|   563k|    } else if (query == 0 && lc == '/' && a[0] == '.' && a[1] == '.' && (a[2] == '/' || a[2] == '\0')) {        /* foo/../bar or ../foo or .. */
  ------------------
  |  Branch (2514:16): [True: 374k, False: 189k]
  |  Branch (2514:30): [True: 11.0k, False: 363k]
  |  Branch (2514:43): [True: 4.74k, False: 6.27k]
  |  Branch (2514:58): [True: 3.59k, False: 1.15k]
  |  Branch (2514:74): [True: 2.44k, False: 1.14k]
  |  Branch (2514:89): [True: 61, False: 1.08k]
  ------------------
 2515|  2.51k|      if (a[2] == '\0')
  ------------------
  |  Branch (2515:11): [True: 61, False: 2.44k]
  ------------------
 2516|     61|        a += 2;
 2517|  2.44k|      else
 2518|  2.44k|        a += 3;
 2519|  2.51k|      if (rollid > 1) {
  ------------------
  |  Branch (2519:11): [True: 1.70k, False: 804]
  ------------------
 2520|  1.70k|        rollid--;
 2521|  1.70k|        b = rollback[rollid - 1];
 2522|  1.70k|      } else {                  /* too many ../ */
 2523|    804|        rollid = 0;
 2524|    804|        b = f;
 2525|    804|        if (wasAbsolute)
  ------------------
  |  Branch (2525:13): [True: 506, False: 298]
  ------------------
 2526|    506|          b++;                  /* after the / */
 2527|    804|      }
 2528|   561k|    } else {
 2529|   561k|      *b++ = lc = *a;
 2530|   561k|      if (*a == '/') {
  ------------------
  |  Branch (2530:11): [True: 9.61k, False: 551k]
  ------------------
 2531|  9.61k|        rollback[rollid++] = b;
 2532|  9.61k|        if (rollid >= 127) {
  ------------------
  |  Branch (2532:13): [True: 13, False: 9.59k]
  ------------------
 2533|     13|          *f = '\0';            /* ERROR */
 2534|     13|          break;
 2535|     13|        }
 2536|  9.61k|      }
 2537|   561k|      a++;
 2538|   561k|    }
 2539|   564k|  }
 2540|  1.05k|  *b = '\0';
 2541|  1.05k|  if (*f == '\0') {
  ------------------
  |  Branch (2541:7): [True: 36, False: 1.01k]
  ------------------
 2542|     36|    if (wasAbsolute) {
  ------------------
  |  Branch (2542:9): [True: 4, False: 32]
  ------------------
 2543|      4|      f[0] = '/';
 2544|      4|      f[1] = '\0';
 2545|     32|    } else {
 2546|     32|      f[0] = '.';
 2547|     32|      f[1] = '/';
 2548|     32|      f[2] = '\0';
 2549|     32|    }
 2550|     36|  }
 2551|  1.05k|}
jump_identification_const:
 3431|  1.11k|HTSEXT_API const char *jump_identification_const(const char *source) {
 3432|  1.11k|  const char *a, *trytofind;
 3433|       |
 3434|  1.11k|  if (strcmp(source, "file://") == 0)
  ------------------
  |  Branch (3434:7): [True: 115, False: 998]
  ------------------
 3435|    115|    return source;
 3436|       |  // rechercher dernier @ (car parfois email transmise dans adresse!)
 3437|       |  // mais sauter ftp:// éventuel
 3438|    998|  a = jump_protocol_const(source);
 3439|    998|  trytofind = strrchr_limit(a, '@', strchr(a, '/'));
 3440|    998|  return trytofind != NULL ? trytofind : a;
  ------------------
  |  Branch (3440:10): [True: 43, False: 955]
  ------------------
 3441|  1.11k|}
strrchr_limit:
 4080|    998|const char *strrchr_limit(const char *s, char c, const char *limit) {
 4081|    998|  if (limit == NULL) {
  ------------------
  |  Branch (4081:7): [True: 870, False: 128]
  ------------------
 4082|    870|    const char *p = strrchr(s, c);
 4083|       |
 4084|    870|    return p ? (p + 1) : NULL;
  ------------------
  |  Branch (4084:12): [True: 34, False: 836]
  ------------------
 4085|    870|  } else {
 4086|    128|    const char *a = NULL, *p;
 4087|       |
 4088|    325|    for(;;) {
 4089|    325|      p = strchr((a) ? a : s, c);
  ------------------
  |  Branch (4089:18): [True: 197, False: 128]
  ------------------
 4090|    325|      if ((p >= limit) || (p == NULL))
  ------------------
  |  Branch (4090:11): [True: 4, False: 321]
  |  Branch (4090:27): [True: 124, False: 197]
  ------------------
 4091|    128|        return a;
 4092|    197|      a = p + 1;
 4093|    197|    }
 4094|    128|  }
 4095|    998|}
jump_protocol_const:
 4098|    998|const char *jump_protocol_const(const char *source) {
 4099|    998|  int p;
 4100|       |
 4101|       |  // scheme
 4102|       |  // "Comparisons of scheme names MUST be case-insensitive" (RFC2616)
 4103|    998|  if ((p = strfield(source, "http:")))
  ------------------
  |  Branch (4103:7): [True: 7, False: 991]
  ------------------
 4104|      7|    source += p;
 4105|    991|  else if ((p = strfield(source, "ftp:")))
  ------------------
  |  Branch (4105:12): [True: 40, False: 951]
  ------------------
 4106|     40|    source += p;
 4107|    951|  else if ((p = strfield(source, "https:")))
  ------------------
  |  Branch (4107:12): [True: 9, False: 942]
  ------------------
 4108|      9|    source += p;
 4109|    942|  else if ((p = strfield(source, "file:")))
  ------------------
  |  Branch (4109:12): [True: 51, False: 891]
  ------------------
 4110|     51|    source += p;
 4111|    891|  else if ((p = strfield(source, "socks5h:")))
  ------------------
  |  Branch (4111:12): [True: 7, False: 884]
  ------------------
 4112|      7|    source += p;
 4113|    884|  else if ((p = strfield(source, "socks5:")))
  ------------------
  |  Branch (4113:12): [True: 7, False: 877]
  ------------------
 4114|      7|    source += p;
 4115|    877|  else if ((p = strfield(source, "connect:")))
  ------------------
  |  Branch (4115:12): [True: 5, False: 872]
  ------------------
 4116|      5|    source += p;
 4117|       |  // net_path
 4118|    998|  if (strncmp(source, "//", 2) == 0)
  ------------------
  |  Branch (4118:7): [True: 70, False: 928]
  ------------------
 4119|     70|    source += 2;
 4120|    998|  return source;
 4121|    998|}

htslib.c:strfield:
  536|  8.40k|HTS_STATIC int strfield(const char *f, const char *s) {
  537|  8.40k|  int r = 0;
  538|       |
  539|  12.1k|  while(streql(*f, *s) && ((*f) != 0) && ((*s) != 0)) {
  ------------------
  |  |  105|  24.3k|#define streql(a,b) (hichar(a)==hichar(b))
  |  |  ------------------
  |  |  |  |  103|  12.1k|#define hichar(a) ((((a)>='a') && ((a)<='z')) ? ((a)-('a'-'A')) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:21): [True: 4.62k, False: 7.54k]
  |  |  |  |  |  Branch (103:35): [True: 4.48k, False: 140]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define streql(a,b) (hichar(a)==hichar(b))
  |  |  ------------------
  |  |  |  |  103|  12.1k|#define hichar(a) ((((a)>='a') && ((a)<='z')) ? ((a)-('a'-'A')) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:21): [True: 11.2k, False: 963]
  |  |  |  |  |  Branch (103:35): [True: 11.2k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (105:21): [True: 3.81k, False: 8.35k]
  |  |  ------------------
  ------------------
  |  Branch (539:27): [True: 3.76k, False: 49]
  |  Branch (539:42): [True: 3.76k, False: 0]
  ------------------
  540|  3.76k|    f++;
  541|  3.76k|    s++;
  542|  3.76k|    r++;
  543|  3.76k|  }
  544|  8.40k|  if (*s == 0)
  ------------------
  |  Branch (544:7): [True: 390, False: 8.01k]
  ------------------
  545|    390|    return r;
  546|  8.01k|  else
  547|  8.01k|    return 0;
  548|  8.40k|}

htslib.c:strcpy_safe_:
  376|    149|             const char *exp, const char *file, int line) {
  377|    149|  assertf_(sizeof_dest != 0, file, line);
  ------------------
  |  |   86|    149|#define assertf_(exp, file, line) assertf__(exp, #exp, file, line)
  |  |  ------------------
  |  |  |  |   81|    149|  (void) ((exp) || (abortf_(sexp, file, line), 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (81:11): [True: 149, False: 0]
  |  |  |  |  |  Branch (81:20): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  378|    149|  dest[0] = '\0';
  379|    149|  return strncat_safe_(dest, sizeof_dest, source, sizeof_source, (size_t) -1,
  380|    149|                       exp, file, line);
  381|    149|}
htslib.c:strncat_safe_:
  358|  1.41k|              const size_t n, const char *exp, const char *file, int line) {
  359|  1.41k|  const size_t source_len = strlen_safe_(source, sizeof_source, file, line);
  360|  1.41k|  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.41k|  const size_t source_copy = source_len <= n ? source_len : n;
  ------------------
  |  Branch (362:30): [True: 1.25k, False: 162]
  ------------------
  363|  1.41k|  const size_t dest_final_len = dest_len + source_copy;
  364|  1.41k|  assertf__(dest_final_len < sizeof_dest, exp, file, line);
  ------------------
  |  |   81|  1.41k|  (void) ((exp) || (abortf_(sexp, file, line), 0))
  |  |  ------------------
  |  |  |  Branch (81:11): [True: 1.41k, False: 0]
  |  |  |  Branch (81:20): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  365|  1.41k|  memcpy(dest + dest_len, source, source_copy);
  366|  1.41k|  dest[dest_final_len] = '\0';
  367|  1.41k|  return dest;
  368|  1.41k|}
htslib.c:strlen_safe_:
  341|  2.82k|                                                 const char *file, int line) {
  342|  2.82k|  size_t size;
  343|  2.82k|  assertf_(source != NULL, file, line);
  ------------------
  |  |   86|  2.82k|#define assertf_(exp, file, line) assertf__(exp, #exp, file, line)
  |  |  ------------------
  |  |  |  |   81|  2.82k|  (void) ((exp) || (abortf_(sexp, file, line), 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (81:11): [True: 2.82k, False: 0]
  |  |  |  |  |  Branch (81:20): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  344|  2.82k|  size = sizeof_source != (size_t) -1 ? htssafe_strnlen_(source, sizeof_source)
  ------------------
  |  Branch (344:10): [True: 1.89k, False: 925]
  ------------------
  345|  2.82k|                                      : strlen(source);
  346|  2.82k|  assertf_(size < sizeof_source, file, line);
  ------------------
  |  |   86|  2.82k|#define assertf_(exp, file, line) assertf__(exp, #exp, file, line)
  |  |  ------------------
  |  |  |  |   81|  2.82k|  (void) ((exp) || (abortf_(sexp, file, line), 0))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (81:11): [True: 2.82k, False: 0]
  |  |  |  |  |  Branch (81:20): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  347|  2.82k|  return size;
  348|  2.82k|}
htslib.c:htssafe_strnlen_:
  316|  1.89k|                                                     size_t maxlen) {
  317|  1.89k|#if (defined(_WIN32) || (defined(HAVE_STRNLEN) && !defined(__STRICT_ANSI__)))
  318|  1.89k|  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|  1.89k|}

