Enhanced sq_quote()

Create function to sq_quote into a buffer
Handle !'s for csh-based shells

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
H. Peter Anvin 2005-10-10 14:46:10 -07:00 committed by Junio C Hamano
parent 4769948afe
commit 77d604c309
2 changed files with 43 additions and 24 deletions

58
quote.c
View File

@ -2,40 +2,52 @@
#include "quote.h"
/* Help to copy the thing properly quoted for the shell safety.
* any single quote is replaced with '\'', and the caller is
* expected to enclose the result within a single quote pair.
* any single quote is replaced with '\'', any exclamation point
* is replaced with '\!', and the whole thing is enclosed in a
*
* E.g.
* original sq_quote result
* name ==> name ==> 'name'
* a b ==> a b ==> 'a b'
* a'b ==> a'\''b ==> 'a'\''b'
* a!b ==> a'\!'b ==> 'a'\!'b'
*/
#define EMIT(x) ( (++len < n) && (*bp++ = (x)) )
size_t sq_quote_buf(char *dst, size_t n, const char *src)
{
char c;
char *bp = dst;
size_t len = 0;
EMIT('\'');
while ((c = *src++)) {
if (c == '\'' || c == '!') {
EMIT('\'');
EMIT('\\');
EMIT(c);
EMIT('\'');
} else {
EMIT(c);
}
}
EMIT('\'');
if ( n )
*bp = 0;
return len;
}
char *sq_quote(const char *src)
{
static char *buf = NULL;
int cnt, c;
const char *cp;
char *bp;
/* count bytes needed to store the quoted string. */
for (cnt = 3, cp = src; *cp; cnt++, cp++)
if (*cp == '\'')
cnt += 3;
char *buf;
size_t cnt;
cnt = sq_quote_buf(NULL, 0, src) + 1;
buf = xmalloc(cnt);
bp = buf;
*bp++ = '\'';
while ((c = *src++)) {
if (c != '\'')
*bp++ = c;
else {
bp = strcpy(bp, "'\\''");
bp += 4;
}
}
*bp++ = '\'';
*bp = 0;
sq_quote_buf(buf, cnt, src);
return buf;
}

11
quote.h
View File

@ -1,10 +1,12 @@
#ifndef QUOTE_H
#define QUOTE_H
#include <stddef.h>
/* Help to copy the thing properly quoted for the shell safety.
* any single quote is replaced with '\'', and the whole thing
* is enclosed in a single quote pair.
* any single quote is replaced with '\'', any exclamation point
* is replaced with '\!', and the whole thing is enclosed in a
* single quote pair.
*
* For example, if you are passing the result to system() as an
* argument:
@ -19,8 +21,13 @@
*
* Note that the above examples leak memory! Remember to free result from
* sq_quote() in a real application.
*
* sq_quote_buf() writes to an existing buffer of specified size; it
* will return the number of characters that would have been written
* excluding the final null regardless of the buffer size.
*/
char *sq_quote(const char *src);
size_t sq_quote_buf(char *dst, size_t n, const char *src);
#endif