Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:kernel-2.6.32
netatalk
netatalk.papd.quote-vars.fixed.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File netatalk.papd.quote-vars.fixed.patch of Package netatalk
quote chars correctly --- etc/papd/lp.c | 214 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 127 insertions(+), 87 deletions(-) --- a/etc/papd/lp.c +++ b/etc/papd/lp.c @@ -211,99 +211,137 @@ static void lp_setup_comments (charset_t } #define is_var(a, b) (strncmp((a), (b), 2) == 0) +enum quote_state { + NONE, + QUOTEDBL, + APOSTROPHE, +}; -static size_t quote(char *dest, char *src, const size_t bsize, size_t len) +static size_t quote_var(char *dest, size_t destlen, enum quote_state qs, const char *untrusted) { -size_t used = 0; + char c = 0; + size_t len = 0; - while (len && used < bsize ) { - switch (*src) { - case '$': - case '\\': - case '"': - case '`': - if (used + 2 > bsize ) - return used; - *dest = '\\'; - dest++; - used++; - break; - } - *dest = *src; - src++; - dest++; - len--; - used++; - } - return used; + if (qs == NONE) { + *dest='\''; + dest++; + len++; + if (destlen > 1) + destlen--; + } + while (untrusted && (destlen - len) > 1 && (c = *untrusted)) { + if (c == '\'' && (qs == NONE || qs == APOSTROPHE)) { + /* man bash: + * A single quote may not occur between single quotes, + * even when preceded by a backslash. + */ + c = '_'; + } else if (qs == QUOTEDBL) { + switch (c) { + /* subshells are escaped + * no need to handle "& * # ' ; { } < >" */ + case '"': + case '`': + case '$': + case '(': + case ')': + case '\\': + case '!': + *dest = '\\'; + dest++; + len++; + default: + break; + } + } else if (c == '\\') { + *dest = '\\'; + dest++; + len++; + } + *dest = c; + dest++; + len++; + untrusted++; + } + if (qs == NONE) { + *dest='\''; + dest++; + len++; + } + return len; } - -static char* pipexlate(char *src) +static char *pipexlate(char *src) { - char *p, *q, *dest; - static char destbuf[MAXPATHLEN +1]; - size_t destlen = MAXPATHLEN; - int len = 0; - - dest = destbuf; - - if (!src) - return NULL; - - memset(dest, 0, MAXPATHLEN +1); - if ((p = strchr(src, '%')) == NULL) { /* nothing to do */ - strncpy(dest, src, MAXPATHLEN); - return destbuf; - } - /* first part of the path. copy and forward to the next variable. */ - len = MIN((size_t)(p - src), destlen); - if (len > 0) { - strncpy(dest, src, len); - destlen -= len; - dest += len; - } - - while (p && destlen > 0) { - /* now figure out what the variable is */ - q = NULL; - if (is_var(p, "%U")) { - q = lp.lp_person; - } else if (is_var(p, "%C") || is_var(p, "%J") ) { - q = lp.lp_job; - } else if (is_var(p, "%F")) { - q = lp.lp_created_for; - } else if (is_var(p, "%%")) { - q = "%"; - } - - /* copy the stuff over. if we don't understand something that we - * should, just skip it over. */ - if (q) { - len = MIN(strlen(q), destlen); - len = quote(dest, q, destlen, len); - } - else { - len = MIN(2, destlen); - strncpy(dest, q, len); - } - dest += len; - destlen -= len; - - /* stuff up to next % */ - src = p + 2; - p = strchr(src, '%'); - len = p ? MIN((size_t)(p - src), destlen) : destlen; - if (len > 0) { - strncpy(dest, src, len); - dest += len; - destlen -= len; - } - } - return destbuf; + char *dest, *p; + char c, *untrusted; + static char destbuf[MAXPATHLEN]; + size_t destlen, vlen; + enum quote_state qs; + + if (!src) + return NULL; + + p = src; + dest = destbuf; + destlen = sizeof(destbuf) - 1; + qs = NONE; + + while (destlen && (c = *src)) { + untrusted = NULL; + if (c == '%') { + switch (src[1]) { + /* %U */ + case 'U': + untrusted = lp.lp_person; + break; + /* %C/%J */ + case 'C': + case 'J': + untrusted = lp.lp_job; + break; + /* %F */ + case 'F': + untrusted = lp.lp_created_for; + break; + /* %% */ + case '%': + src++; /* forward to the % and continue copying */ + /* Unhandled variable, just copy */ + default: + break; + } + } + /* expand variables */ + if (untrusted) { + vlen = quote_var(dest, destlen, qs, untrusted); + src += 2; + dest += vlen; + destlen -= vlen; + continue; + } + if (c == '\'') { + if (qs == NONE) { + qs = APOSTROPHE; + } else if (qs == APOSTROPHE) { + qs = NONE; + } + } else if (c == '"') { + if (qs == NONE) { + qs = QUOTEDBL; + } else if (qs == QUOTEDBL) { + qs = NONE; + } + } + *dest = c; + src++; + dest++; + destlen--; + } + *dest = '\0'; + return destbuf; } - void lp_person( person ) char *person; { @@ -570,6 +608,7 @@ int lp_open( out, sat ) } if ( lp.lp_flags & LP_PIPE ) { + char *pipe_cmd; /* go right to program */ if (lp.lp_person != NULL) { @@ -583,12 +622,13 @@ int lp_open( out, sat ) } lp_setup_comments(CH_UNIX); - if (( lp.lp_stream = popen( pipexlate(printer->p_printer), "w" )) == NULL ) { + pipe_cmd = pipexlate(printer->p_printer); + if ((lp.lp_stream = popen(pipe_cmd, "w")) == NULL) { LOG(log_error, logtype_papd, "lp_open popen %s: %m", printer->p_printer ); spoolerror( out, NULL ); return( -1 ); } - LOG(log_debug, logtype_papd, "lp_open: opened %s", pipexlate(printer->p_printer) ); + LOG(log_debug, logtype_papd, "lp_open: opened %s", pipe_cmd); } else { sprintf( name, "df%c%03d%s", lp.lp_letter++, lp.lp_seq, hostname );
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor