Diff for /embedaddon/sudo/common/lbuf.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2012/10/09 09:29:52 version 1.1.1.4, 2013/07/22 10:46:11
Line 1 Line 1
 /*  /*
 * Copyright (c) 2007-2011 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 2007-2013 Todd C. Miller <Todd.Miller@courtesan.com>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 19 Line 19
 #include <config.h>  #include <config.h>
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/param.h>  
 #include <stdio.h>  #include <stdio.h>
 #ifdef STDC_HEADERS  #ifdef STDC_HEADERS
 # include <stdlib.h>  # include <stdlib.h>
Line 77  lbuf_destroy(struct lbuf *lbuf) Line 76  lbuf_destroy(struct lbuf *lbuf)
     debug_return;      debug_return;
 }  }
   
   static void
   lbuf_expand(struct lbuf *lbuf, size_t extra)
   {
       if (lbuf->len + extra + 1 >= lbuf->size) {
           do {
               lbuf->size += 256;
           } while (lbuf->len + extra + 1 >= lbuf->size);
           lbuf->buf = erealloc(lbuf->buf, lbuf->size);
       }
   }
   
 /*  /*
  * Parse the format and append strings, only %s and %% escapes are supported.   * Parse the format and append strings, only %s and %% escapes are supported.
  * Any characters in set are quoted with a backslash.   * Any characters in set are quoted with a backslash.
Line 86  lbuf_append_quoted(struct lbuf *lbuf, const char *set, Line 96  lbuf_append_quoted(struct lbuf *lbuf, const char *set,
 {  {
     va_list ap;      va_list ap;
     int len;      int len;
    char *cp, *s = NULL;    char *cp, *s;
     debug_decl(lbuf_append_quoted, SUDO_DEBUG_UTIL)      debug_decl(lbuf_append_quoted, SUDO_DEBUG_UTIL)
   
     va_start(ap, fmt);      va_start(ap, fmt);
     while (*fmt != '\0') {      while (*fmt != '\0') {
         len = 1;  
         if (fmt[0] == '%' && fmt[1] == 's') {          if (fmt[0] == '%' && fmt[1] == 's') {
            s = va_arg(ap, char *);            if ((s = va_arg(ap, char *)) == NULL)
            len = strlen(s);                goto done;
        }            while ((cp = strpbrk(s, set)) != NULL) {
        /* Assume worst case that all chars must be escaped. */                len = (int)(cp - s);
        if (lbuf->len + (len * 2) + 1 >= lbuf->size) {                lbuf_expand(lbuf, len + 2);
            do {                memcpy(lbuf->buf + lbuf->len, s, len);
                lbuf->size += 256;                lbuf->len += len;
            } while (lbuf->len + len + 1 >= lbuf->size);                lbuf->buf[lbuf->len++] = '\\';
            lbuf->buf = erealloc(lbuf->buf, lbuf->size);                lbuf->buf[lbuf->len++] = *cp;
        }                s = cp + 1;
        if (*fmt == '%') { 
            if (*(++fmt) == 's') { 
                while ((cp = strpbrk(s, set)) != NULL) { 
                    len = (int)(cp - s); 
                    memcpy(lbuf->buf + lbuf->len, s, len); 
                    lbuf->len += len; 
                    lbuf->buf[lbuf->len++] = '\\'; 
                    lbuf->buf[lbuf->len++] = *cp; 
                    s = cp + 1; 
                } 
                if (*s != '\0') { 
                    len = strlen(s); 
                    memcpy(lbuf->buf + lbuf->len, s, len); 
                    lbuf->len += len; 
                } 
                fmt++; 
                continue; 
             }              }
               if (*s != '\0') {
                   len = strlen(s);
                   lbuf_expand(lbuf, len);
                   memcpy(lbuf->buf + lbuf->len, s, len);
                   lbuf->len += len;
               }
               fmt += 2;
               continue;
         }          }
           lbuf_expand(lbuf, 2);
         if (strchr(set, *fmt) != NULL)          if (strchr(set, *fmt) != NULL)
             lbuf->buf[lbuf->len++] = '\\';              lbuf->buf[lbuf->len++] = '\\';
         lbuf->buf[lbuf->len++] = *fmt++;          lbuf->buf[lbuf->len++] = *fmt++;
     }      }
    lbuf->buf[lbuf->len] = '\0';done:
     if (lbuf->size != 0)
         lbuf->buf[lbuf->len] = '\0';
     va_end(ap);      va_end(ap);
   
     debug_return;      debug_return;
Line 140  lbuf_append(struct lbuf *lbuf, const char *fmt, ...) Line 143  lbuf_append(struct lbuf *lbuf, const char *fmt, ...)
 {  {
     va_list ap;      va_list ap;
     int len;      int len;
    char *s = NULL;    char *s;
     debug_decl(lbuf_append, SUDO_DEBUG_UTIL)      debug_decl(lbuf_append, SUDO_DEBUG_UTIL)
   
     va_start(ap, fmt);      va_start(ap, fmt);
     while (*fmt != '\0') {      while (*fmt != '\0') {
         len = 1;  
         if (fmt[0] == '%' && fmt[1] == 's') {          if (fmt[0] == '%' && fmt[1] == 's') {
            s = va_arg(ap, char *);            if ((s = va_arg(ap, char *)) == NULL)
                 goto done;
             len = strlen(s);              len = strlen(s);
               lbuf_expand(lbuf, len);
               memcpy(lbuf->buf + lbuf->len, s, len);
               lbuf->len += len;
               fmt += 2;
               continue;
         }          }
        if (lbuf->len + len + 1 >= lbuf->size) {        lbuf_expand(lbuf, 1);
            do { 
                lbuf->size += 256; 
            } while (lbuf->len + len + 1 >= lbuf->size); 
            lbuf->buf = erealloc(lbuf->buf, lbuf->size); 
        } 
        if (*fmt == '%') { 
            if (*(++fmt) == 's') { 
                memcpy(lbuf->buf + lbuf->len, s, len); 
                lbuf->len += len; 
                fmt++; 
                continue; 
            } 
        } 
         lbuf->buf[lbuf->len++] = *fmt++;          lbuf->buf[lbuf->len++] = *fmt++;
     }      }
    lbuf->buf[lbuf->len] = '\0';done:
     if (lbuf->size != 0)
         lbuf->buf[lbuf->len] = '\0';
     va_end(ap);      va_end(ap);
   
     debug_return;      debug_return;

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>