1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-10-27 11:33:19 +03:00

Escape double quotes and backslashes in external metadata and config data.

Add functions for escaping double quotes in strings.
Rename count_chars_len to count_chars.
This commit is contained in:
Alasdair Kergon
2008-03-12 16:03:22 +00:00
parent bcacf9d0e3
commit d4ce89d9da
6 changed files with 155 additions and 25 deletions

View File

@@ -39,16 +39,16 @@ int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
* Count occurences of 'c' in 'str' until we reach a null char.
*
* Returns:
* len - incremented for each char we encounter, whether 'c' or not.
* count - number of occurrences of 'c'
* len - incremented for each char we encounter.
* count - number of occurrences of 'c' and 'c2'.
*/
void count_chars(const char *str, size_t *len, int *count,
const int c)
static void _count_chars(const char *str, size_t *len, int *count,
const int c1, const int c2)
{
const char *ptr;
for (ptr = str; *ptr; ptr++, (*len)++)
if (*ptr == c)
if (*ptr == c1 || *ptr == c2)
(*count)++;
}
@@ -58,7 +58,7 @@ void count_chars(const char *str, size_t *len, int *count,
* Returns:
* Number of occurrences of 'c'
*/
unsigned count_chars_len(const char *str, size_t len, const int c)
unsigned count_chars(const char *str, size_t len, const int c)
{
size_t i;
unsigned count = 0;
@@ -70,17 +70,62 @@ unsigned count_chars_len(const char *str, size_t len, const int c)
return count;
}
/*
* Length of string after escaping double quotes and backslashes.
*/
size_t escaped_len(const char *str)
{
size_t len = 1;
int count = 0;
_count_chars(str, &len, &count, '\"', '\\');
return count + len;
}
/*
* Copies a string, quoting orig_char with quote_char.
* Optionally also quote quote_char.
*/
static void _quote_characters(char **out, const char *src,
const int orig_char, const int quote_char,
int quote_quote_char)
{
while (*src) {
if (*src == orig_char ||
(*src == quote_char && quote_quote_char))
*(*out)++ = quote_char;
*(*out)++ = *src++;
}
}
/*
* Unquote orig_char in string.
* Also unquote quote_char.
*/
static void _unquote_characters(char *src, const int orig_char,
const int quote_char)
{
char *out = src;
while (*src) {
if (*src == quote_char &&
(*(src + 1) == orig_char || *(src + 1) == quote_char))
src++;
*out++ = *src++;
}
*out = '\0';
}
/*
* Copies a string, quoting hyphens with hyphens.
*/
static void _quote_hyphens(char **out, const char *src)
{
while (*src) {
if (*src == '-')
*(*out)++ = '-';
*(*out)++ = *src++;
}
return _quote_characters(out, src, '-', '-', 0);
}
/*
@@ -93,11 +138,11 @@ char *build_dm_name(struct dm_pool *mem, const char *vgname,
int hyphens = 1;
char *r, *out;
count_chars(vgname, &len, &hyphens, '-');
count_chars(lvname, &len, &hyphens, '-');
_count_chars(vgname, &len, &hyphens, '-', 0);
_count_chars(lvname, &len, &hyphens, '-', 0);
if (layer && *layer) {
count_chars(layer, &len, &hyphens, '-');
_count_chars(layer, &len, &hyphens, '-', 0);
hyphens++;
}
@@ -125,6 +170,27 @@ char *build_dm_name(struct dm_pool *mem, const char *vgname,
return r;
}
/*
* Copies a string, quoting double quotes with backslashes.
*/
char *escape_double_quotes(char *out, const char *src)
{
char *buf = out;
_quote_characters(&buf, src, '\"', '\\', 1);
*buf = '\0';
return out;
}
/*
* Undo quoting in situ.
*/
void unescape_double_quotes(char *src)
{
_unquote_characters(src, '\"', '\\');
}
/*
* Device layer names are all of the form <vg>-<lv>-<layer>, any
* other hyphens that appear in these names are quoted with yet