summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrian m. carlson <sandals@crustytoothpaste.net>2020-07-21 01:15:11 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-07-21 04:05:16 (GMT)
commitcd85b447bfc09ddfab660048883de6a07d893097 (patch)
treeebdf948039d52261f1bf8c36a389f9dbb4840b46
parent274b9cc25322d9ee79aa8e6d4e86f0ffe5ced925 (diff)
downloadgit-cd85b447bfc09ddfab660048883de6a07d893097.zip
git-cd85b447bfc09ddfab660048883de6a07d893097.tar.gz
git-cd85b447bfc09ddfab660048883de6a07d893097.tar.bz2
remote-curl: make --force-with-lease work with non-ASCII ref names
When we invoke a remote transport helper and pass an option with an argument, we quote the argument as a C-style string if necessary. This is the case for the cas option, which implements the --force-with-lease command-line flag, when we're passing a non-ASCII refname. However, the remote curl helper isn't designed to parse such an argument, meaning that if we try to use --force-with-lease with an HTTP push and a non-ASCII refname, we get an error like this: error: cannot parse expected object name '0000000000000000000000000000000000000000"' Note the double quote, which get_oid has reminded us is not valid in an hex object ID. Even if we had been able to parse it, we would send the wrong data to the server: we'd send an escaped ref, which would not behave as the user wanted and might accidentally result in updating or deleting a ref we hadn't intended. Since we need to expect a quoted C-style string here, just check if the first argument is a double quote, and if so, unquote it. Note that if the refname contains a double quote, then we will have double-quoted it already, so there is no ambiguity. We test for this case only in the smart protocol, since the DAV-based protocol is not capable of handling this capability. We use UTF-8 because this is nicer in our tests and friendlier to Windows, but the code should work for all non-ASCII refs. While we're at it, since the name of the option is now well established and isn't going to change, let's inline it instead of using the #define constant. Reported-by: Frej Bjon <frej.bjon@nemit.fi> Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--remote-curl.c6
-rwxr-xr-xt/t5541-http-push-smart.sh15
2 files changed, 20 insertions, 1 deletions
diff --git a/remote-curl.c b/remote-curl.c
index e4cd321..0b331fa 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -119,7 +119,11 @@ static int set_option(const char *name, const char *value)
}
else if (!strcmp(name, "cas")) {
struct strbuf val = STRBUF_INIT;
- strbuf_addf(&val, "--" CAS_OPT_NAME "=%s", value);
+ strbuf_addstr(&val, "--force-with-lease=");
+ if (*value != '"')
+ strbuf_addstr(&val, value);
+ else if (unquote_c_style(&val, value, NULL))
+ return -1;
string_list_append(&cas_options, val.buf);
strbuf_release(&val);
return 0;
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 23be8ce..26c28ce 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -456,6 +456,21 @@ test_expect_success 'push status output scrubs password' '
grep "^To $HTTPD_URL/smart/test_repo.git" status
'
+test_expect_success 'Non-ASCII branch name can be used with --force-with-lease' '
+ cd "$ROOT_PATH" &&
+ git clone "$HTTPD_URL_USER_PASS/smart/test_repo.git" non-ascii &&
+ cd non-ascii &&
+ git checkout -b rama-de-árbol &&
+ test_commit F &&
+ git push --force-with-lease origin rama-de-árbol &&
+ git ls-remote origin refs/heads/rama-de-árbol >actual &&
+ git ls-remote . refs/heads/rama-de-árbol >expect &&
+ test_cmp expect actual &&
+ git push --delete --force-with-lease origin rama-de-árbol &&
+ git ls-remote origin refs/heads/rama-de-árbol >actual &&
+ test_must_be_empty actual
+'
+
test_expect_success 'colorize errors/hints' '
cd "$ROOT_PATH"/test_repo_clone &&
test_must_fail git -c color.transport=always -c color.advice=always \