On 02/18/17 at 05:09pm, Andrew Gregory wrote:
> 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 <[email protected]>
> ---
>  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 a459cf00..7651df3c 100644
> --- a/src/pacman/pacman.c
> +++ b/src/pacman/pacman.c
> @@ -1094,7 +1094,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();
> @@ -1142,44 +1141,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);
> +                     }

This, of course, won't catch errors from appending to pm_targets.
Switched to using errno for error detection in my repo.

> +
>                       if(!freopen(ctermid(NULL), "r", stdin)) {
>                               pm_printf(ALPM_LOG_ERROR, _("failed to reopen 
> stdin for reading: (%s)\n"),
>                                               strerror(errno));
> -- 
> 2.11.1

Reply via email to