Merge branch 'jk/protocol-cap-parse-fix'
The code to parse capability list for v0 on-wire protocol fell into an infinite loop when a capability appears multiple times, which has been corrected. * jk/protocol-cap-parse-fix: v0 protocol: use size_t for capability length/offset t5512: test "ls-remote --heads --symref" filtering with v0 and v2 t5512: allow any protocol version for filtered symref test t5512: add v2 support for "ls-remote --symref" test v0 protocol: fix sha1/sha256 confusion for capabilities^{} t5512: stop referring to "v1" protocol v0 protocol: fix infinite loop when parsing multi-valued capabilities
This commit is contained in:
commit
80d268f309
@ -2096,7 +2096,7 @@ static struct command *read_head_info(struct packet_reader *reader,
|
|||||||
const char *feature_list = reader->line + linelen + 1;
|
const char *feature_list = reader->line + linelen + 1;
|
||||||
const char *hash = NULL;
|
const char *hash = NULL;
|
||||||
const char *client_sid;
|
const char *client_sid;
|
||||||
int len = 0;
|
size_t len = 0;
|
||||||
if (parse_feature_request(feature_list, "report-status"))
|
if (parse_feature_request(feature_list, "report-status"))
|
||||||
report_status = 1;
|
report_status = 1;
|
||||||
if (parse_feature_request(feature_list, "report-status-v2"))
|
if (parse_feature_request(feature_list, "report-status-v2"))
|
||||||
|
30
connect.c
30
connect.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
static char *server_capabilities_v1;
|
static char *server_capabilities_v1;
|
||||||
static struct strvec server_capabilities_v2 = STRVEC_INIT;
|
static struct strvec server_capabilities_v2 = STRVEC_INIT;
|
||||||
static const char *next_server_feature_value(const char *feature, int *len, int *offset);
|
static const char *next_server_feature_value(const char *feature, size_t *len, size_t *offset);
|
||||||
|
|
||||||
static int check_ref(const char *name, unsigned int flags)
|
static int check_ref(const char *name, unsigned int flags)
|
||||||
{
|
{
|
||||||
@ -205,10 +205,10 @@ reject:
|
|||||||
static void annotate_refs_with_symref_info(struct ref *ref)
|
static void annotate_refs_with_symref_info(struct ref *ref)
|
||||||
{
|
{
|
||||||
struct string_list symref = STRING_LIST_INIT_DUP;
|
struct string_list symref = STRING_LIST_INIT_DUP;
|
||||||
int offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int len;
|
size_t len;
|
||||||
const char *val;
|
const char *val;
|
||||||
|
|
||||||
val = next_server_feature_value("symref", &len, &offset);
|
val = next_server_feature_value("symref", &len, &offset);
|
||||||
@ -231,7 +231,7 @@ static void annotate_refs_with_symref_info(struct ref *ref)
|
|||||||
static void process_capabilities(struct packet_reader *reader, int *linelen)
|
static void process_capabilities(struct packet_reader *reader, int *linelen)
|
||||||
{
|
{
|
||||||
const char *feat_val;
|
const char *feat_val;
|
||||||
int feat_len;
|
size_t feat_len;
|
||||||
const char *line = reader->line;
|
const char *line = reader->line;
|
||||||
int nul_location = strlen(line);
|
int nul_location = strlen(line);
|
||||||
if (nul_location == *linelen)
|
if (nul_location == *linelen)
|
||||||
@ -263,7 +263,8 @@ static int process_dummy_ref(const struct packet_reader *reader)
|
|||||||
return 0;
|
return 0;
|
||||||
name++;
|
name++;
|
||||||
|
|
||||||
return oideq(null_oid(), &oid) && !strcmp(name, "capabilities^{}");
|
return oideq(reader->hash_algo->null_oid, &oid) &&
|
||||||
|
!strcmp(name, "capabilities^{}");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_no_capabilities(const char *line, int len)
|
static void check_no_capabilities(const char *line, int len)
|
||||||
@ -595,9 +596,10 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp, int *offset)
|
const char *parse_feature_value(const char *feature_list, const char *feature, size_t *lenp, size_t *offset)
|
||||||
{
|
{
|
||||||
int len;
|
const char *orig_start = feature_list;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
if (!feature_list)
|
if (!feature_list)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -616,19 +618,19 @@ const char *parse_feature_value(const char *feature_list, const char *feature, i
|
|||||||
if (lenp)
|
if (lenp)
|
||||||
*lenp = 0;
|
*lenp = 0;
|
||||||
if (offset)
|
if (offset)
|
||||||
*offset = found + len - feature_list;
|
*offset = found + len - orig_start;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
/* feature with a value (e.g., "agent=git/1.2.3") */
|
/* feature with a value (e.g., "agent=git/1.2.3") */
|
||||||
else if (*value == '=') {
|
else if (*value == '=') {
|
||||||
int end;
|
size_t end;
|
||||||
|
|
||||||
value++;
|
value++;
|
||||||
end = strcspn(value, " \t\n");
|
end = strcspn(value, " \t\n");
|
||||||
if (lenp)
|
if (lenp)
|
||||||
*lenp = end;
|
*lenp = end;
|
||||||
if (offset)
|
if (offset)
|
||||||
*offset = value + end - feature_list;
|
*offset = value + end - orig_start;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -643,8 +645,8 @@ const char *parse_feature_value(const char *feature_list, const char *feature, i
|
|||||||
|
|
||||||
int server_supports_hash(const char *desired, int *feature_supported)
|
int server_supports_hash(const char *desired, int *feature_supported)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
size_t offset = 0;
|
||||||
int len;
|
size_t len;
|
||||||
const char *hash;
|
const char *hash;
|
||||||
|
|
||||||
hash = next_server_feature_value("object-format", &len, &offset);
|
hash = next_server_feature_value("object-format", &len, &offset);
|
||||||
@ -668,12 +670,12 @@ int parse_feature_request(const char *feature_list, const char *feature)
|
|||||||
return !!parse_feature_value(feature_list, feature, NULL, NULL);
|
return !!parse_feature_value(feature_list, feature, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *next_server_feature_value(const char *feature, int *len, int *offset)
|
static const char *next_server_feature_value(const char *feature, size_t *len, size_t *offset)
|
||||||
{
|
{
|
||||||
return parse_feature_value(server_capabilities_v1, feature, len, offset);
|
return parse_feature_value(server_capabilities_v1, feature, len, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *server_feature_value(const char *feature, int *len)
|
const char *server_feature_value(const char *feature, size_t *len)
|
||||||
{
|
{
|
||||||
return parse_feature_value(server_capabilities_v1, feature, len, NULL);
|
return parse_feature_value(server_capabilities_v1, feature, len, NULL);
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,14 @@ int finish_connect(struct child_process *conn);
|
|||||||
int git_connection_is_socket(struct child_process *conn);
|
int git_connection_is_socket(struct child_process *conn);
|
||||||
int server_supports(const char *feature);
|
int server_supports(const char *feature);
|
||||||
int parse_feature_request(const char *features, const char *feature);
|
int parse_feature_request(const char *features, const char *feature);
|
||||||
const char *server_feature_value(const char *feature, int *len_ret);
|
const char *server_feature_value(const char *feature, size_t *len_ret);
|
||||||
int url_is_local_not_ssh(const char *url);
|
int url_is_local_not_ssh(const char *url);
|
||||||
|
|
||||||
struct packet_reader;
|
struct packet_reader;
|
||||||
enum protocol_version discover_version(struct packet_reader *reader);
|
enum protocol_version discover_version(struct packet_reader *reader);
|
||||||
|
|
||||||
int server_supports_hash(const char *desired, int *feature_supported);
|
int server_supports_hash(const char *desired, int *feature_supported);
|
||||||
const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp, int *offset);
|
const char *parse_feature_value(const char *feature_list, const char *feature, size_t *lenp, size_t *offset);
|
||||||
int server_supports_v2(const char *c);
|
int server_supports_v2(const char *c);
|
||||||
void ensure_server_supports_v2(const char *c);
|
void ensure_server_supports_v2(const char *c);
|
||||||
int server_feature_v2(const char *c, const char **v);
|
int server_feature_v2(const char *c, const char **v);
|
||||||
|
@ -1100,7 +1100,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
|||||||
struct ref *ref = copy_ref_list(orig_ref);
|
struct ref *ref = copy_ref_list(orig_ref);
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
const char *agent_feature;
|
const char *agent_feature;
|
||||||
int agent_len;
|
size_t agent_len;
|
||||||
struct fetch_negotiator negotiator_alloc;
|
struct fetch_negotiator negotiator_alloc;
|
||||||
struct fetch_negotiator *negotiator;
|
struct fetch_negotiator *negotiator;
|
||||||
|
|
||||||
@ -1118,7 +1118,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
|
|||||||
agent_supported = 1;
|
agent_supported = 1;
|
||||||
if (agent_len)
|
if (agent_len)
|
||||||
print_verbose(args, _("Server version is %.*s"),
|
print_verbose(args, _("Server version is %.*s"),
|
||||||
agent_len, agent_feature);
|
(int)agent_len, agent_feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!server_supports("session-id"))
|
if (!server_supports("session-id"))
|
||||||
|
@ -539,7 +539,7 @@ int send_pack(struct send_pack_args *args,
|
|||||||
die(_("the receiving end does not support this repository's hash algorithm"));
|
die(_("the receiving end does not support this repository's hash algorithm"));
|
||||||
|
|
||||||
if (args->push_cert != SEND_PACK_PUSH_CERT_NEVER) {
|
if (args->push_cert != SEND_PACK_PUSH_CERT_NEVER) {
|
||||||
int len;
|
size_t len;
|
||||||
push_cert_nonce = server_feature_value("push-cert", &len);
|
push_cert_nonce = server_feature_value("push-cert", &len);
|
||||||
if (push_cert_nonce) {
|
if (push_cert_nonce) {
|
||||||
reject_invalid_nonce(push_cert_nonce, len);
|
reject_invalid_nonce(push_cert_nonce, len);
|
||||||
|
@ -15,6 +15,19 @@ generate_references () {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_expect_success 'set up fake upload-pack' '
|
||||||
|
# This can be used to simulate an upload-pack that just shows the
|
||||||
|
# contents of the "input" file (prepared with the test-tool pkt-line
|
||||||
|
# helper), and does not do any negotiation (since ls-remote does not
|
||||||
|
# need it).
|
||||||
|
write_script cat-input <<-\EOF
|
||||||
|
# send our initial advertisement/response
|
||||||
|
cat input
|
||||||
|
# soak up the flush packet from the client
|
||||||
|
cat
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'dies when no remote found' '
|
test_expect_success 'dies when no remote found' '
|
||||||
test_must_fail git ls-remote
|
test_must_fail git ls-remote
|
||||||
'
|
'
|
||||||
@ -231,22 +244,25 @@ test_expect_success 'protocol v2 supports hiderefs' '
|
|||||||
|
|
||||||
test_expect_success 'ls-remote --symref' '
|
test_expect_success 'ls-remote --symref' '
|
||||||
git fetch origin &&
|
git fetch origin &&
|
||||||
echo "ref: refs/heads/main HEAD" >expect &&
|
echo "ref: refs/heads/main HEAD" >expect.v2 &&
|
||||||
generate_references \
|
generate_references \
|
||||||
HEAD \
|
HEAD \
|
||||||
refs/heads/main >>expect &&
|
refs/heads/main >>expect.v2 &&
|
||||||
|
echo "ref: refs/remotes/origin/main refs/remotes/origin/HEAD" >>expect.v2 &&
|
||||||
oid=$(git rev-parse HEAD) &&
|
oid=$(git rev-parse HEAD) &&
|
||||||
echo "$oid refs/remotes/origin/HEAD" >>expect &&
|
echo "$oid refs/remotes/origin/HEAD" >>expect.v2 &&
|
||||||
generate_references \
|
generate_references \
|
||||||
refs/remotes/origin/main \
|
refs/remotes/origin/main \
|
||||||
refs/tags/mark \
|
refs/tags/mark \
|
||||||
refs/tags/mark1.1 \
|
refs/tags/mark1.1 \
|
||||||
refs/tags/mark1.10 \
|
refs/tags/mark1.10 \
|
||||||
refs/tags/mark1.2 >>expect &&
|
refs/tags/mark1.2 >>expect.v2 &&
|
||||||
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
|
# v0 does not show non-HEAD symrefs
|
||||||
# protocol v0 here.
|
grep -v "ref: refs/remotes" <expect.v2 >expect.v0 &&
|
||||||
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref >actual &&
|
git -c protocol.version=0 ls-remote --symref >actual.v0 &&
|
||||||
test_cmp expect actual
|
test_cmp expect.v0 actual.v0 &&
|
||||||
|
git -c protocol.version=2 ls-remote --symref >actual.v2 &&
|
||||||
|
test_cmp expect.v2 actual.v2
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'ls-remote with filtered symref (refname)' '
|
test_expect_success 'ls-remote with filtered symref (refname)' '
|
||||||
@ -255,76 +271,41 @@ test_expect_success 'ls-remote with filtered symref (refname)' '
|
|||||||
ref: refs/heads/main HEAD
|
ref: refs/heads/main HEAD
|
||||||
$rev HEAD
|
$rev HEAD
|
||||||
EOF
|
EOF
|
||||||
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
|
git ls-remote --symref . HEAD >actual &&
|
||||||
# protocol v0 here.
|
|
||||||
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . HEAD >actual &&
|
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_failure 'ls-remote with filtered symref (--heads)' '
|
test_expect_success 'ls-remote with filtered symref (--heads)' '
|
||||||
git symbolic-ref refs/heads/foo refs/tags/mark &&
|
git symbolic-ref refs/heads/foo refs/tags/mark &&
|
||||||
cat >expect <<-EOF &&
|
cat >expect.v2 <<-EOF &&
|
||||||
ref: refs/tags/mark refs/heads/foo
|
ref: refs/tags/mark refs/heads/foo
|
||||||
$rev refs/heads/foo
|
$rev refs/heads/foo
|
||||||
$rev refs/heads/main
|
$rev refs/heads/main
|
||||||
EOF
|
EOF
|
||||||
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
|
grep -v "^ref: refs/tags/" <expect.v2 >expect.v0 &&
|
||||||
# protocol v0 here.
|
git -c protocol.version=0 ls-remote --symref --heads . >actual.v0 &&
|
||||||
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
|
test_cmp expect.v0 actual.v0 &&
|
||||||
test_cmp expect actual
|
git -c protocol.version=2 ls-remote --symref --heads . >actual.v2 &&
|
||||||
|
test_cmp expect.v2 actual.v2
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'ls-remote --symref omits filtered-out matches' '
|
test_expect_success 'indicate no refs in v0 standards-compliant empty remote' '
|
||||||
cat >expect <<-EOF &&
|
# Git does not produce an output like this, but it does match the
|
||||||
$rev refs/heads/foo
|
# standard and is produced by other implementations like JGit. So
|
||||||
$rev refs/heads/main
|
# hard-code the case we care about.
|
||||||
|
#
|
||||||
|
# The actual capabilities do not matter; there are none that would
|
||||||
|
# change how ls-remote behaves.
|
||||||
|
oid=0000000000000000000000000000000000000000 &&
|
||||||
|
test-tool pkt-line pack >input.q <<-EOF &&
|
||||||
|
$oid capabilities^{}Qcaps-go-here
|
||||||
|
0000
|
||||||
EOF
|
EOF
|
||||||
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
|
q_to_nul <input.q >input &&
|
||||||
# protocol v0 here.
|
|
||||||
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
|
|
||||||
test_cmp expect actual &&
|
|
||||||
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . "refs/heads/*" >actual &&
|
|
||||||
test_cmp expect actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_lazy_prereq GIT_DAEMON '
|
|
||||||
test_bool_env GIT_TEST_GIT_DAEMON true
|
|
||||||
'
|
|
||||||
|
|
||||||
# This test spawns a daemon, so run it only if the user would be OK with
|
|
||||||
# testing with git-daemon.
|
|
||||||
test_expect_success PIPE,JGIT,GIT_DAEMON 'indicate no refs in standards-compliant empty remote' '
|
|
||||||
test_set_port JGIT_DAEMON_PORT &&
|
|
||||||
JGIT_DAEMON_PID= &&
|
|
||||||
git init --bare empty.git &&
|
|
||||||
>empty.git/git-daemon-export-ok &&
|
|
||||||
mkfifo jgit_daemon_output &&
|
|
||||||
{
|
|
||||||
jgit daemon --port="$JGIT_DAEMON_PORT" . >jgit_daemon_output &
|
|
||||||
JGIT_DAEMON_PID=$!
|
|
||||||
} &&
|
|
||||||
test_when_finished kill "$JGIT_DAEMON_PID" &&
|
|
||||||
{
|
|
||||||
read line &&
|
|
||||||
case $line in
|
|
||||||
Exporting*)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Expected: Exporting" &&
|
|
||||||
false;;
|
|
||||||
esac &&
|
|
||||||
read line &&
|
|
||||||
case $line in
|
|
||||||
"Listening on"*)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Expected: Listening on" &&
|
|
||||||
false;;
|
|
||||||
esac
|
|
||||||
} <jgit_daemon_output &&
|
|
||||||
# --exit-code asks the command to exit with 2 when no
|
# --exit-code asks the command to exit with 2 when no
|
||||||
# matching refs are found.
|
# matching refs are found.
|
||||||
test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git
|
test_expect_code 2 git ls-remote --exit-code --upload-pack=./cat-input .
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'ls-remote works outside repository' '
|
test_expect_success 'ls-remote works outside repository' '
|
||||||
@ -345,8 +326,8 @@ test_expect_success 'ls-remote --sort fails gracefully outside repository' '
|
|||||||
test_expect_success 'ls-remote patterns work with all protocol versions' '
|
test_expect_success 'ls-remote patterns work with all protocol versions' '
|
||||||
git for-each-ref --format="%(objectname) %(refname)" \
|
git for-each-ref --format="%(objectname) %(refname)" \
|
||||||
refs/heads/main refs/remotes/origin/main >expect &&
|
refs/heads/main refs/remotes/origin/main >expect &&
|
||||||
git -c protocol.version=1 ls-remote . main >actual.v1 &&
|
git -c protocol.version=0 ls-remote . main >actual.v0 &&
|
||||||
test_cmp expect actual.v1 &&
|
test_cmp expect actual.v0 &&
|
||||||
git -c protocol.version=2 ls-remote . main >actual.v2 &&
|
git -c protocol.version=2 ls-remote . main >actual.v2 &&
|
||||||
test_cmp expect actual.v2
|
test_cmp expect actual.v2
|
||||||
'
|
'
|
||||||
@ -354,10 +335,49 @@ test_expect_success 'ls-remote patterns work with all protocol versions' '
|
|||||||
test_expect_success 'ls-remote prefixes work with all protocol versions' '
|
test_expect_success 'ls-remote prefixes work with all protocol versions' '
|
||||||
git for-each-ref --format="%(objectname) %(refname)" \
|
git for-each-ref --format="%(objectname) %(refname)" \
|
||||||
refs/heads/ refs/tags/ >expect &&
|
refs/heads/ refs/tags/ >expect &&
|
||||||
git -c protocol.version=1 ls-remote --heads --tags . >actual.v1 &&
|
git -c protocol.version=0 ls-remote --heads --tags . >actual.v0 &&
|
||||||
test_cmp expect actual.v1 &&
|
test_cmp expect actual.v0 &&
|
||||||
git -c protocol.version=2 ls-remote --heads --tags . >actual.v2 &&
|
git -c protocol.version=2 ls-remote --heads --tags . >actual.v2 &&
|
||||||
test_cmp expect actual.v2
|
test_cmp expect actual.v2
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'v0 clients can handle multiple symrefs' '
|
||||||
|
# Modern versions of Git will not return multiple symref capabilities
|
||||||
|
# for v0, so we have to hard-code the response. Note that we will
|
||||||
|
# always use both v0 and object-format=sha1 here, as the hard-coded
|
||||||
|
# response reflects a server that only supports those.
|
||||||
|
oid=1234567890123456789012345678901234567890 &&
|
||||||
|
symrefs="symref=refs/remotes/origin/HEAD:refs/remotes/origin/main" &&
|
||||||
|
symrefs="$symrefs symref=HEAD:refs/heads/main" &&
|
||||||
|
|
||||||
|
# Likewise we want to make sure our parser is not fooled by the string
|
||||||
|
# "symref" appearing as part of an earlier cap. But there is no way to
|
||||||
|
# do that via upload-pack, as arbitrary strings can appear only in a
|
||||||
|
# "symref" value itself (where we skip past the values as a whole)
|
||||||
|
# and "agent" (which always appears after "symref", so putting our
|
||||||
|
# parser in a confused state is less interesting).
|
||||||
|
caps="some other caps including a-fake-symref-cap" &&
|
||||||
|
|
||||||
|
test-tool pkt-line pack >input.q <<-EOF &&
|
||||||
|
$oid HEADQ$caps $symrefs
|
||||||
|
$oid refs/heads/main
|
||||||
|
$oid refs/remotes/origin/HEAD
|
||||||
|
$oid refs/remotes/origin/main
|
||||||
|
0000
|
||||||
|
EOF
|
||||||
|
q_to_nul <input.q >input &&
|
||||||
|
|
||||||
|
cat >expect <<-EOF &&
|
||||||
|
ref: refs/heads/main HEAD
|
||||||
|
$oid HEAD
|
||||||
|
$oid refs/heads/main
|
||||||
|
ref: refs/remotes/origin/main refs/remotes/origin/HEAD
|
||||||
|
$oid refs/remotes/origin/HEAD
|
||||||
|
$oid refs/remotes/origin/main
|
||||||
|
EOF
|
||||||
|
|
||||||
|
git ls-remote --symref --upload-pack=./cat-input . >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
@ -320,7 +320,7 @@ static struct ref *handshake(struct transport *transport, int for_push,
|
|||||||
struct git_transport_data *data = transport->data;
|
struct git_transport_data *data = transport->data;
|
||||||
struct ref *refs = NULL;
|
struct ref *refs = NULL;
|
||||||
struct packet_reader reader;
|
struct packet_reader reader;
|
||||||
int sid_len;
|
size_t sid_len;
|
||||||
const char *server_sid;
|
const char *server_sid;
|
||||||
|
|
||||||
connect_setup(transport, for_push);
|
connect_setup(transport, for_push);
|
||||||
|
@ -1070,7 +1070,7 @@ static void receive_needs(struct upload_pack_data *data,
|
|||||||
const char *features;
|
const char *features;
|
||||||
struct object_id oid_buf;
|
struct object_id oid_buf;
|
||||||
const char *arg;
|
const char *arg;
|
||||||
int feature_len;
|
size_t feature_len;
|
||||||
|
|
||||||
reset_timeout(data->timeout);
|
reset_timeout(data->timeout);
|
||||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||||
|
Loading…
Reference in New Issue
Block a user