eventlog_free:
   43|    367|{
   44|    367|    int i;
   45|    367|    debug_decl(eventlog_free, SUDO_DEBUG_UTIL);
  ------------------
  |  |  119|    367|    debug_decl_vars((funcname), (subsys));				       \
  |  |  ------------------
  |  |  |  |  110|    367|    const int sudo_debug_subsys = (subsys)
  |  |  ------------------
  |  |  120|    367|    sudo_debug_enter(__func__, __FILE__, __LINE__, sudo_debug_subsys)
  |  |  ------------------
  |  |  |  |  280|    367|#define sudo_debug_enter(_a, _b, _c, _d) sudo_debug_enter_v1((_a), (_b), (_c), (_d))
  |  |  ------------------
  ------------------
   46|       |
   47|    367|    if (evlog != NULL) {
  ------------------
  |  Branch (47:9): [True: 367, False: 0]
  ------------------
   48|    367|	free(evlog->iolog_path);
   49|    367|	free(evlog->command);
   50|    367|	free(evlog->cwd);
   51|    367|	free(evlog->runchroot);
   52|    367|	free(evlog->runcwd);
   53|    367|	free(evlog->rungroup);
   54|    367|	free(evlog->runuser);
   55|    367|	free(evlog->peeraddr);
   56|    367|	free(evlog->signal_name);
   57|    367|	free(evlog->submithost);
   58|    367|	free(evlog->submituser);
   59|    367|	free(evlog->submitgroup);
   60|    367|	free(evlog->ttyname);
   61|    367|	if (evlog->argv != NULL) {
  ------------------
  |  Branch (61:6): [True: 0, False: 367]
  ------------------
   62|      0|	    for (i = 0; evlog->argv[i] != NULL; i++)
  ------------------
  |  Branch (62:18): [True: 0, False: 0]
  ------------------
   63|      0|		free(evlog->argv[i]);
   64|      0|	    free(evlog->argv);
   65|      0|	}
   66|    367|	if (evlog->envp != NULL) {
  ------------------
  |  Branch (66:6): [True: 0, False: 367]
  ------------------
   67|      0|	    for (i = 0; evlog->envp[i] != NULL; i++)
  ------------------
  |  Branch (67:18): [True: 0, False: 0]
  ------------------
   68|      0|		free(evlog->envp[i]);
   69|      0|	    free(evlog->envp);
   70|      0|	}
   71|    367|	if (evlog->env_add != NULL) {
  ------------------
  |  Branch (71:6): [True: 0, False: 367]
  ------------------
   72|      0|	    for (i = 0; evlog->env_add[i] != NULL; i++)
  ------------------
  |  Branch (72:18): [True: 0, False: 0]
  ------------------
   73|      0|		free(evlog->env_add[i]);
   74|      0|	    free(evlog->env_add);
   75|      0|	}
   76|    367|	free(evlog);
   77|    367|    }
   78|       |
   79|    367|    debug_return;
  ------------------
  |  |  126|    367|    do {								       \
  |  |  127|    367|	sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);      \
  |  |  ------------------
  |  |  |  |  282|    367|#define sudo_debug_exit(_a, _b, _c, _d) sudo_debug_exit_v1((_a), (_b), (_c), (_d))
  |  |  ------------------
  |  |  128|    367|	return;								       \
  |  |  129|    367|    } while (0)
  |  |  ------------------
  |  |  |  Branch (129:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   80|    367|}

iolog_parse_loginfo_legacy:
   49|    367|{
   50|    367|    char *buf = NULL, *cp, *ep;
   51|    367|    const char *errstr;
   52|    367|    size_t bufsize = 0, cwdsize = 0, cmdsize = 0;
   53|    367|    bool ret = false;
   54|    367|    debug_decl(iolog_parse_loginfo_legacy, SUDO_DEBUG_UTIL);
  ------------------
  |  |  119|    367|    debug_decl_vars((funcname), (subsys));				       \
  |  |  ------------------
  |  |  |  |  110|    367|    const int sudo_debug_subsys = (subsys)
  |  |  ------------------
  |  |  120|    367|    sudo_debug_enter(__func__, __FILE__, __LINE__, sudo_debug_subsys)
  |  |  ------------------
  |  |  |  |  280|    367|#define sudo_debug_enter(_a, _b, _c, _d) sudo_debug_enter_v1((_a), (_b), (_c), (_d))
  |  |  ------------------
  ------------------
   55|       |
   56|       |    /*
   57|       |     * Info file has three lines:
   58|       |     *  1) a log info line
   59|       |     *  2) cwd
   60|       |     *  3) command with args
   61|       |     */
   62|    367|    if (getdelim(&buf, &bufsize, '\n', fp) == -1 ||
  ------------------
  |  Branch (62:9): [True: 0, False: 367]
  ------------------
   63|    367|	getdelim(&evlog->cwd, &cwdsize, '\n', fp) == -1 ||
  ------------------
  |  Branch (63:2): [True: 21, False: 346]
  ------------------
   64|    367|	getdelim(&evlog->command, &cmdsize, '\n', fp) == -1) {
  ------------------
  |  Branch (64:2): [True: 20, False: 326]
  ------------------
   65|     41|	sudo_warn(U_("%s: invalid log file"), iolog_dir);
  ------------------
  |  |   44|     41|# define sudo_warn sudo_warn_nodebug_v1
  ------------------
              	sudo_warn(U_("%s: invalid log file"), iolog_dir);
  ------------------
  |  |   59|     41|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|     41|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
   66|     41|	goto done;
   67|     41|    }
   68|       |
   69|       |    /* Strip the newline from the cwd and command. */
   70|    326|    evlog->cwd[strcspn(evlog->cwd, "\n")] = '\0';
   71|    326|    evlog->command[strcspn(evlog->command, "\n")] = '\0';
   72|       |
   73|       |    /*
   74|       |     * Crack the log line (lines and cols not present in old versions).
   75|       |     *	timestamp:user:runas_user:runas_group:tty:lines:cols
   76|       |     * XXX - probably better to use strtok and switch on the state.
   77|       |     */
   78|    326|    buf[strcspn(buf, "\n")] = '\0';
   79|    326|    cp = buf;
   80|       |
   81|       |    /* timestamp */
   82|    326|    if ((ep = strchr(cp, ':')) == NULL) {
  ------------------
  |  Branch (82:9): [True: 19, False: 307]
  ------------------
   83|     19|	sudo_warn(U_("%s: time stamp field is missing"), iolog_dir);
  ------------------
  |  |   44|     19|# define sudo_warn sudo_warn_nodebug_v1
  ------------------
              	sudo_warn(U_("%s: time stamp field is missing"), iolog_dir);
  ------------------
  |  |   59|     19|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|     19|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
   84|     19|	goto done;
   85|     19|    }
   86|    307|    *ep = '\0';
   87|    307|    evlog->submit_time.tv_sec = sudo_strtonum(cp, 0, TIME_T_MAX, &errstr);
  ------------------
  |  |   45|    307|#  define TIME_T_MAX	LLONG_MAX
  ------------------
   88|    307|    if (errstr != NULL) {
  ------------------
  |  Branch (88:9): [True: 94, False: 213]
  ------------------
   89|     94|	sudo_warn(U_("%s: time stamp %s: %s"), iolog_dir, cp, errstr);
  ------------------
  |  |   44|     94|# define sudo_warn sudo_warn_nodebug_v1
  ------------------
              	sudo_warn(U_("%s: time stamp %s: %s"), iolog_dir, cp, errstr);
  ------------------
  |  |   59|     94|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|     94|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
   90|     94|	goto done;
   91|     94|    }
   92|       |
   93|       |    /* submit user */
   94|    213|    cp = ep + 1;
   95|    213|    if ((ep = strchr(cp, ':')) == NULL) {
  ------------------
  |  Branch (95:9): [True: 130, False: 83]
  ------------------
   96|    130|	sudo_warn(U_("%s: user field is missing"), iolog_dir);
  ------------------
  |  |   44|    130|# define sudo_warn sudo_warn_nodebug_v1
  ------------------
              	sudo_warn(U_("%s: user field is missing"), iolog_dir);
  ------------------
  |  |   59|    130|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|    130|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
   97|    130|	goto done;
   98|    130|    }
   99|     83|    if ((evlog->submituser = strndup(cp, (size_t)(ep - cp))) == NULL) {
  ------------------
  |  Branch (99:9): [True: 0, False: 83]
  ------------------
  100|      0|	sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   45|      0|# define sudo_warnx sudo_warnx_nodebug_v1
  ------------------
              	sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   59|      0|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      0|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
              	sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   59|      0|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      0|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
  101|      0|	goto done;
  102|      0|    }
  103|       |
  104|       |    /* runas user */
  105|     83|    cp = ep + 1;
  106|     83|    if ((ep = strchr(cp, ':')) == NULL) {
  ------------------
  |  Branch (106:9): [True: 1, False: 82]
  ------------------
  107|      1|	sudo_warn(U_("%s: runas user field is missing"), iolog_dir);
  ------------------
  |  |   44|      1|# define sudo_warn sudo_warn_nodebug_v1
  ------------------
              	sudo_warn(U_("%s: runas user field is missing"), iolog_dir);
  ------------------
  |  |   59|      1|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      1|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
  108|      1|	goto done;
  109|      1|    }
  110|     82|    if ((evlog->runuser = strndup(cp, (size_t)(ep - cp))) == NULL) {
  ------------------
  |  Branch (110:9): [True: 0, False: 82]
  ------------------
  111|      0|	sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   45|      0|# define sudo_warnx sudo_warnx_nodebug_v1
  ------------------
              	sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   59|      0|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      0|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
              	sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   59|      0|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      0|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
  112|      0|	goto done;
  113|      0|    }
  114|       |
  115|       |    /* runas group */
  116|     82|    cp = ep + 1;
  117|     82|    if ((ep = strchr(cp, ':')) == NULL) {
  ------------------
  |  Branch (117:9): [True: 1, False: 81]
  ------------------
  118|      1|	sudo_warn(U_("%s: runas group field is missing"), iolog_dir);
  ------------------
  |  |   44|      1|# define sudo_warn sudo_warn_nodebug_v1
  ------------------
              	sudo_warn(U_("%s: runas group field is missing"), iolog_dir);
  ------------------
  |  |   59|      1|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      1|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
  119|      1|	goto done;
  120|      1|    }
  121|     81|    if (cp != ep) {
  ------------------
  |  Branch (121:9): [True: 1, False: 80]
  ------------------
  122|      1|	if ((evlog->rungroup = strndup(cp, (size_t)(ep - cp))) == NULL) {
  ------------------
  |  Branch (122:6): [True: 0, False: 1]
  ------------------
  123|      0|	    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   45|      0|# define sudo_warnx sudo_warnx_nodebug_v1
  ------------------
              	    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   59|      0|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      0|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
              	    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   59|      0|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      0|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
  124|      0|	    goto done;
  125|      0|	}
  126|      1|    }
  127|       |
  128|       |    /* tty, followed by optional lines + cols */
  129|     81|    cp = ep + 1;
  130|     81|    if ((ep = strchr(cp, ':')) == NULL) {
  ------------------
  |  Branch (130:9): [True: 2, False: 79]
  ------------------
  131|       |	/* just the tty */
  132|      2|	if ((evlog->ttyname = strdup(cp)) == NULL) {
  ------------------
  |  Branch (132:6): [True: 0, False: 2]
  ------------------
  133|      0|	    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   45|      0|# define sudo_warnx sudo_warnx_nodebug_v1
  ------------------
              	    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   59|      0|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      0|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
              	    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   59|      0|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      0|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
  134|      0|	    goto done;
  135|      0|	}
  136|     79|    } else {
  137|       |	/* tty followed by lines + cols */
  138|     79|	if ((evlog->ttyname = strndup(cp, (size_t)(ep - cp))) == NULL) {
  ------------------
  |  Branch (138:6): [True: 0, False: 79]
  ------------------
  139|      0|	    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   45|      0|# define sudo_warnx sudo_warnx_nodebug_v1
  ------------------
              	    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   59|      0|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      0|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
              	    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  ------------------
  |  |   59|      0|# define U_(String) sudo_warn_gettext(String)
  |  |  ------------------
  |  |  |  |  208|      0|# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
  |  |  ------------------
  ------------------
  140|      0|	    goto done;
  141|      0|	}
  142|     79|	cp = ep + 1;
  143|       |	/* need to NULL out separator to use sudo_strtonum() */
  144|       |	/* XXX - use sudo_strtonumx */
  145|     79|	if ((ep = strchr(cp, ':')) != NULL) {
  ------------------
  |  Branch (145:6): [True: 12, False: 67]
  ------------------
  146|     12|	    *ep = '\0';
  147|     12|	}
  148|     79|	evlog->lines = sudo_strtonum(cp, 1, INT_MAX, &errstr);
  149|     79|	if (errstr != NULL) {
  ------------------
  |  Branch (149:6): [True: 55, False: 24]
  ------------------
  150|     55|	    sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
  ------------------
  |  |  239|     55|    sudo_debug_printf2(__func__, __FILE__, __LINE__, (pri)|sudo_debug_subsys, \
  |  |  ------------------
  |  |  |  |  298|     55|#define sudo_debug_printf2 sudo_debug_printf2_v1
  |  |  ------------------
  |  |  240|     55|    __VA_ARGS__)
  ------------------
  151|     55|		"%s: tty lines %s: %s", iolog_dir, cp, errstr);
  152|     55|	}
  153|     79|	if (ep != NULL) {
  ------------------
  |  Branch (153:6): [True: 12, False: 67]
  ------------------
  154|     12|	    cp = ep + 1;
  155|     12|	    evlog->columns = sudo_strtonum(cp, 1, INT_MAX, &errstr);
  156|     12|	    if (errstr != NULL) {
  ------------------
  |  Branch (156:10): [True: 8, False: 4]
  ------------------
  157|      8|		sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
  ------------------
  |  |  239|      8|    sudo_debug_printf2(__func__, __FILE__, __LINE__, (pri)|sudo_debug_subsys, \
  |  |  ------------------
  |  |  |  |  298|      8|#define sudo_debug_printf2 sudo_debug_printf2_v1
  |  |  ------------------
  |  |  240|      8|    __VA_ARGS__)
  ------------------
  158|      8|		    "%s: tty cols %s: %s", iolog_dir, cp, errstr);
  159|      8|	    }
  160|     12|	}
  161|     79|    }
  162|       |
  163|     81|    ret = true;
  164|       |
  165|    367|done:
  166|    367|    free(buf);
  167|    367|    debug_return_bool(ret);
  ------------------
  |  |  180|    367|    do {								       \
  |  |  181|    367|	bool sudo_debug_ret = (ret);					       \
  |  |  182|    367|	sudo_debug_exit_bool(__func__, __FILE__, __LINE__, sudo_debug_subsys,  \
  |  |  ------------------
  |  |  |  |  283|    367|#define sudo_debug_exit_bool(_a, _b, _c, _d, _e) sudo_debug_exit_bool_v1((_a), (_b), (_c), (_d), (_e))
  |  |  ------------------
  |  |  183|    367|	    sudo_debug_ret);						       \
  |  |  184|    367|	return sudo_debug_ret;						       \
  |  |  185|    367|    } while (0)
  |  |  ------------------
  |  |  |  Branch (185:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  168|    367|}

LLVMFuzzerTestOneInput:
   93|    367|{
   94|    367|    struct eventlog *evlog = NULL;
   95|    367|    FILE *fp;
   96|       |
   97|    367|    initprogname("fuzz_iolog_legacy");
   98|    367|    if (getenv("SUDO_FUZZ_VERBOSE") == NULL)
  ------------------
  |  Branch (98:9): [True: 367, False: 0]
  ------------------
   99|    367|	sudo_warn_set_conversation(fuzz_conversation);
  ------------------
  |  |  203|    367|#define sudo_warn_set_conversation(_a) sudo_warn_set_conversation_v1(_a)
  ------------------
  100|       |
  101|    367|    fp = open_data(data, size);
  102|    367|    if (fp == NULL)
  ------------------
  |  Branch (102:9): [True: 0, False: 367]
  ------------------
  103|      0|        return 0;
  104|       |
  105|       |    /* Parsed contents of an I/O log info file are stored in evlog. */
  106|    367|    evlog = calloc(1, sizeof(*evlog));
  107|    367|    if (evlog != NULL) {
  ------------------
  |  Branch (107:9): [True: 367, False: 0]
  ------------------
  108|    367|	evlog->runuid = (uid_t)-1;
  109|    367|	evlog->rungid = (gid_t)-1;
  110|       |
  111|       |	/* Try to parse buffer as a legacy-format I/O log info file. */
  112|    367|	iolog_parse_loginfo_legacy(fp, "fuzz.legacy", evlog);
  113|    367|	eventlog_free(evlog);
  114|    367|    }
  115|    367|    fclose(fp);
  116|    367|    fflush(stdout);
  117|       |
  118|    367|    return 0;
  119|    367|}
fuzz_iolog_legacy.c:fuzz_conversation:
   68|    286|{
   69|    286|    int n;
   70|       |
   71|  2.00k|    for (n = 0; n < num_msgs; n++) {
  ------------------
  |  Branch (71:17): [True: 1.71k, False: 286]
  ------------------
   72|  1.71k|	const struct sudo_conv_message *msg = &msgs[n];
   73|       |
   74|  1.71k|	switch (msg->msg_type & 0xff) {
   75|      0|	    case SUDO_CONV_PROMPT_ECHO_ON:
  ------------------
  |  |   44|      0|#define SUDO_CONV_PROMPT_ECHO_ON    0x0002  /* echo user input */
  ------------------
  |  Branch (75:6): [True: 0, False: 1.71k]
  ------------------
   76|      0|	    case SUDO_CONV_PROMPT_MASK:
  ------------------
  |  |   47|      0|#define SUDO_CONV_PROMPT_MASK	    0x0005  /* mask user input */
  ------------------
  |  Branch (76:6): [True: 0, False: 1.71k]
  ------------------
   77|      0|	    case SUDO_CONV_PROMPT_ECHO_OFF:
  ------------------
  |  |   43|      0|#define SUDO_CONV_PROMPT_ECHO_OFF   0x0001  /* do not echo user input */
  ------------------
  |  Branch (77:6): [True: 0, False: 1.71k]
  ------------------
   78|       |		/* input not supported */
   79|      0|		return -1;
   80|  1.71k|	    case SUDO_CONV_ERROR_MSG:
  ------------------
  |  |   45|  1.71k|#define SUDO_CONV_ERROR_MSG	    0x0003  /* error message */
  ------------------
  |  Branch (80:6): [True: 1.71k, False: 0]
  ------------------
   81|  1.71k|	    case SUDO_CONV_INFO_MSG:
  ------------------
  |  |   46|  1.71k|#define SUDO_CONV_INFO_MSG	    0x0004  /* informational message */
  ------------------
  |  Branch (81:6): [True: 0, False: 1.71k]
  ------------------
   82|       |		/* no output for fuzzers */
   83|  1.71k|		break;
   84|      0|	    default:
  ------------------
  |  Branch (84:6): [True: 0, False: 1.71k]
  ------------------
   85|      0|		return -1;
   86|  1.71k|	}
   87|  1.71k|    }
   88|    286|    return 0;
   89|    286|}
fuzz_iolog_legacy.c:open_data:
   41|    367|{
   42|    367|#ifdef HAVE_FMEMOPEN
   43|       |    /* Operate in-memory. */
   44|    367|    return fmemopen((void *)data, size, "r");
   45|       |#else
   46|       |    char tempfile[] = "/tmp/legacy.XXXXXX";
   47|       |    size_t nwritten;
   48|       |    int fd;
   49|       |
   50|       |    /* Use (unlinked) temporary file. */
   51|       |    fd = mkstemp(tempfile);
   52|       |    if (fd == -1)
   53|       |	return NULL;
   54|       |    unlink(tempfile);
   55|       |    nwritten = write(fd, data, size);
   56|       |    if (nwritten != size) {
   57|       |	close(fd);
   58|       |	return NULL;
   59|       |    }
   60|       |    lseek(fd, 0, SEEK_SET);
   61|       |    return fdopen(fd, "r");
   62|       |#endif
   63|    367|}

sudo_warn_nodebug_v1:
  117|    286|{
  118|    286|    va_list ap;
  119|       |
  120|    286|    va_start(ap, fmt);
  121|    286|    warning(strerror(errno), fmt, ap);
  122|    286|    va_end(ap);
  123|    286|}
sudo_warn_set_conversation_v1:
  311|    367|{
  312|    367|    sudo_warn_conversation = conv;
  313|    367|}
sudo_warn_gettext_v1:
  329|    286|{
  330|    286|    int cookie;
  331|    286|    char *msg;
  332|       |
  333|       |    /* Set user locale if setter was specified. */
  334|    286|    if (sudo_warn_setlocale != NULL)
  ------------------
  |  Branch (334:9): [True: 0, False: 286]
  ------------------
  335|      0|	sudo_warn_setlocale(false, &cookie);
  336|       |
  337|    286|    msg = dgettext(domainname, msgid);
  338|       |
  339|       |    /* Restore old locale as needed. */
  340|    286|    if (sudo_warn_setlocale != NULL)
  ------------------
  |  Branch (340:9): [True: 0, False: 286]
  ------------------
  341|      0|	sudo_warn_setlocale(true, &cookie);
  342|       |
  343|    286|    return msg;
  344|    286|}
fatal.c:warning:
  184|    286|{
  185|    286|    int cookie;
  186|    286|    const int saved_errno = errno;
  187|       |
  188|       |    /* Set user locale if setter was specified. */
  189|    286|    if (sudo_warn_setlocale != NULL)
  ------------------
  |  Branch (189:9): [True: 0, False: 286]
  ------------------
  190|      0|	sudo_warn_setlocale(false, &cookie);
  191|       |
  192|    286|    if (sudo_warn_conversation != NULL) {
  ------------------
  |  Branch (192:9): [True: 286, False: 0]
  ------------------
  193|    286|	struct sudo_conv_message msgs[6];
  194|    286|	char static_buf[1024], *buf = static_buf;
  195|    286|	int nmsgs = 0;
  196|       |
  197|       |	/* Use conversation function. */
  198|    286|        msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
  ------------------
  |  |   45|    286|#define SUDO_CONV_ERROR_MSG	    0x0003  /* error message */
  ------------------
  199|    286|	msgs[nmsgs++].msg = getprogname();
  ------------------
  |  |  546|    286|# define getprogname() sudo_getprogname()
  ------------------
  200|    286|        if (fmt != NULL) {
  ------------------
  |  Branch (200:13): [True: 286, False: 0]
  ------------------
  201|    286|		va_list ap2;
  202|    286|		int buflen;
  203|       |
  204|       |		/* Use static buffer if possible, else dynamic. */
  205|    286|		va_copy(ap2, ap);
  206|    286|		buflen = vsnprintf(static_buf, sizeof(static_buf), fmt, ap2);
  207|    286|		va_end(ap2);
  208|    286|		if (buflen >= ssizeof(static_buf)) {
  ------------------
  |  |  131|    286|#define ssizeof(_x)	((ssize_t)sizeof(_x))
  ------------------
  |  Branch (208:7): [True: 11, False: 275]
  ------------------
  209|     11|		    buf = malloc(++buflen);
  210|     11|		    if (buf != NULL)
  ------------------
  |  Branch (210:11): [True: 11, False: 0]
  ------------------
  211|     11|			(void)vsnprintf(buf, buflen, fmt, ap);
  212|      0|		    else
  213|      0|			buf = static_buf;
  214|     11|		}
  215|    286|		msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
  ------------------
  |  |   45|    286|#define SUDO_CONV_ERROR_MSG	    0x0003  /* error message */
  ------------------
  216|    286|		msgs[nmsgs++].msg = ": ";
  217|    286|		msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
  ------------------
  |  |   45|    286|#define SUDO_CONV_ERROR_MSG	    0x0003  /* error message */
  ------------------
  218|    286|		msgs[nmsgs++].msg = buf;
  219|    286|        }
  220|    286|        if (errstr != NULL) {
  ------------------
  |  Branch (220:13): [True: 286, False: 0]
  ------------------
  221|    286|	    msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
  ------------------
  |  |   45|    286|#define SUDO_CONV_ERROR_MSG	    0x0003  /* error message */
  ------------------
  222|    286|	    msgs[nmsgs++].msg = ": ";
  223|    286|	    msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
  ------------------
  |  |   45|    286|#define SUDO_CONV_ERROR_MSG	    0x0003  /* error message */
  ------------------
  224|    286|	    msgs[nmsgs++].msg = errstr;
  225|    286|        }
  226|    286|	msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
  ------------------
  |  |   45|    286|#define SUDO_CONV_ERROR_MSG	    0x0003  /* error message */
  ------------------
  227|    286|	msgs[nmsgs++].msg = "\n";
  228|    286|	sudo_warn_conversation(nmsgs, msgs, NULL, NULL);
  229|    286|	if (buf != static_buf)
  ------------------
  |  Branch (229:6): [True: 11, False: 275]
  ------------------
  230|     11|	    free(buf);
  231|    286|    } else {
  232|       |	/* Write to the standard error. */
  233|      0|        fputs(getprogname(), stderr);
  ------------------
  |  |  546|      0|# define getprogname() sudo_getprogname()
  ------------------
  234|      0|        if (fmt != NULL) {
  ------------------
  |  Branch (234:13): [True: 0, False: 0]
  ------------------
  235|      0|                fputs(": ", stderr);
  236|      0|                vfprintf(stderr, fmt, ap);
  237|      0|        }
  238|      0|        if (errstr != NULL) {
  ------------------
  |  Branch (238:13): [True: 0, False: 0]
  ------------------
  239|      0|            fputs(": ", stderr);
  240|      0|            fputs(errstr, stderr);
  241|      0|        }
  242|       |#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  243|       |        if (sudo_term_is_raw(fileno(stderr)))
  244|       |            putc('\r', stderr);
  245|       |#endif
  246|      0|        putc('\n', stderr);
  247|      0|    }
  248|       |
  249|       |    /* Restore old locale as needed. */
  250|    286|    if (sudo_warn_setlocale != NULL)
  ------------------
  |  Branch (250:9): [True: 0, False: 286]
  ------------------
  251|      0|	sudo_warn_setlocale(true, &cookie);
  252|       |
  253|       |    /* Do not clobber errno. */
  254|    286|    errno = saved_errno;
  255|    286|}

sudo_getprogname:
   47|    653|{
   48|    653|    return __progname;
   49|    653|}
initprogname2:
   62|    367|{
   63|    367|    const char *progname;
   64|    367|    int i;
   65|       |
   66|       |    /* Fall back on "name" if getprogname() returns an empty string. */
   67|    367|    if ((progname = getprogname()) != NULL && *progname != '\0') {
  ------------------
  |  |  546|    367|# define getprogname() sudo_getprogname()
  ------------------
  |  Branch (67:9): [True: 367, False: 0]
  |  Branch (67:47): [True: 367, False: 0]
  ------------------
   68|    367|	name = progname;
   69|    367|    } else {
   70|       |	/* Make sure user-specified name is relative. */
   71|      0|	name = sudo_basename(name);
  ------------------
  |  |  171|      0|#define sudo_basename(_a) sudo_basename_v1(_a)
  ------------------
   72|      0|    }
   73|       |
   74|       |    /* Check for libtool prefix and strip it if present. */
   75|    367|    if (name[0] == 'l' && name[1] == 't' && name[2] == '-' && name[3] != '\0')
  ------------------
  |  Branch (75:9): [True: 0, False: 367]
  |  Branch (75:27): [True: 0, False: 0]
  |  Branch (75:45): [True: 0, False: 0]
  |  Branch (75:63): [True: 0, False: 0]
  ------------------
   76|      0|	name += 3;
   77|       |
   78|       |    /* Check allow list if present (first element is the default). */
   79|    367|    if (allowed != NULL) {
  ------------------
  |  Branch (79:9): [True: 0, False: 367]
  ------------------
   80|      0|	for (i = 0; ; i++) {
   81|      0|	    if (allowed[i] == NULL) {
  ------------------
  |  Branch (81:10): [True: 0, False: 0]
  ------------------
   82|      0|		name = allowed[0];
   83|      0|		break;
   84|      0|	    }
   85|      0|	    if (strcmp(allowed[i], name) == 0)
  ------------------
  |  Branch (85:10): [True: 0, False: 0]
  ------------------
   86|      0|		break;
   87|      0|	}
   88|      0|    }
   89|       |
   90|       |    /* Update internal progname if needed. */
   91|    367|    if (name != progname)
  ------------------
  |  Branch (91:9): [True: 0, False: 367]
  ------------------
   92|      0|	setprogname(name);
  ------------------
  |  |  551|      0|# define setprogname(_a) sudo_setprogname(_a)
  ------------------
   93|    367|    return;
   94|    367|}
initprogname:
   98|    367|{
   99|    367|    initprogname2(name, NULL);
  100|    367|}

sudo_strtonumx:
   48|    398|{
   49|    398|    enum strtonum_err errval = STN_INITIAL;
   50|    398|    long long lastval, result = 0;
   51|    398|    const char *cp = str;
   52|    398|    unsigned char ch;
   53|    398|    int remainder;
   54|    398|    char sign;
   55|       |
   56|    398|    if (minval > maxval) {
  ------------------
  |  Branch (56:9): [True: 0, False: 398]
  ------------------
   57|      0|	errval = STN_INVALID;
   58|      0|	goto done;
   59|      0|    }
   60|       |
   61|       |    /* Trim leading space and check sign, if any. */
   62|    592|    do {
   63|    592|	ch = *cp++;
   64|    592|    } while (isspace(ch));
   65|    398|    switch (ch) {
   66|     49|    case '-':
  ------------------
  |  Branch (66:5): [True: 49, False: 349]
  ------------------
   67|     49|	sign = '-';
   68|     49|	ch = *cp++;
   69|     49|	break;
   70|      6|    case '+':
  ------------------
  |  Branch (70:5): [True: 6, False: 392]
  ------------------
   71|      6|	ch = *cp++;
   72|      6|	FALLTHROUGH;
  ------------------
  |  | 1597|      6|#  define FALLTHROUGH		__attribute__((__fallthrough__))
  ------------------
   73|    349|    default:
  ------------------
  |  Branch (73:5): [True: 343, False: 55]
  ------------------
   74|    349|	sign = '+';
   75|    349|	break;
   76|    398|    }
   77|       |
   78|       |    /*
   79|       |     * To prevent overflow we determine the highest (or lowest in
   80|       |     * the case of negative numbers) value result can have *before*
   81|       |     * if its multiplied (divided) by 10 as well as the remainder.
   82|       |     * If result matches this value and the next digit is larger than
   83|       |     * the remainder, we know the result is out of range.
   84|       |     * The remainder is always positive since it is compared against
   85|       |     * an unsigned digit.
   86|       |     */
   87|    398|    if (sign == '-') {
  ------------------
  |  Branch (87:9): [True: 49, False: 349]
  ------------------
   88|     49|	lastval = minval / 10;
   89|     49|	remainder = -(minval % 10);
   90|     49|	if (remainder < 0) {
  ------------------
  |  Branch (90:6): [True: 9, False: 40]
  ------------------
   91|      9|	    lastval += 1;
   92|      9|	    remainder += 10;
   93|      9|	}
   94|    434|	for (;; ch = *cp++) {
   95|    434|	    if (!isdigit(ch))
  ------------------
  |  Branch (95:10): [True: 18, False: 416]
  ------------------
   96|     18|		break;
   97|    416|	    ch -= '0';
   98|    416|	    if (result < lastval || (result == lastval && ch > remainder)) {
  ------------------
  |  Branch (98:10): [True: 3, False: 413]
  |  Branch (98:31): [True: 413, False: 0]
  |  Branch (98:52): [True: 28, False: 385]
  ------------------
   99|       |		/* Skip remaining digits. */
  100|   518k|		do {
  101|   518k|		    ch = *cp++;
  102|   518k|		} while (isdigit(ch));
  103|     31|		errval = STN_TOOSMALL;
  104|     31|		break;
  105|    385|	    } else {
  106|    385|		result *= 10;
  107|    385|		result -= ch;
  108|    385|		errval = STN_VALID;
  109|    385|	    }
  110|    416|	}
  111|     49|	if (result > maxval)
  ------------------
  |  Branch (111:6): [True: 0, False: 49]
  ------------------
  112|      0|	    errval = STN_TOOBIG;
  113|    349|    } else {
  114|    349|	lastval = maxval / 10;
  115|    349|	remainder = maxval % 10;
  116|  3.66k|	for (;; ch = *cp++) {
  117|  3.66k|	    if (!isdigit(ch))
  ------------------
  |  Branch (117:10): [True: 258, False: 3.41k]
  ------------------
  118|    258|		break;
  119|  3.41k|	    ch -= '0';
  120|  3.41k|	    if (result > lastval || (result == lastval && ch > remainder)) {
  ------------------
  |  Branch (120:10): [True: 87, False: 3.32k]
  |  Branch (120:31): [True: 14, False: 3.31k]
  |  Branch (120:52): [True: 4, False: 10]
  ------------------
  121|       |		/* Skip remaining digits. */
  122|  5.89k|		do {
  123|  5.89k|		    ch = *cp++;
  124|  5.89k|		} while (isdigit(ch));
  125|     91|		errval = STN_TOOBIG;
  126|     91|		break;
  127|  3.32k|	    } else {
  128|  3.32k|		result *= 10;
  129|  3.32k|		result += ch;
  130|  3.32k|		errval = STN_VALID;
  131|  3.32k|	    }
  132|  3.41k|	}
  133|    349|	if (result < minval)
  ------------------
  |  Branch (133:6): [True: 7, False: 342]
  ------------------
  134|      7|	    errval = STN_TOOSMALL;
  135|    349|    }
  136|       |
  137|    398|done:
  138|    398|    switch (errval) {
  ------------------
  |  Branch (138:13): [True: 0, False: 398]
  ------------------
  139|     17|    case STN_INITIAL:
  ------------------
  |  Branch (139:5): [True: 17, False: 381]
  ------------------
  140|    269|    case STN_VALID:
  ------------------
  |  Branch (140:5): [True: 252, False: 146]
  ------------------
  141|    269|	if (errstrp != NULL)
  ------------------
  |  Branch (141:6): [True: 269, False: 0]
  ------------------
  142|    269|	    *errstrp = NULL;
  143|    269|	break;
  144|      0|    case STN_INVALID:
  ------------------
  |  Branch (144:5): [True: 0, False: 398]
  ------------------
  145|      0|	result = 0;
  146|      0|	errno = EINVAL;
  147|      0|	if (errstrp != NULL)
  ------------------
  |  Branch (147:6): [True: 0, False: 0]
  ------------------
  148|      0|	    *errstrp = N_("invalid value");
  ------------------
  |  |   58|      0|# define N_(String) gettext_noop(String)
  |  |  ------------------
  |  |  |  |   57|      0|# define gettext_noop(String) String
  |  |  ------------------
  ------------------
  149|      0|	break;
  150|     38|    case STN_TOOSMALL:
  ------------------
  |  Branch (150:5): [True: 38, False: 360]
  ------------------
  151|     38|	result = 0;
  152|     38|	errno = ERANGE;
  153|     38|	if (errstrp != NULL)
  ------------------
  |  Branch (153:6): [True: 38, False: 0]
  ------------------
  154|     38|	    *errstrp = N_("value too small");
  ------------------
  |  |   58|     38|# define N_(String) gettext_noop(String)
  |  |  ------------------
  |  |  |  |   57|     38|# define gettext_noop(String) String
  |  |  ------------------
  ------------------
  155|     38|	break;
  156|     91|    case STN_TOOBIG:
  ------------------
  |  Branch (156:5): [True: 91, False: 307]
  ------------------
  157|     91|	result = 0;
  158|     91|	errno = ERANGE;
  159|     91|	if (errstrp != NULL)
  ------------------
  |  Branch (159:6): [True: 91, False: 0]
  ------------------
  160|     91|	    *errstrp = N_("value too large");
  ------------------
  |  |   58|     91|# define N_(String) gettext_noop(String)
  |  |  ------------------
  |  |  |  |   57|     91|# define gettext_noop(String) String
  |  |  ------------------
  ------------------
  161|     91|	break;
  162|    398|    }
  163|    398|    if (endp != NULL) {
  ------------------
  |  Branch (163:9): [True: 398, False: 0]
  ------------------
  164|    398|	if (errval == STN_INITIAL || errval == STN_INVALID)
  ------------------
  |  Branch (164:6): [True: 17, False: 381]
  |  Branch (164:31): [True: 0, False: 381]
  ------------------
  165|     17|	    *endp = (char *)str;
  166|    381|	else
  167|    381|	    *endp = (char *)(cp - 1);
  168|    398|    }
  169|    398|    return result;
  170|    398|}
sudo_strtonum:
  178|    398|{
  179|    398|    const char *errstr;
  180|    398|    char *ep;
  181|    398|    long long ret;
  182|       |
  183|    398|    ret = sudo_strtonumx(str, minval, maxval, &ep, &errstr);
  184|       |    /* Check for empty string and terminating NUL. */
  185|    398|    if (str == ep || *ep != '\0') {
  ------------------
  |  Branch (185:9): [True: 21, False: 377]
  |  Branch (185:22): [True: 12, False: 365]
  ------------------
  186|     33|	errno = EINVAL;
  187|     33|	errstr = N_("invalid value");
  ------------------
  |  |   58|     33|# define N_(String) gettext_noop(String)
  |  |  ------------------
  |  |  |  |   57|     33|# define gettext_noop(String) String
  |  |  ------------------
  ------------------
  188|     33|	ret = 0;
  189|     33|    }
  190|    398|    if (errstrp != NULL)
  ------------------
  |  Branch (190:9): [True: 398, False: 0]
  ------------------
  191|    398|	*errstrp = errstr;
  192|    398|    return ret;
  193|    398|}

sudo_debug_enter_v1:
 1040|    734|{
 1041|    734|}
sudo_debug_exit_v1:
 1046|    367|{
 1047|    367|}
sudo_debug_exit_bool_v1:
 1088|    367|{
 1089|    367|}
sudo_debug_printf2_v1:
 1137|     63|{
 1138|     63|}

