diff --git a/bundle-uri.c b/bundle-uri.c index 34fa452e76..9ca2060e9a 100644 --- a/bundle-uri.c +++ b/bundle-uri.c @@ -946,8 +946,12 @@ static int config_to_packet_line(const char *key, const char *value, { struct packet_reader *writer = data; - if (starts_with(key, "bundle.")) - packet_write_fmt(writer->fd, "%s=%s", key, value); + if (starts_with(key, "bundle.")) { + if (value && *value) + packet_write_fmt(writer->fd, "%s=%s", key, value); + else + warning(_("config '%s' has no value"), key); + } return 0; } diff --git a/connect.c b/connect.c index 47e39d2a73..1d74c1eda2 100644 --- a/connect.c +++ b/connect.c @@ -517,7 +517,7 @@ static void send_capabilities(int fd_out, struct packet_reader *reader) int get_remote_bundle_uri(int fd_out, struct packet_reader *reader, struct bundle_list *bundles, int stateless_rpc) { - int line_nr = 1; + int line_nr = 1, err = 0; /* Assert bundle-uri support */ ensure_server_supports_v2("bundle-uri"); @@ -536,10 +536,19 @@ int get_remote_bundle_uri(int fd_out, struct packet_reader *reader, const char *line = reader->line; line_nr++; + /* + * Do not parse if an error was encountered, but + * continue draining the response so no stale data + * is left in the reader for subsequent protocol + * exchanges. + */ + if (err) + continue; + if (!bundle_uri_parse_line(bundles, line)) continue; - return error(_("error on bundle-uri response line %d: %s"), + err = error(_("error on bundle-uri response line %d: %s"), line_nr, line); } @@ -554,7 +563,7 @@ int get_remote_bundle_uri(int fd_out, struct packet_reader *reader, check_stateless_delimiter(stateless_rpc, reader, _("expected response end packet after ref listing")); - return 0; + return err; } struct ref **get_remote_refs(int fd_out, struct packet_reader *reader, diff --git a/t/lib-bundle-uri-protocol.sh b/t/lib-bundle-uri-protocol.sh index ecf3284297..794478ae19 100644 --- a/t/lib-bundle-uri-protocol.sh +++ b/t/lib-bundle-uri-protocol.sh @@ -214,3 +214,26 @@ test_expect_success "test bundle-uri with $BUNDLE_URI_PROTOCOL:// using protocol >actual && test_cmp_config_output expect actual ' + +test_expect_success "test bundle-uri with $BUNDLE_URI_PROTOCOL:// using protocol v2 with empty value" ' + test_config -C "$BUNDLE_URI_PARENT" \ + bundle.bundle1.uri "$BUNDLE_URI_BUNDLE_URI_ESCAPED-1.bdl" && + test_config -C "$BUNDLE_URI_PARENT" \ + bundle.bundle2.uri "" && + + # The empty bundle.bundle2.uri value is invalid configuration and the + # server must not advertise it to the client. + cat >expect <<-EOF && + [bundle] + version = 1 + mode = all + [bundle "bundle1"] + uri = $BUNDLE_URI_BUNDLE_URI_ESCAPED-1.bdl + EOF + + test-tool bundle-uri \ + ls-remote \ + "$BUNDLE_URI_REPO_URI" \ + >actual && + test_cmp_config_output expect actual +' diff --git a/t/t5558-clone-bundle-uri.sh b/t/t5558-clone-bundle-uri.sh index 0d5be0d56e..f81f1f8db7 100755 --- a/t/t5558-clone-bundle-uri.sh +++ b/t/t5558-clone-bundle-uri.sh @@ -1302,6 +1302,35 @@ test_expect_success 'bundles with newline in target path are rejected' ' test_path_is_missing escape ' +test_expect_success 'bundles advertised with missing URI' ' + git clone --no-local --mirror clone-from \ + "$HTTPD_DOCUMENT_ROOT_PATH/no-uri.git" && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/no-uri.git" config uploadpack.advertiseBundleURIs true && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/no-uri.git" config bundle.version 1 && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/no-uri.git" config bundle.mode all && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/no-uri.git" config bundle.bundle-1.creationToken 1 && + + git -c transfer.bundleURI=true clone \ + "$HTTPD_URL/smart/no-uri.git" target-no-uri 2>err && + test_grep "bundle ${SQ}bundle-1${SQ} has no uri" err && + test_grep ! "expected packfile" err +' + +test_expect_success 'bundles advertised with empty URI' ' + git clone --no-local --mirror clone-from \ + "$HTTPD_DOCUMENT_ROOT_PATH/empty-uri.git" && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/empty-uri.git" config uploadpack.advertiseBundleURIs true && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/empty-uri.git" config bundle.version 1 && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/empty-uri.git" config bundle.mode all && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/empty-uri.git" config bundle.bundle-1.uri "" && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/empty-uri.git" config bundle.bundle-1.creationToken 1 && + + git -c transfer.bundleURI=true clone \ + "$HTTPD_URL/smart/empty-uri.git" target-empty-uri 2>err && + test_grep "bundle ${SQ}bundle-1${SQ} has no uri" err && + test_grep ! "expected packfile" err +' + # Do not add tests here unless they use the HTTP server, as they will # not run unless the HTTP dependencies exist.