From d9908fc1f272a2859b525c3bd92d9f3e8a2a6293 Mon Sep 17 00:00:00 2001 From: Andrew Gregory Date: Sat, 18 Feb 2017 17:09:50 -0500 Subject: parse stdin as newline-separated Newline-separated input is more reliable because most of the arguments we accept over stdin can validly contain spaces but not newlines. Resolves FS#52992 Signed-off-by: Andrew Gregory Signed-off-by: Allan McRae --- src/pacman/pacman.c | 55 ++++++++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index a66bf585..fe96cb3b 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -1100,7 +1100,6 @@ static void cl_to_log(int argc, char *argv[]) int main(int argc, char *argv[]) { int ret = 0; - size_t i; uid_t myuid = getuid(); install_segv_handler(); @@ -1148,44 +1147,36 @@ int main(int argc, char *argv[]) if(alpm_list_find_str(pm_targets, "-")) { if(!isatty(fileno(stdin))) { int target_found = 0; - size_t current_size = PATH_MAX; - char *vdata, *line = malloc(current_size); - int c; + char *vdata, *line = NULL; + size_t line_size = 0; + ssize_t nread; /* remove the '-' from the list */ pm_targets = alpm_list_remove_str(pm_targets, "-", &vdata); free(vdata); - i = 0; - do { - c = fgetc(stdin); - if(c == EOF || isspace(c)) { - /* avoid adding zero length arg when multiple spaces separate args */ - if(i > 0) { - line[i] = '\0'; - pm_targets = alpm_list_add(pm_targets, strdup(line)); - target_found = 1; - i = 0; - } - } else { - line[i++] = (char)c; - /* we may be at the end of our allocated buffer now */ - if(i >= current_size) { - char *new = realloc(line, current_size * 2); - if(new) { - line = new; - current_size *= 2; - } else { - free(line); - pm_printf(ALPM_LOG_ERROR, - _("memory exhausted in argument parsing\n")); - cleanup(EXIT_FAILURE); - } - } + while((nread = getline(&line, &line_size, stdin)) != -1) { + if(line[nread - 1] == '\n') { + /* remove trailing newline */ + line[nread - 1] = '\0'; } - } while(c != EOF); - + if(line[0] == '\0') { + /* skip empty lines */ + continue; + } + if(!alpm_list_append_strdup(&pm_targets, line)) { + break; + } + target_found = 1; + } free(line); + + if(ferror(stdin)) { + pm_printf(ALPM_LOG_ERROR, + _("failed to read arguments from stdin: (%s)\n"), strerror(errno)); + cleanup(EXIT_FAILURE); + } + if(!freopen(ctermid(NULL), "r", stdin)) { pm_printf(ALPM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"), strerror(errno)); -- cgit v1.2.3