Commit d4763c98 by Carlos Martín Nieto

Merge pull request #3574 from chescock/buffer-sideband-pack-data

Buffer sideband packet data
parents 63f7b7f9 9028a8a2
...@@ -721,18 +721,39 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt) ...@@ -721,18 +721,39 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt)
return 0; return 0;
} }
static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt) static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, git_buf *data_pkt_buf)
{ {
git_pkt *pkt; git_pkt *pkt;
const char *line = data_pkt->data, *line_end; const char *line, *line_end;
size_t line_len = data_pkt->len; size_t line_len;
int error; int error;
int reading_from_buf = data_pkt_buf->size > 0;
if (reading_from_buf) {
/* We had an existing partial packet, so add the new
* packet to the buffer and parse the whole thing */
git_buf_put(data_pkt_buf, data_pkt->data, data_pkt->len);
line = data_pkt_buf->ptr;
line_len = data_pkt_buf->size;
}
else {
line = data_pkt->data;
line_len = data_pkt->len;
}
while (line_len > 0) { while (line_len > 0) {
error = git_pkt_parse_line(&pkt, line, &line_end, line_len); error = git_pkt_parse_line(&pkt, line, &line_end, line_len);
if (error < 0) if (error == GIT_EBUFS) {
return error; /* Buffer the data when the inner packet is split
* across multiple sideband packets */
if (!reading_from_buf)
git_buf_put(data_pkt_buf, line, line_len);
error = 0;
goto done;
}
else if (error < 0)
goto done;
/* Advance in the buffer */ /* Advance in the buffer */
line_len -= (line_end - line); line_len -= (line_end - line);
...@@ -743,10 +764,15 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt) ...@@ -743,10 +764,15 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt)
git_pkt_free(pkt); git_pkt_free(pkt);
if (error < 0 && error != GIT_ITEROVER) if (error < 0 && error != GIT_ITEROVER)
return error; goto done;
} }
return 0; error = 0;
done:
if (reading_from_buf)
git_buf_consume(data_pkt_buf, line_end);
return error;
} }
static int parse_report(transport_smart *transport, git_push *push) static int parse_report(transport_smart *transport, git_push *push)
...@@ -755,6 +781,7 @@ static int parse_report(transport_smart *transport, git_push *push) ...@@ -755,6 +781,7 @@ static int parse_report(transport_smart *transport, git_push *push)
const char *line_end = NULL; const char *line_end = NULL;
gitno_buffer *buf = &transport->buffer; gitno_buffer *buf = &transport->buffer;
int error, recvd; int error, recvd;
git_buf data_pkt_buf = GIT_BUF_INIT;
for (;;) { for (;;) {
if (buf->offset > 0) if (buf->offset > 0)
...@@ -763,16 +790,21 @@ static int parse_report(transport_smart *transport, git_push *push) ...@@ -763,16 +790,21 @@ static int parse_report(transport_smart *transport, git_push *push)
else else
error = GIT_EBUFS; error = GIT_EBUFS;
if (error < 0 && error != GIT_EBUFS) if (error < 0 && error != GIT_EBUFS) {
return -1; error = -1;
goto done;
}
if (error == GIT_EBUFS) { if (error == GIT_EBUFS) {
if ((recvd = gitno_recv(buf)) < 0) if ((recvd = gitno_recv(buf)) < 0) {
return recvd; error = recvd;
goto done;
}
if (recvd == 0) { if (recvd == 0) {
giterr_set(GITERR_NET, "early EOF"); giterr_set(GITERR_NET, "early EOF");
return GIT_EEOF; error = GIT_EEOF;
goto done;
} }
continue; continue;
} }
...@@ -784,7 +816,7 @@ static int parse_report(transport_smart *transport, git_push *push) ...@@ -784,7 +816,7 @@ static int parse_report(transport_smart *transport, git_push *push)
switch (pkt->type) { switch (pkt->type) {
case GIT_PKT_DATA: case GIT_PKT_DATA:
/* This is a sideband packet which contains other packets */ /* This is a sideband packet which contains other packets */
error = add_push_report_sideband_pkt(push, (git_pkt_data *)pkt); error = add_push_report_sideband_pkt(push, (git_pkt_data *)pkt, &data_pkt_buf);
break; break;
case GIT_PKT_ERR: case GIT_PKT_ERR:
giterr_set(GITERR_NET, "report-status: Error reported: %s", giterr_set(GITERR_NET, "report-status: Error reported: %s",
...@@ -805,12 +837,24 @@ static int parse_report(transport_smart *transport, git_push *push) ...@@ -805,12 +837,24 @@ static int parse_report(transport_smart *transport, git_push *push)
git_pkt_free(pkt); git_pkt_free(pkt);
/* add_push_report_pkt returns GIT_ITEROVER when it receives a flush */ /* add_push_report_pkt returns GIT_ITEROVER when it receives a flush */
if (error == GIT_ITEROVER) if (error == GIT_ITEROVER) {
return 0; error = 0;
if (data_pkt_buf.size > 0) {
/* If there was data remaining in the pack data buffer,
* then the server sent a partial pkt-line */
giterr_set(GITERR_NET, "Incomplete pack data pkt-line");
error = GIT_ERROR;
}
goto done;
}
if (error < 0) if (error < 0) {
return error; goto done;
}
} }
done:
git_buf_free(&data_pkt_buf);
return error;
} }
static int add_ref_from_push_spec(git_vector *refs, push_spec *push_spec) static int add_ref_from_push_spec(git_vector *refs, push_spec *push_spec)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment