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

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

ident_url_absolute:
 2368|    544|int ident_url_absolute(const char *url, lien_adrfil *adrfil) {
 2369|    544|  int pos = 0;
 2370|    544|  int scheme = 0;
 2371|       |
 2372|       |  // effacer adrfil->adr et adrfil->fil
 2373|    544|  adrfil->adr[0] = adrfil->fil[0] = '\0';
 2374|       |
 2375|       |  // Reject an over-long URL: a root-relative path is copied whole into fil[].
 2376|    544|  if (strlen(url) >= HTS_URLMAXSIZE * 2)
  ------------------
  |  |  214|    544|#define HTS_URLMAXSIZE 1024
  ------------------
  |  Branch (2376:7): [True: 9, False: 535]
  ------------------
 2377|      9|    return -1;
 2378|       |
 2379|       |#if HDEBUG
 2380|       |  printf("protocol: %s\n", url);
 2381|       |#endif
 2382|       |
 2383|       |  // Scheme?
 2384|    535|  {
 2385|    535|    const char *a = url;
 2386|       |
 2387|    535|    while(isalpha((unsigned char) *a))
  ------------------
  |  Branch (2387:11): [True: 1.15k, False: 535]
  ------------------
 2388|  1.15k|      a++;
 2389|    535|    if (*a == ':')
  ------------------
  |  Branch (2389:9): [True: 151, False: 384]
  ------------------
 2390|    151|      scheme = 1;
 2391|    535|  }
 2392|       |
 2393|       |  // 1. optional scheme ":"
 2394|    535|  if ((pos = strfield(url, "file:"))) { // fichier local!! (pour les tests)
  ------------------
  |  Branch (2394:7): [True: 111, False: 424]
  ------------------
 2395|       |    //!!p+=3;
 2396|    111|    strcpybuff(adrfil->adr, "file://");
  ------------------
  |  |  265|    111|  __builtin_choose_expr(HTS_IS_CHAR_BUFFER(A),                                 \
  |  |  ------------------
  |  |  |  |  113|    111|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  266|    111|                        strcpy_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B),      \
  |  |  ------------------
  |  |  |  |  125|    111|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    111|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    111|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 111]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  267|    111|                                     "overflow while copying '" #B "' to '" #A \
  |  |  268|    111|                                     "'",                                      \
  |  |  269|    111|                                     __FILE__, __LINE__),                      \
  |  |  270|    111|                        strcpybuff_ptr_((A), (B)))
  ------------------
 2397|    424|  } else if ((pos = strfield(url, "http:"))) {  // HTTP
  ------------------
  |  Branch (2397:14): [True: 1, False: 423]
  ------------------
 2398|       |    //!!p+=3;
 2399|    423|  } else if ((pos = strfield(url, "ftp:"))) {   // FTP
  ------------------
  |  Branch (2399:14): [True: 37, False: 386]
  ------------------
 2400|     37|    strcpybuff(adrfil->adr, "ftp://");  // FTP!!
  ------------------
  |  |  265|     37|  __builtin_choose_expr(HTS_IS_CHAR_BUFFER(A),                                 \
  |  |  ------------------
  |  |  |  |  113|     37|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  266|     37|                        strcpy_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B),      \
  |  |  ------------------
  |  |  |  |  125|     37|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     37|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     37|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 37]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  267|     37|                                     "overflow while copying '" #B "' to '" #A \
  |  |  268|     37|                                     "'",                                      \
  |  |  269|     37|                                     __FILE__, __LINE__),                      \
  |  |  270|     37|                        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|    386|  } else if (scheme) {
  ------------------
  |  Branch (2406:14): [True: 2, False: 384]
  ------------------
 2407|      2|    return -1;                  // erreur non reconnu
 2408|      2|  } else
 2409|    384|    pos = 0;
 2410|       |
 2411|       |  // 2. optional "//" authority
 2412|    533|  if (strncmp(url + pos, "//", 2) == 0)
  ------------------
  |  Branch (2412:7): [True: 49, False: 484]
  ------------------
 2413|     49|    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|    533|  if (!strfield(adrfil->adr, "file:")) {        // PAS adrfil->file://
  ------------------
  |  Branch (2418:7): [True: 422, False: 111]
  ------------------
 2419|    422|    const char *p, *q;
 2420|       |
 2421|    422|    p = url + pos;
 2422|       |
 2423|       |    // p pointe sur le début de l'adrfil->adresse, ex: www.truc.fr/sommaire/index.html
 2424|    422|    q = strchr(jump_identification_const(p), '/');
 2425|    422|    if (q == 0)
  ------------------
  |  Branch (2425:9): [True: 290, False: 132]
  ------------------
 2426|    290|      q = strchr(jump_identification_const(p), '?');  // http://www.foo.com?bar=1
 2427|    422|    if (q == 0)
  ------------------
  |  Branch (2427:9): [True: 256, False: 166]
  ------------------
 2428|    256|      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|    422|    if ((((int) (q - p))) > HTS_URLMAXSIZE) {
  ------------------
  |  |  214|    422|#define HTS_URLMAXSIZE 1024
  ------------------
  |  Branch (2432:9): [True: 2, False: 420]
  ------------------
 2433|      2|      return -1;                // erreur
 2434|      2|    }
 2435|       |    // recopier adrfil->adresse www..
 2436|    420|    strncatbuff(adrfil->adr, p, ((int) (q - p)));
  ------------------
  |  |  219|    420|  __builtin_choose_expr(HTS_IS_CHAR_BUFFER(A),                                 \
  |  |  ------------------
  |  |  |  |  113|    420|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  220|    420|                        strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), N,  \
  |  |  ------------------
  |  |  |  |  125|    420|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    420|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    420|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 420, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  221|    420|                                      "overflow while appending '" #B          \
  |  |  222|    420|                                      "' to '" #A "'",                         \
  |  |  223|    420|                                      __FILE__, __LINE__),                     \
  |  |  224|    420|                        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|    420|    if (strlen(q) >= sizeof(adrfil->fil) - (q[0] != '/' ? 1 : 0))
  ------------------
  |  Branch (2440:9): [True: 3, False: 417]
  |  Branch (2440:45): [True: 288, False: 132]
  ------------------
 2441|      3|      return -1;
 2442|       |
 2443|       |    // recopier chemin /pub/..
 2444|    417|    if (q[0] != '/')            // page par défaut (/)
  ------------------
  |  Branch (2444:9): [True: 285, False: 132]
  ------------------
 2445|    285|      strcatbuff(adrfil->fil, "/");
  ------------------
  |  |  242|    285|  __builtin_choose_expr(                                                       \
  |  |  243|    285|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|    285|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|    285|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|    285|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    285|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    285|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 285]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|    285|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|    285|      strcatbuff_ptr_((A), (B)))
  ------------------
 2446|    417|    strcatbuff(adrfil->fil, q);
  ------------------
  |  |  242|    417|  __builtin_choose_expr(                                                       \
  |  |  243|    417|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|    417|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|    417|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|    417|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|    417|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|    417|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 417, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|    417|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|    417|      strcatbuff_ptr_((A), (B)))
  ------------------
 2447|       |    // SECURITE:
 2448|       |    // simplifier url pour les ../
 2449|    417|    fil_simplifie(adrfil->fil);
 2450|    417|  } else {                      // localhost adrfil->file://
 2451|    111|    const char *p;
 2452|    111|    size_t i;
 2453|    111|    char *a;
 2454|       |
 2455|    111|    p = url + pos;
 2456|    111|    if (*p == '/' || *p == '\\') {      /* adrfil->file:///.. */
  ------------------
  |  Branch (2456:9): [True: 13, False: 98]
  |  Branch (2456:22): [True: 13, False: 85]
  ------------------
 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|     85|    } else {
 2459|     85|      if (*p == '\0' || p[1] != ':') {  /* empty path: not a DOS drive letter */
  ------------------
  |  Branch (2459:11): [True: 1, False: 84]
  |  Branch (2459:25): [True: 58, False: 26]
  ------------------
 2460|     59|        strcatbuff(adrfil->fil, "//");  /* adrfil->file://server/foo */
  ------------------
  |  |  242|     59|  __builtin_choose_expr(                                                       \
  |  |  243|     59|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|     59|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|     59|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|     59|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     59|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     59|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [Folded, False: 59]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|     59|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|     59|      strcatbuff_ptr_((A), (B)))
  ------------------
 2461|     59|        strcatbuff(adrfil->fil, p);
  ------------------
  |  |  242|     59|  __builtin_choose_expr(                                                       \
  |  |  243|     59|      HTS_IS_CHAR_BUFFER(A),                                                   \
  |  |  ------------------
  |  |  |  |  113|     59|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  ------------------
  |  |  244|     59|      strncat_safe_(A, sizeof(A), B, HTS_SIZEOF_SRC_(B), (size_t) -1,          \
  |  |  ------------------
  |  |  |  |  125|     59|  (HTS_IS_NOT_CHAR_BUFFER(B) ? (size_t) -1 : sizeof(__typeof__(B)))
  |  |  |  |  ------------------
  |  |  |  |  |  |  119|     59|#define HTS_IS_NOT_CHAR_BUFFER(VAR) (!HTS_IS_CHAR_BUFFER(VAR))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  113|     59|  (__builtin_types_compatible_p(__typeof__(VAR), char[]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (119:37): [True: 59, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  245|     59|                    "overflow while appending '" #B "' to '" #A "'", __FILE__, \
  |  |  246|       |                    __LINE__),                                                 \
  |  |  247|     59|      strcatbuff_ptr_((A), (B)))
  ------------------
 2462|     59|      } else {
 2463|     26|        strcatbuff(adrfil->fil, p);     // adrfil->file://C:\..
  ------------------
  |  |  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)))
  ------------------
 2464|     26|      }
 2465|     85|    }
 2466|       |
 2467|    111|    a = strchr(adrfil->fil, '?');
 2468|    111|    if (a)
  ------------------
  |  Branch (2468:9): [True: 17, False: 94]
  ------------------
 2469|     17|      *a = '\0';                /* couper query (inutile pour adrfil->file:// lors de la requête) */
 2470|       |    // adrfil->filtrer les \\ -> / pour les fichiers DOS
 2471|  34.6k|    for(i = 0; adrfil->fil[i] != '\0'; i++)
  ------------------
  |  Branch (2471:16): [True: 34.5k, False: 111]
  ------------------
 2472|  34.5k|      if (adrfil->fil[i] == '\\')
  ------------------
  |  Branch (2472:11): [True: 498, False: 34.0k]
  ------------------
 2473|    498|        adrfil->fil[i] = '/';
 2474|       |    // collapse ../ like the http branch above (path-traversal safety)
 2475|    111|    fil_simplifie(adrfil->fil);
 2476|    111|  }
 2477|       |
 2478|       |  // no hostname
 2479|    528|  if (!strnotempty(adrfil->adr))
  ------------------
  |  |  274|    528|#define strnotempty(A) (((A) != NULL && (A)[0] != '\0'))
  |  |  ------------------
  |  |  |  Branch (274:26): [True: 528, False: 0]
  |  |  |  Branch (274:41): [True: 434, False: 94]
  |  |  ------------------
  ------------------
 2480|     94|    return -1;                  // erreur non reconnu
 2481|       |
 2482|       |  // nommer au besoin.. (non utilisé normalement)
 2483|    434|  if (!strnotempty(adrfil->fil))
  ------------------
  |  |  274|    434|#define strnotempty(A) (((A) != NULL && (A)[0] != '\0'))
  |  |  ------------------
  |  |  |  Branch (274:26): [True: 434, False: 0]
  |  |  |  Branch (274:41): [True: 434, 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|    434|  {
 2488|    434|    char *a = jump_identification(adrfil->adr);
 2489|       |
 2490|  10.2k|    while(*a) {
  ------------------
  |  Branch (2490:11): [True: 9.77k, False: 434]
  ------------------
 2491|  9.77k|      if ((*a >= 'A') && (*a <= 'Z'))
  ------------------
  |  Branch (2491:11): [True: 3.19k, False: 6.58k]
  |  Branch (2491:26): [True: 1.43k, False: 1.75k]
  ------------------
 2492|  1.43k|        *a += 'a' - 'A';
 2493|  9.77k|      a++;
 2494|  9.77k|    }
 2495|    434|  }
 2496|       |
 2497|    434|  return 0;
 2498|    528|}
fil_simplifie:
 2501|  1.07k|void fil_simplifie(char *f) {
 2502|  1.07k|  char *a, *b;
 2503|  1.07k|  char *rollback[128];
 2504|  1.07k|  int rollid = 0;
 2505|  1.07k|  char lc = '/';
 2506|  1.07k|  int query = 0;
 2507|  1.07k|  int wasAbsolute = (*f == '/');
 2508|       |
 2509|   569k|  for(a = b = f; *a != '\0';) {
  ------------------
  |  Branch (2509:18): [True: 568k, False: 1.04k]
  ------------------
 2510|   568k|    if (*a == '?')
  ------------------
  |  Branch (2510:9): [True: 1.01k, False: 567k]
  ------------------
 2511|  1.01k|      query = 1;
 2512|   568k|    if (query == 0 && lc == '/' && a[0] == '.' && a[1] == '/') {        /* foo/./bar or ./foo  */
  ------------------
  |  Branch (2512:9): [True: 418k, False: 149k]
  |  Branch (2512:23): [True: 12.8k, False: 405k]
  |  Branch (2512:36): [True: 5.61k, False: 7.26k]
  |  Branch (2512:51): [True: 479, False: 5.13k]
  ------------------
 2513|    479|      a += 2;
 2514|   568k|    } else if (query == 0 && lc == '/' && a[0] == '.' && a[1] == '.' && (a[2] == '/' || a[2] == '\0')) {        /* foo/../bar or ../foo or .. */
  ------------------
  |  Branch (2514:16): [True: 418k, False: 149k]
  |  Branch (2514:30): [True: 12.3k, False: 405k]
  |  Branch (2514:43): [True: 5.13k, False: 7.26k]
  |  Branch (2514:58): [True: 3.49k, False: 1.64k]
  |  Branch (2514:74): [True: 2.78k, False: 711]
  |  Branch (2514:89): [True: 66, False: 645]
  ------------------
 2515|  2.84k|      if (a[2] == '\0')
  ------------------
  |  Branch (2515:11): [True: 66, False: 2.78k]
  ------------------
 2516|     66|        a += 2;
 2517|  2.78k|      else
 2518|  2.78k|        a += 3;
 2519|  2.84k|      if (rollid > 1) {
  ------------------
  |  Branch (2519:11): [True: 2.08k, False: 761]
  ------------------
 2520|  2.08k|        rollid--;
 2521|  2.08k|        b = rollback[rollid - 1];
 2522|  2.08k|      } else {                  /* too many ../ */
 2523|    761|        rollid = 0;
 2524|    761|        b = f;
 2525|    761|        if (wasAbsolute)
  ------------------
  |  Branch (2525:13): [True: 459, False: 302]
  ------------------
 2526|    459|          b++;                  /* after the / */
 2527|    761|      }
 2528|   565k|    } else {
 2529|   565k|      *b++ = lc = *a;
 2530|   565k|      if (*a == '/') {
  ------------------
  |  Branch (2530:11): [True: 10.3k, False: 554k]
  ------------------
 2531|  10.3k|        rollback[rollid++] = b;
 2532|  10.3k|        if (rollid >= 127) {
  ------------------
  |  Branch (2532:13): [True: 25, False: 10.3k]
  ------------------
 2533|     25|          *f = '\0';            /* ERROR */
 2534|     25|          break;
 2535|     25|        }
 2536|  10.3k|      }
 2537|   565k|      a++;
 2538|   565k|    }
 2539|   568k|  }
 2540|  1.07k|  *b = '\0';
 2541|  1.07k|  if (*f == '\0') {
  ------------------
  |  Branch (2541:7): [True: 48, False: 1.02k]
  ------------------
 2542|     48|    if (wasAbsolute) {
  ------------------
  |  Branch (2542:9): [True: 9, False: 39]
  ------------------
 2543|      9|      f[0] = '/';
 2544|      9|      f[1] = '\0';
 2545|     39|    } else {
 2546|     39|      f[0] = '.';
 2547|     39|      f[1] = '/';
 2548|     39|      f[2] = '\0';
 2549|     39|    }
 2550|     48|  }
 2551|  1.07k|}
jump_identification_const:
 3431|  1.14k|HTSEXT_API const char *jump_identification_const(const char *source) {
 3432|  1.14k|  const char *a, *trytofind;
 3433|       |
 3434|  1.14k|  if (strcmp(source, "file://") == 0)
  ------------------
  |  Branch (3434:7): [True: 112, False: 1.03k]
  ------------------
 3435|    112|    return source;
 3436|       |  // rechercher dernier @ (car parfois email transmise dans adresse!)
 3437|       |  // mais sauter ftp:// éventuel
 3438|  1.03k|  a = jump_protocol_const(source);
 3439|  1.03k|  trytofind = strrchr_limit(a, '@', strchr(a, '/'));
 3440|  1.03k|  return trytofind != NULL ? trytofind : a;
  ------------------
  |  Branch (3440:10): [True: 47, False: 987]
  ------------------
 3441|  1.14k|}
strrchr_limit:
 3725|  1.03k|const char *strrchr_limit(const char *s, char c, const char *limit) {
 3726|  1.03k|  if (limit == NULL) {
  ------------------
  |  Branch (3726:7): [True: 901, False: 133]
  ------------------
 3727|    901|    const char *p = strrchr(s, c);
 3728|       |
 3729|    901|    return p ? (p + 1) : NULL;
  ------------------
  |  Branch (3729:12): [True: 34, False: 867]
  ------------------
 3730|    901|  } else {
 3731|    133|    const char *a = NULL, *p;
 3732|       |
 3733|    569|    for(;;) {
 3734|    569|      p = strchr((a) ? a : s, c);
  ------------------
  |  Branch (3734:18): [True: 436, False: 133]
  ------------------
 3735|    569|      if ((p >= limit) || (p == NULL))
  ------------------
  |  Branch (3735:11): [True: 9, False: 560]
  |  Branch (3735:27): [True: 124, False: 436]
  ------------------
 3736|    133|        return a;
 3737|    436|      a = p + 1;
 3738|    436|    }
 3739|    133|  }
 3740|  1.03k|}
jump_protocol_const:
 3743|  1.03k|const char *jump_protocol_const(const char *source) {
 3744|  1.03k|  int p;
 3745|       |
 3746|       |  // scheme
 3747|       |  // "Comparisons of scheme names MUST be case-insensitive" (RFC2616)
 3748|  1.03k|  if ((p = strfield(source, "http:")))
  ------------------
  |  Branch (3748:7): [True: 7, False: 1.02k]
  ------------------
 3749|      7|    source += p;
 3750|  1.02k|  else if ((p = strfield(source, "ftp:")))
  ------------------
  |  Branch (3750:12): [True: 44, False: 983]
  ------------------
 3751|     44|    source += p;
 3752|    983|  else if ((p = strfield(source, "https:")))
  ------------------
  |  Branch (3752:12): [True: 9, False: 974]
  ------------------
 3753|      9|    source += p;
 3754|    974|  else if ((p = strfield(source, "file:")))
  ------------------
  |  Branch (3754:12): [True: 51, False: 923]
  ------------------
 3755|     51|    source += p;
 3756|    923|  else if ((p = strfield(source, "socks5h:")))
  ------------------
  |  Branch (3756:12): [True: 7, False: 916]
  ------------------
 3757|      7|    source += p;
 3758|    916|  else if ((p = strfield(source, "socks5:")))
  ------------------
  |  Branch (3758:12): [True: 7, False: 909]
  ------------------
 3759|      7|    source += p;
 3760|    909|  else if ((p = strfield(source, "connect:")))
  ------------------
  |  Branch (3760:12): [True: 7, False: 902]
  ------------------
 3761|      7|    source += p;
 3762|       |  // net_path
 3763|  1.03k|  if (strncmp(source, "//", 2) == 0)
  ------------------
  |  Branch (3763:7): [True: 72, False: 962]
  ------------------
 3764|     72|    source += 2;
 3765|  1.03k|  return source;
 3766|  1.03k|}

htslib.c:strfield:
  536|  8.68k|HTS_STATIC int strfield(const char *f, const char *s) {
  537|  8.68k|  int r = 0;
  538|       |
  539|  12.5k|  while(streql(*f, *s) && ((*f) != 0) && ((*s) != 0)) {
  ------------------
  |  |  105|  25.1k|#define streql(a,b) (hichar(a)==hichar(b))
  |  |  ------------------
  |  |  |  |  103|  12.5k|#define hichar(a) ((((a)>='a') && ((a)<='z')) ? ((a)-('a'-'A')) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:21): [True: 4.74k, False: 7.81k]
  |  |  |  |  |  Branch (103:35): [True: 4.60k, False: 138]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define streql(a,b) (hichar(a)==hichar(b))
  |  |  ------------------
  |  |  |  |  103|  12.5k|#define hichar(a) ((((a)>='a') && ((a)<='z')) ? ((a)-('a'-'A')) : (a))
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (103:21): [True: 11.5k, False: 977]
  |  |  |  |  |  Branch (103:35): [True: 11.5k, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  |  Branch (105:21): [True: 3.92k, False: 8.63k]
  |  |  ------------------
  ------------------
  |  Branch (539:27): [True: 3.87k, False: 50]
  |  Branch (539:42): [True: 3.87k, False: 0]
  ------------------
  540|  3.87k|    f++;
  541|  3.87k|    s++;
  542|  3.87k|    r++;
  543|  3.87k|  }
  544|  8.68k|  if (*s == 0)
  ------------------
  |  Branch (544:7): [True: 392, False: 8.28k]
  ------------------
  545|    392|    return r;
  546|  8.28k|  else
  547|  8.28k|    return 0;
  548|  8.68k|}

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

