Browse Source

Remove expansion of '%' #584.

The % is often used in urls and in case of the x-hint-command those are
feed to :shellcmd and will be replaced by current URL. This made the
x-hint-command unusable on some search engines.
The expansion of % to the current URL also required to give the current
browser state to the expansion logic and to feed it to all callers of
this too. This bloated the code.
This patch removes the % expansion which was a redundant alternative to
$VIMB_URI.
linenumbers
Daniel Carl 2 years ago
parent
commit
71693a23e9
  1. 5
      CHANGELOG.md
  2. 12
      src/ex.c
  3. 4
      src/main.c
  4. 24
      src/util.c
  5. 11
      src/util.h
  6. 74
      tests/test-util.c

5
CHANGELOG.md

@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Removed
* Expansion of `%` to the current opened URI for `:shellcmd` was removed
because it breaks the `x-hint-command` with URIs containing '%'. But it is
still possible to use `$VIMB_URI` for the `:shellcmd` which has the same
effect.
## [3.6.0] - 2020-01-02
### Added

12
src/ex.c

@ -127,7 +127,7 @@ static gboolean parse_count(const char **input, ExArg *arg);
static gboolean parse_command_name(Client *c, const char **input, ExArg *arg);
static gboolean parse_bang(const char **input, ExArg *arg);
static gboolean parse_lhs(const char **input, ExArg *arg);
static gboolean parse_rhs(Client *c, const char **input, ExArg *arg);
static gboolean parse_rhs(const char **input, ExArg *arg);
static void skip_whitespace(const char **input);
static void free_cmdarg(ExArg *arg);
static VbCmdResult execute(Client *c, const ExArg *arg);
@ -598,7 +598,7 @@ static gboolean parse(Client *c, const char **input, ExArg *arg, gboolean *nohis
}
/* parse the rhs if this is available */
skip_whitespace(input);
parse_rhs(c, input, arg);
parse_rhs(input, arg);
if (**input) {
(*input)++;
@ -731,7 +731,7 @@ static gboolean parse_lhs(const char **input, ExArg *arg)
* command can contain any char accept of the newline, else the right hand
* side end on the first none escaped | or newline.
*/
static gboolean parse_rhs(Client *c, const char **input, ExArg *arg)
static gboolean parse_rhs(const char **input, ExArg *arg)
{
int expflags, flags;
gboolean cmdlist;
@ -746,7 +746,7 @@ static gboolean parse_rhs(Client *c, const char **input, ExArg *arg)
cmdlist = (arg->flags & EX_FLAG_CMD) != 0;
expflags = (arg->flags & EX_FLAG_EXP)
? UTIL_EXP_TILDE|UTIL_EXP_DOLLAR|UTIL_EXP_SPECIAL
? UTIL_EXP_TILDE|UTIL_EXP_DOLLAR
: 0;
flags = expflags;
@ -754,7 +754,7 @@ static gboolean parse_rhs(Client *c, const char **input, ExArg *arg)
* EX_FLAG_CMD is not set also on | */
while (**input && **input != '\n' && (cmdlist || **input != '|')) {
/* check for expansion placeholder */
util_parse_expansion(c->state, input, arg->rhs, flags, "|\\");
util_parse_expansion(input, arg->rhs, flags, "|\\");
if (VB_IS_SEPARATOR(**input)) {
/* add tilde expansion for next loop needs to be first char or to
@ -1324,7 +1324,7 @@ static gboolean complete(Client *c, short direction)
case EX_SAVE: /* Fallthrough */
case EX_SOURCE:
found = util_filename_fill_completion(c->state, store, token);
found = util_filename_fill_completion(store, token);
break;
#ifdef FEATURE_AUTOCMD

4
src/main.c

@ -147,7 +147,7 @@ gboolean vb_download_set_destination(Client *c, WebKitDownload *download,
/* Prepare the path to save the download. */
if (path && *path) {
file = util_build_path(c->state, path, download_path);
file = util_build_path(path, download_path);
/* if file is an directory append a file name */
if (g_file_test(file, (G_FILE_TEST_IS_DIR))) {
@ -156,7 +156,7 @@ gboolean vb_download_set_destination(Client *c, WebKitDownload *download,
g_free(dir);
}
} else {
file = util_build_path(c->state, suggested_filename, download_path);
file = util_build_path(suggested_filename, download_path);
}
g_free(basename);

24
src/util.c

@ -48,13 +48,13 @@ static gboolean match_list(const char *pattern, int patlen, const char *subject)
*
* Returned path must be freed.
*/
char *util_build_path(State state, const char *path, const char *dir)
char *util_build_path(const char *path, const char *dir)
{
char *fullPath = NULL, *fexp, *dexp, *p;
int expflags = UTIL_EXP_TILDE|UTIL_EXP_DOLLAR;
/* if the path could be expanded */
if ((fexp = util_expand(state, path, expflags))) {
if ((fexp = util_expand(path, expflags))) {
if (*fexp == '/') {
/* path is already absolute, no need to use given dir - there is
* no need to free fexp, because this should be done by the caller
@ -62,7 +62,7 @@ char *util_build_path(State state, const char *path, const char *dir)
fullPath = fexp;
} else if (dir && *dir) {
/* try to expand also the dir given - this may be ~/path */
if ((dexp = util_expand(state, dir, expflags))) {
if ((dexp = util_expand(dir, expflags))) {
/* use expanded dir and append expanded path */
fullPath = g_build_filename(dexp, fexp, NULL);
g_free(dexp);
@ -161,7 +161,7 @@ gboolean util_create_tmp_file(const char *content, char **file)
*
* Returned path must be g_freed.
*/
char *util_expand(State state, const char *src, int expflags)
char *util_expand(const char *src, int expflags)
{
const char **input = &src;
char *result;
@ -169,7 +169,7 @@ char *util_expand(State state, const char *src, int expflags)
int flags = expflags;
while (**input) {
util_parse_expansion(state, input, dst, flags, "\\");
util_parse_expansion(input, dst, flags, "\\");
if (VB_IS_SEPARATOR(**input)) {
/* after space the tilde expansion is allowed */
flags = expflags;
@ -556,7 +556,7 @@ gboolean util_fill_completion(GtkListStore *store, const char *input, GList *src
* Fills file path completion entries into given list store for also given
* input.
*/
gboolean util_filename_fill_completion(State state, GtkListStore *store, const char *input)
gboolean util_filename_fill_completion(GtkListStore *store, const char *input)
{
gboolean found = FALSE;
GError *error = NULL;
@ -568,9 +568,8 @@ gboolean util_filename_fill_completion(State state, GtkListStore *store, const c
input_basename = last_slash ? last_slash + 1 : input;
input_dirname = g_strndup(input, input_basename - input);
real_dirname = util_expand(
state,
*input_dirname ? input_dirname : ".",
UTIL_EXP_TILDE|UTIL_EXP_DOLLAR|UTIL_EXP_SPECIAL
UTIL_EXP_TILDE|UTIL_EXP_DOLLAR
);
dir = g_dir_open(real_dirname, 0, &error);
@ -655,7 +654,7 @@ double util_js_result_as_number(WebKitJavascriptResult *result)
* @quoteable: String of chars that are additionally escapable by \.
* Returns TRUE if input started with expandable pattern.
*/
gboolean util_parse_expansion(State state, const char **input, GString *str,
gboolean util_parse_expansion(const char **input, GString *str,
int flags, const char *quoteable)
{
GString *name;
@ -729,12 +728,6 @@ gboolean util_parse_expansion(State state, const char **input, GString *str,
/* variable are expanded even if they do not exists */
expanded = TRUE;
g_string_free(name, TRUE);
} else if (flags & UTIL_EXP_SPECIAL && **input == '%') {
if (state.uri) {
/* TODO check for modifiers like :h:t:r:e */
g_string_append(str, state.uri);
expanded = TRUE;
}
}
if (!expanded) {
@ -752,7 +745,6 @@ gboolean util_parse_expansion(State state, const char **input, GString *str,
} else if (strchr(quoteable, **input)
|| (flags & UTIL_EXP_TILDE && **input == '~')
|| (flags & UTIL_EXP_DOLLAR && **input == '$')
|| (flags & UTIL_EXP_SPECIAL && **input == '%')
) {
/* escaped char becomes only char */
g_string_append_c(str, **input);

11
src/util.h

@ -26,15 +26,14 @@
enum {
UTIL_EXP_TILDE = 0x01, /* ~/ and ~user expansion */
UTIL_EXP_DOLLAR = 0x02, /* $ENV and ${ENV} expansion */
UTIL_EXP_SPECIAL = 0x04, /* expand % to current URI */
};
typedef void *(*Util_Content_Func)(const char*, const char*);
char *util_build_path(State state, const char *path, const char *dir);
char *util_build_path(const char *path, const char *dir);
void util_cleanup(void);
gboolean util_create_dir_if_not_exists(const char *dirpath);
gboolean util_create_tmp_file(const char *content, char **file);
char *util_expand(State state, const char *src, int expflags);
char *util_expand(const char *src, int expflags);
gboolean util_file_append(const char *file, const char *format, ...);
gboolean util_file_prepend(const char *file, const char *format, ...);
void util_file_prepend_line(const char *file, const char *line,
@ -47,11 +46,11 @@ char **util_get_lines(const char *filename);
GList *util_strv_to_unique_list(char **lines, Util_Content_Func func,
guint max_items);
gboolean util_fill_completion(GtkListStore *store, const char *input, GList *src);
gboolean util_filename_fill_completion(State state, GtkListStore *store, const char *input);
gboolean util_filename_fill_completion(GtkListStore *store, const char *input);
char *util_js_result_as_string(WebKitJavascriptResult *result);
double util_js_result_as_number(WebKitJavascriptResult *result);
gboolean util_parse_expansion(State state, const char **input, GString *str,
int flags, const char *quoteable);
gboolean util_parse_expansion(const char **input, GString *str, int flags,
const char *quoteable);
char *util_sanitize_filename(char *filename);
char *util_sanitize_uri(const char *uri_str);
char *util_strcasestr(const char *haystack, const char *needle);

74
tests/test-util.c

@ -21,74 +21,69 @@
#include <gtk/gtk.h>
#include <src/util.h>
static void check_expand(State state, const char *str, const char *expected)
static void check_expand(const char *str, const char *expected)
{
char *result = util_expand(state, str, UTIL_EXP_DOLLAR|UTIL_EXP_TILDE|UTIL_EXP_SPECIAL);
char *result = util_expand(str, UTIL_EXP_DOLLAR|UTIL_EXP_TILDE);
g_assert_cmpstr(result, ==, expected);
g_free(result);
}
static void test_expand_evn(void)
{
State state = {0};
/* set environment var for testing expansion */
g_setenv("VIMB_VAR", "value", true);
check_expand(state, "$VIMB_VAR", "value");
check_expand(state, "$VIMB_VAR", "value");
check_expand(state, "$VIMB_VAR$VIMB_VAR", "valuevalue");
check_expand(state, "${VIMB_VAR}", "value");
check_expand(state, "my$VIMB_VAR", "myvalue");
check_expand(state, "'$VIMB_VAR'", "'value'");
check_expand(state, "${VIMB_VAR}s ", "values ");
check_expand("$VIMB_VAR", "value");
check_expand("$VIMB_VAR", "value");
check_expand("$VIMB_VAR$VIMB_VAR", "valuevalue");
check_expand("${VIMB_VAR}", "value");
check_expand("my$VIMB_VAR", "myvalue");
check_expand("'$VIMB_VAR'", "'value'");
check_expand("${VIMB_VAR}s ", "values ");
g_unsetenv("UNKNOWN");
check_expand(state, "$UNKNOWN", "");
check_expand(state, "${UNKNOWN}", "");
check_expand(state, "'$UNKNOWN'", "''");
check_expand("$UNKNOWN", "");
check_expand("${UNKNOWN}", "");
check_expand("'$UNKNOWN'", "''");
}
static void test_expand_escaped(void)
{
State state = {0};
g_setenv("VIMB_VAR", "value", true);
check_expand(state, "\\$VIMB_VAR", "$VIMB_VAR");
check_expand(state, "\\${VIMB_VAR}", "${VIMB_VAR}");
check_expand(state, "\\~/", "~/");
check_expand(state, "\\~/vimb", "~/vimb");
check_expand(state, "\\~root", "~root");
check_expand(state, "\\%", "%");
check_expand(state, "\\\\$VIMB_VAR", "\\value"); /* \\$VAR becomes \ExpandedVar */
check_expand(state, "\\\\\\$VIMB_VAR", "\\$VIMB_VAR"); /* \\\$VAR becomes \$VAR */
check_expand("\\$VIMB_VAR", "$VIMB_VAR");
check_expand("\\${VIMB_VAR}", "${VIMB_VAR}");
check_expand("\\~/", "~/");
check_expand("\\~/vimb", "~/vimb");
check_expand("\\~root", "~root");
check_expand("\\\\$VIMB_VAR", "\\value"); /* \\$VAR becomes \ExpandedVar */
check_expand("\\\\\\$VIMB_VAR", "\\$VIMB_VAR"); /* \\\$VAR becomes \$VAR */
}
static void test_expand_tilde_home(void)
{
State state = {0};
char *dir;
const char *home = g_get_home_dir();
check_expand(state, "~", "~");
check_expand(state, "~/", home);
check_expand(state, "foo~/bar", "foo~/bar");
check_expand(state, "~/foo", (dir = g_strdup_printf("%s/foo", home)));
check_expand("~", "~");
check_expand("~/", home);
check_expand("foo~/bar", "foo~/bar");
check_expand("~/foo", (dir = g_strdup_printf("%s/foo", home)));
g_free(dir);
check_expand(state, "foo ~/bar", (dir = g_strdup_printf("foo %s/bar", home)));
check_expand("foo ~/bar", (dir = g_strdup_printf("foo %s/bar", home)));
g_free(dir);
check_expand(state, "~/~", (dir = g_strdup_printf("%s/~", home)));
check_expand("~/~", (dir = g_strdup_printf("%s/~", home)));
g_free(dir);
check_expand(state, "~/~/", (dir = g_strdup_printf("%s/~/", home)));
check_expand("~/~/", (dir = g_strdup_printf("%s/~/", home)));
g_free(dir);
}
static void test_expand_tilde_user(void)
{
State state = {0};
const char *user = g_get_user_name();
const char *home;
char *in, *out;
@ -101,29 +96,21 @@ static void test_expand_tilde_user(void)
/* don't expand within words */
in = g_strdup_printf("foo~%s/bar", user);
check_expand(state, in, in);
check_expand(in, in);
g_free(in);
check_expand(state, (in = g_strdup_printf("foo ~%s", user)), (out = g_strdup_printf("foo %s", home)));
check_expand((in = g_strdup_printf("foo ~%s", user)), (out = g_strdup_printf("foo %s", home)));
g_free(in);
g_free(out);
check_expand(state, (in = g_strdup_printf("~%s", user)), home);
check_expand((in = g_strdup_printf("~%s", user)), home);
g_free(in);
check_expand(state, (in = g_strdup_printf("~%s/bar", user)), (out = g_strdup_printf("%s/bar", home)));
check_expand((in = g_strdup_printf("~%s/bar", user)), (out = g_strdup_printf("%s/bar", home)));
g_free(in);
g_free(out);
}
static void test_expand_speacial(void)
{
State state = {.uri = "http://fanglingsu.github.io/vimb/"};
check_expand(state, "%", "http://fanglingsu.github.io/vimb/");
check_expand(state, "'%'", "'http://fanglingsu.github.io/vimb/'");
}
static void test_strcasestr(void)
{
g_assert_nonnull(util_strcasestr("Vim like Browser", "browser"));
@ -332,7 +319,6 @@ int main(int argc, char *argv[])
g_test_add_func("/test-util/expand-escaped", test_expand_escaped);
g_test_add_func("/test-util/expand-tilde-home", test_expand_tilde_home);
g_test_add_func("/test-util/expand-tilde-user", test_expand_tilde_user);
g_test_add_func("/test-util/expand-spacial", test_expand_speacial);
g_test_add_func("/test-util/strcasestr", test_strcasestr);
g_test_add_func("/test-util/str_replace", test_str_replace);
g_test_add_func("/test-util/wildmatch-simple", test_wildmatch_simple);

Loading…
Cancel
Save