diff options
author | Etienne Samson <samson.etienne@gmail.com> | 2018-07-06 22:24:16 +0200 |
---|---|---|
committer | Etienne Samson <samson.etienne@gmail.com> | 2018-07-06 22:24:16 +0200 |
commit | 6ae6491e5f6033a23dfdb0fb010da74ef5413c0f (patch) | |
tree | 2c7e5aa88b6c8807bffb85a34a2fbc90c559b338 | |
parent | 68c7480a8ef77424c67bcf5f0b822926e030d758 (diff) | |
download | libgit2-6ae6491e5f6033a23dfdb0fb010da74ef5413c0f.tar.gz |
smart: don't dereference a NULL pkt pointer
By clarifying what detect_caps returns on empty/missing packet, we can
be sure there are actually refs to process. The old code could blindly
dereference `first`, which might have been NULL.
Reported by Coverity, CID 1393614
-rw-r--r-- | src/transports/smart.c | 25 | ||||
-rw-r--r-- | src/transports/smart_protocol.c | 2 |
2 files changed, 15 insertions, 12 deletions
diff --git a/src/transports/smart.c b/src/transports/smart.c index 180099539..ff66f91ba 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -280,20 +280,23 @@ static int git_smart__connect( /* Detect capabilities */ if ((error = git_smart__detect_caps(first, &t->caps, &symrefs)) == 0) { - goto cleanup; - } + /* If the only ref in the list is capabilities^{} with OID_ZERO, remove it */ + if (1 == t->refs.length && !strcmp(first->head.name, "capabilities^{}") && + git_oid_iszero(&first->head.oid)) { + git_vector_clear(&t->refs); + git_pkt_free((git_pkt *)first); + } - /* If the only ref in the list is capabilities^{} with OID_ZERO, remove it */ - if (1 == t->refs.length && !strcmp(first->head.name, "capabilities^{}") && - git_oid_iszero(&first->head.oid)) { - git_vector_clear(&t->refs); - git_pkt_free((git_pkt *)first); + /* Keep a list of heads for _ls */ + git_smart__update_heads(t, &symrefs); + } else if (error == GIT_ENOTFOUND) { + /* There was no ref packet received, or the cap list was empty */ + error = 0; + } else { + giterr_set(GITERR_NET, "invalid response"); + goto cleanup; } - /* Keep a list of heads for _ls */ - git_smart__update_heads(t, &symrefs); - - if (t->rpc && (error = git_smart__reset_stream(t, false)) < 0) goto cleanup; diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index b114e182b..750ae6ddb 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -142,7 +142,7 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vec /* No refs or capabilites, odd but not a problem */ if (pkt == NULL || pkt->capabilities == NULL) - return 0; + return GIT_ENOTFOUND; ptr = pkt->capabilities; while (ptr != NULL && *ptr != '\0') { |