mirror of
https://github.com/libgit2/libgit2.git
synced 2026-01-25 02:56:17 +00:00
str: allow escaping with prefix and suffix
Allow `git_str_puts_escaped` to take an escaping prefix and an escaping suffix; this allows for more options, including the ability to better support escaping executed paths.
This commit is contained in:
@@ -1065,10 +1065,13 @@ int git_str_puts_escaped(
|
||||
git_str *buf,
|
||||
const char *string,
|
||||
const char *esc_chars,
|
||||
const char *esc_with)
|
||||
const char *esc_prefix,
|
||||
const char *esc_suffix)
|
||||
{
|
||||
const char *scan;
|
||||
size_t total = 0, esc_len = strlen(esc_with), count, alloclen;
|
||||
size_t total = 0, count, alloclen;
|
||||
size_t esc_prefix_len = esc_prefix ? strlen(esc_prefix) : 0;
|
||||
size_t esc_suffix_len = esc_suffix ? strlen(esc_suffix) : 0;
|
||||
|
||||
if (!string)
|
||||
return 0;
|
||||
@@ -1080,7 +1083,7 @@ int git_str_puts_escaped(
|
||||
scan += count;
|
||||
/* count run of escaped characters */
|
||||
count = strspn(scan, esc_chars);
|
||||
total += count * (esc_len + 1);
|
||||
total += count * (esc_prefix_len + esc_suffix_len + 1);
|
||||
scan += count;
|
||||
}
|
||||
|
||||
@@ -1096,13 +1099,22 @@ int git_str_puts_escaped(
|
||||
buf->size += count;
|
||||
|
||||
for (count = strspn(scan, esc_chars); count > 0; --count) {
|
||||
/* copy escape sequence */
|
||||
memmove(buf->ptr + buf->size, esc_with, esc_len);
|
||||
buf->size += esc_len;
|
||||
/* copy escape prefix sequence */
|
||||
if (esc_prefix) {
|
||||
memmove(buf->ptr + buf->size, esc_prefix, esc_prefix_len);
|
||||
buf->size += esc_prefix_len;
|
||||
}
|
||||
|
||||
/* copy character to be escaped */
|
||||
buf->ptr[buf->size] = *scan;
|
||||
buf->size++;
|
||||
scan++;
|
||||
|
||||
/* copy escape suffix sequence */
|
||||
if (esc_suffix) {
|
||||
memmove(buf->ptr + buf->size, esc_suffix, esc_suffix_len);
|
||||
buf->size += esc_suffix_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -268,21 +268,23 @@ int git_str_splice(
|
||||
* @param str String buffer to append data to
|
||||
* @param string String to escape and append
|
||||
* @param esc_chars Characters to be escaped
|
||||
* @param esc_with String to insert in from of each found character
|
||||
* @param esc_prefix String to insert as prefix of each found character
|
||||
* @param esc_suffix String to insert as suffix of each found character
|
||||
* @return 0 on success, <0 on failure (probably allocation problem)
|
||||
*/
|
||||
extern int git_str_puts_escaped(
|
||||
git_str *str,
|
||||
const char *string,
|
||||
const char *esc_chars,
|
||||
const char *esc_with);
|
||||
const char *esc_prefix,
|
||||
const char *esc_suffix);
|
||||
|
||||
/**
|
||||
* Append string escaping characters that are regex special
|
||||
*/
|
||||
GIT_INLINE(int) git_str_puts_escape_regex(git_str *str, const char *string)
|
||||
{
|
||||
return git_str_puts_escaped(str, string, "^.[]$()|*+?{}\\", "\\");
|
||||
return git_str_puts_escaped(str, string, "^.[]$()|*+?{}\\", "\\", NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -691,17 +691,33 @@ void test_gitstr__puts_escaped(void)
|
||||
git_str a = GIT_STR_INIT;
|
||||
|
||||
git_str_clear(&a);
|
||||
cl_git_pass(git_str_puts_escaped(&a, "this is a test", "", ""));
|
||||
cl_git_pass(git_str_puts_escaped(&a, "this is a test", "", "", ""));
|
||||
cl_assert_equal_s("this is a test", a.ptr);
|
||||
|
||||
git_str_clear(&a);
|
||||
cl_git_pass(git_str_puts_escaped(&a, "this is a test", "t", "\\"));
|
||||
cl_git_pass(git_str_puts_escaped(&a, "this is a test", "", NULL, NULL));
|
||||
cl_assert_equal_s("this is a test", a.ptr);
|
||||
|
||||
git_str_clear(&a);
|
||||
cl_git_pass(git_str_puts_escaped(&a, "this is a test", "t", "\\", ""));
|
||||
cl_assert_equal_s("\\this is a \\tes\\t", a.ptr);
|
||||
|
||||
git_str_clear(&a);
|
||||
cl_git_pass(git_str_puts_escaped(&a, "this is a test", "i ", "__"));
|
||||
cl_git_pass(git_str_puts_escaped(&a, "this is a test", "t", "\\", NULL));
|
||||
cl_assert_equal_s("\\this is a \\tes\\t", a.ptr);
|
||||
|
||||
git_str_clear(&a);
|
||||
cl_git_pass(git_str_puts_escaped(&a, "this is a test", "i ", "__", NULL));
|
||||
cl_assert_equal_s("th__is__ __is__ a__ test", a.ptr);
|
||||
|
||||
git_str_clear(&a);
|
||||
cl_git_pass(git_str_puts_escaped(&a, "this is a test", "i ", "__", "!!"));
|
||||
cl_assert_equal_s("th__i!!s__ !!__i!!s__ !!a__ !!test", a.ptr);
|
||||
|
||||
git_str_clear(&a);
|
||||
cl_git_pass(git_str_puts_escaped(&a, "this' is' an' escape! ", "'!", "'\\", "'"));
|
||||
cl_assert_equal_s("this'\\'' is'\\'' an'\\'' escape'\\!' ", a.ptr);
|
||||
|
||||
git_str_clear(&a);
|
||||
cl_git_pass(git_str_puts_escape_regex(&a, "^match\\s*[A-Z]+.*"));
|
||||
cl_assert_equal_s("\\^match\\\\s\\*\\[A-Z\\]\\+\\.\\*", a.ptr);
|
||||
|
||||
Reference in New Issue
Block a user