mirror of
https://github.com/libgit2/libgit2.git
synced 2026-01-25 02:56:17 +00:00
str: introduce git_str_shellquote
Introduce a helper method to quote a string in a shellsafe manner. This wraps the entire buffer in single quotes, escaping single-quotes and exclamation points.
This commit is contained in:
@@ -1415,3 +1415,40 @@ done:
|
||||
git_str_dispose(&replaced);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_str_shellquote(git_str *buf)
|
||||
{
|
||||
git_str quoted = GIT_STR_INIT;
|
||||
size_t i;
|
||||
int error = 0;
|
||||
|
||||
ENSURE_SIZE("ed, buf->size);
|
||||
|
||||
git_str_putc("ed, '\'');
|
||||
|
||||
for (i = 0; i < buf->size; i++) {
|
||||
switch (buf->ptr[i]) {
|
||||
case '\'':
|
||||
case '!':
|
||||
git_str_puts("ed, "'\\");
|
||||
git_str_putc("ed, buf->ptr[i]);
|
||||
git_str_putc("ed, '\'');
|
||||
break;
|
||||
default:
|
||||
git_str_putc("ed, buf->ptr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
git_str_putc("ed, '\'');
|
||||
|
||||
if (git_str_oom("ed)) {
|
||||
error = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
git_str_swap("ed, buf);
|
||||
|
||||
done:
|
||||
git_str_dispose("ed);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -366,4 +366,10 @@ int git_str_replace(
|
||||
const char *replacements[][2],
|
||||
size_t replacements_len);
|
||||
|
||||
/**
|
||||
* Quote for shell safety. Wrap the given buffer in single quotes,
|
||||
* escaping any single quotes and exclamation points.
|
||||
*/
|
||||
int git_str_shellquote(git_str *buf);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -64,3 +64,32 @@ void test_str_basic__replace(void)
|
||||
|
||||
git_str_dispose(&buf);
|
||||
}
|
||||
|
||||
void test_str_basic__shellquote(void)
|
||||
{
|
||||
git_str buf = GIT_BUF_INIT;
|
||||
|
||||
cl_git_pass(git_str_puts(&buf, "filename"));
|
||||
cl_git_pass(git_str_shellquote(&buf));
|
||||
cl_assert_equal_s("\'filename\'", buf.ptr);
|
||||
|
||||
git_str_clear(&buf);
|
||||
|
||||
cl_git_pass(git_str_puts(&buf, "file name"));
|
||||
cl_git_pass(git_str_shellquote(&buf));
|
||||
cl_assert_equal_s("\'file name\'", buf.ptr);
|
||||
|
||||
git_str_clear(&buf);
|
||||
|
||||
cl_git_pass(git_str_puts(&buf, "file\'name"));
|
||||
cl_git_pass(git_str_shellquote(&buf));
|
||||
cl_assert_equal_s("\'file\'\\\'\'name\'", buf.ptr);
|
||||
|
||||
git_str_clear(&buf);
|
||||
|
||||
cl_git_pass(git_str_puts(&buf, "file!name"));
|
||||
cl_git_pass(git_str_shellquote(&buf));
|
||||
cl_assert_equal_s("\'file\'\\!\'name\'", buf.ptr);
|
||||
|
||||
git_str_dispose(&buf);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user